v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
test-alloc.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include "v8.h"
29 #include "accessors.h"
30 
31 #include "cctest.h"
32 
33 
34 using namespace v8::internal;
35 
36 
37 static MaybeObject* AllocateAfterFailures() {
38  static int attempts = 0;
39  if (++attempts < 3) return Failure::RetryAfterGC();
40  Heap* heap = CcTest::heap();
41 
42  // New space.
43  SimulateFullSpace(heap->new_space());
44  CHECK(!heap->AllocateByteArray(100)->IsFailure());
45  CHECK(!heap->AllocateFixedArray(100, NOT_TENURED)->IsFailure());
46 
47  // Make sure we can allocate through optimized allocation functions
48  // for specific kinds.
49  CHECK(!heap->AllocateFixedArray(100)->IsFailure());
50  CHECK(!heap->AllocateHeapNumber(0.42)->IsFailure());
51  CHECK(!heap->AllocateArgumentsObject(Smi::FromInt(87), 10)->IsFailure());
52  Object* object = heap->AllocateJSObject(
53  *CcTest::i_isolate()->object_function())->ToObjectChecked();
54  CHECK(!heap->CopyJSObject(JSObject::cast(object))->IsFailure());
55 
56  // Old data space.
57  SimulateFullSpace(heap->old_data_space());
58  CHECK(!heap->AllocateRawOneByteString(100, TENURED)->IsFailure());
59 
60  // Old pointer space.
61  SimulateFullSpace(heap->old_pointer_space());
62  CHECK(!heap->AllocateFixedArray(10000, TENURED)->IsFailure());
63 
64  // Large object space.
65  static const int kLargeObjectSpaceFillerLength = 300000;
66  static const int kLargeObjectSpaceFillerSize = FixedArray::SizeFor(
67  kLargeObjectSpaceFillerLength);
68  ASSERT(kLargeObjectSpaceFillerSize > heap->old_pointer_space()->AreaSize());
69  while (heap->OldGenerationSpaceAvailable() > kLargeObjectSpaceFillerSize) {
70  CHECK(!heap->AllocateFixedArray(kLargeObjectSpaceFillerLength, TENURED)->
71  IsFailure());
72  }
73  CHECK(!heap->AllocateFixedArray(kLargeObjectSpaceFillerLength, TENURED)->
74  IsFailure());
75 
76  // Map space.
77  SimulateFullSpace(heap->map_space());
78  int instance_size = JSObject::kHeaderSize;
79  CHECK(!heap->AllocateMap(JS_OBJECT_TYPE, instance_size)->IsFailure());
80 
81  // Test that we can allocate in old pointer space and code space.
82  SimulateFullSpace(heap->code_space());
83  CHECK(!heap->AllocateFixedArray(100, TENURED)->IsFailure());
85  Builtins::kIllegal))->IsFailure());
86 
87  // Return success.
88  return Smi::FromInt(42);
89 }
90 
91 
92 static Handle<Object> Test() {
93  CALL_HEAP_FUNCTION(CcTest::i_isolate(), AllocateAfterFailures(), Object);
94 }
95 
96 
97 TEST(StressHandles) {
100  env->Enter();
101  Handle<Object> o = Test();
102  CHECK(o->IsSmi() && Smi::cast(*o)->value() == 42);
103  env->Exit();
104 }
105 
106 
107 static MaybeObject* TestAccessorGet(Isolate* isolate, Object* object, void*) {
108  return AllocateAfterFailures();
109 }
110 
111 
113  TestAccessorGet,
114  0,
115  0
116 };
117 
118 
119 TEST(StressJS) {
120  Isolate* isolate = CcTest::i_isolate();
121  Factory* factory = isolate->factory();
124  env->Enter();
125  Handle<JSFunction> function =
126  factory->NewFunction(factory->function_string(), factory->null_value());
127  // Force the creation of an initial map and set the code to
128  // something empty.
129  factory->NewJSObject(function);
130  function->ReplaceCode(CcTest::i_isolate()->builtins()->builtin(
131  Builtins::kEmptyFunction));
132  // Patch the map to have an accessor for "get".
133  Handle<Map> map(function->initial_map());
134  Handle<DescriptorArray> instance_descriptors(map->instance_descriptors());
135  Handle<Foreign> foreign = factory->NewForeign(&kDescriptor);
137  factory->NewStringFromAscii(Vector<const char>("get", 3));
138  ASSERT(instance_descriptors->IsEmpty());
139 
140  Handle<DescriptorArray> new_descriptors = factory->NewDescriptorArray(0, 1);
141 
142  v8::internal::DescriptorArray::WhitenessWitness witness(*new_descriptors);
143  map->set_instance_descriptors(*new_descriptors);
144 
145  CallbacksDescriptor d(*name,
146  *foreign,
147  static_cast<PropertyAttributes>(0));
148  map->AppendDescriptor(&d, witness);
149 
150  // Add the Foo constructor the global object.
151  env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "Foo"),
152  v8::Utils::ToLocal(function));
153  // Call the accessor through JavaScript.
155  v8::String::NewFromUtf8(CcTest::isolate(), "(new Foo).get"))->Run();
156  CHECK_EQ(42, result->Int32Value());
157  env->Exit();
158 }
159 
160 
161 // CodeRange test.
162 // Tests memory management in a CodeRange by allocating and freeing blocks,
163 // using a pseudorandom generator to choose block sizes geometrically
164 // distributed between 2 * Page::kPageSize and 2^5 + 1 * Page::kPageSize.
165 // Ensure that the freed chunks are collected and reused by allocating (in
166 // total) more than the size of the CodeRange.
167 
168 // This pseudorandom generator does not need to be particularly good.
169 // Use the lower half of the V8::Random() generator.
170 unsigned int Pseudorandom() {
171  static uint32_t lo = 2345;
172  lo = 18273 * (lo & 0xFFFF) + (lo >> 16); // Provably not 0.
173  return lo & 0xFFFF;
174 }
175 
176 
177 // Plain old data class. Represents a block of allocated memory.
178 class Block {
179  public:
180  Block(Address base_arg, int size_arg)
181  : base(base_arg), size(size_arg) {}
182 
184  int size;
185 };
186 
187 
189  const int code_range_size = 32*MB;
191  CodeRange code_range(reinterpret_cast<Isolate*>(CcTest::isolate()));
192  code_range.SetUp(code_range_size);
193  int current_allocated = 0;
194  int total_allocated = 0;
195  List<Block> blocks(1000);
196 
197  while (total_allocated < 5 * code_range_size) {
198  if (current_allocated < code_range_size / 10) {
199  // Allocate a block.
200  // Geometrically distributed sizes, greater than
201  // Page::kMaxRegularHeapObjectSize (which is greater than code page area).
202  // TODO(gc): instead of using 3 use some contant based on code_range_size
203  // kMaxHeapObjectSize.
204  size_t requested =
206  Pseudorandom() % 5000 + 1;
207  size_t allocated = 0;
208  Address base = code_range.AllocateRawMemory(requested,
209  requested,
210  &allocated);
211  CHECK(base != NULL);
212  blocks.Add(Block(base, static_cast<int>(allocated)));
213  current_allocated += static_cast<int>(allocated);
214  total_allocated += static_cast<int>(allocated);
215  } else {
216  // Free a block.
217  int index = Pseudorandom() % blocks.length();
218  code_range.FreeRawMemory(blocks[index].base, blocks[index].size);
219  current_allocated -= blocks[index].size;
220  if (index < blocks.length() - 1) {
221  blocks[index] = blocks.RemoveLast();
222  } else {
223  blocks.RemoveLast();
224  }
225  }
226  }
227 
228  code_range.TearDown();
229 }
void Enter()
Definition: api.cc:650
byte * Address
Definition: globals.h:186
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
MUST_USE_RESULT MaybeObject * CopyCode(Code *code)
Definition: heap.cc:4220
Code * builtin(Name name)
Definition: builtins.h:322
Handle< JSObject > NewJSObject(Handle< JSFunction > constructor, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:1319
#define CHECK_EQ(expected, value)
Definition: checks.h:252
MUST_USE_RESULT MaybeObject * AllocateRawOneByteString(int length, PretenureFlag pretenure=NOT_TENURED)
Definition: heap.cc:5087
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf map
Definition: flags.cc:350
Handle< DescriptorArray > NewDescriptorArray(int number_of_descriptors, int slack=0)
Definition: factory.cc:169
bool SetUp(const size_t requested_size)
Definition: spaces.cc:136
static Smi * FromInt(int value)
Definition: objects-inl.h:1209
MUST_USE_RESULT MaybeObject * CopyJSObject(JSObject *source, AllocationSite *site=NULL)
Definition: heap.cc:4712
Handle< String > NewStringFromAscii(Vector< const char > str, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.h:141
Builtins * builtins()
Definition: isolate.h:948
Address base
Definition: test-alloc.cc:183
#define ASSERT(condition)
Definition: checks.h:329
static i::Heap * heap()
Definition: cctest.h:106
#define CHECK(condition)
Definition: checks.h:75
Factory * factory()
Definition: isolate.h:995
MUST_USE_RESULT MaybeObject * AllocateJSObject(JSFunction *constructor, PretenureFlag pretenure=NOT_TENURED, AllocationSite *allocation_site=NULL)
Definition: heap.cc:4530
static Smi * cast(Object *object)
unsigned int Pseudorandom()
Definition: test-alloc.cc:170
MUST_USE_RESULT MaybeObject * AllocateHeapNumber(double value, PretenureFlag pretenure=NOT_TENURED)
Definition: heap.cc:2969
Handle< JSFunction > NewFunction(Handle< String > name, Handle< Object > prototype)
Definition: factory.cc:1663
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object size
Definition: flags.cc:211
static Failure * RetryAfterGC()
Definition: objects-inl.h:1255
#define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE)
Definition: heap-inl.h:679
int32_t Int32Value() const
Definition: api.cc:2929
static Local< Script > Compile(Handle< String > source, ScriptOrigin *origin=NULL, ScriptData *script_data=NULL)
Definition: api.cc:1832
static const int kMaxRegularHeapObjectSize
Definition: spaces.h:820
Local< Object > Global()
Definition: api.cc:5239
OldSpace * old_pointer_space()
Definition: heap.h:638
static i::Isolate * i_isolate()
Definition: cctest.h:102
MUST_USE_RESULT MaybeObject * AllocateByteArray(int length, PretenureFlag pretenure=NOT_TENURED)
Definition: heap.cc:3987
OldSpace * code_space()
Definition: heap.h:640
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
static int SizeFor(int length)
Definition: objects.h:3067
static Local< Context > New(Isolate *isolate, ExtensionConfiguration *extensions=NULL, Handle< ObjectTemplate > global_template=Handle< ObjectTemplate >(), Handle< Value > global_object=Handle< Value >())
Definition: api.cc:5188
int size
Definition: test-alloc.cc:184
MUST_USE_RESULT MaybeObject * AllocateArgumentsObject(Object *callee, int length)
Definition: heap.cc:4401
static void InitializeVM()
Definition: cctest.h:116
void Exit()
Definition: api.cc:661
Block(Address base_arg, int size_arg)
Definition: test-alloc.cc:180
MUST_USE_RESULT Address AllocateRawMemory(const size_t requested_size, const size_t commit_size, size_t *allocated)
Definition: spaces.cc:211
Handle< Foreign > NewForeign(Address addr, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:726
MUST_USE_RESULT MaybeObject * AllocateFixedArray(int length, PretenureFlag pretenure=NOT_TENURED)
Definition: heap.cc:5297
static const int kHeaderSize
Definition: objects.h:2757
MapSpace * map_space()
Definition: heap.h:641
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Definition: list-inl.h:39
const AccessorDescriptor kDescriptor
Definition: test-alloc.cc:112
void FreeRawMemory(Address buf, size_t length)
Definition: spaces.cc:258
intptr_t OldGenerationSpaceAvailable()
Definition: heap.h:1585
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print statistics of the maximum memory committed for the heap in name
Definition: flags.cc:505
NewSpace * new_space()
Definition: heap.h:637
MUST_USE_RESULT MaybeObject * AllocateMap(InstanceType instance_type, int instance_size, ElementsKind elements_kind=TERMINAL_FAST_ELEMENTS_KIND)
Definition: heap.cc:2643
static JSObject * cast(Object *obj)
OldSpace * old_data_space()
Definition: heap.h:639
static v8::Isolate * isolate()
Definition: cctest.h:96
static Local< String > NewFromUtf8(Isolate *isolate, const char *data, NewStringType type=kNormalString, int length=-1)
Definition: api.cc:5417
const int MB
Definition: globals.h:246