v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
test-heap.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 
3 #include <stdlib.h>
4 
5 #include "v8.h"
6 
7 #include "execution.h"
8 #include "factory.h"
9 #include "macro-assembler.h"
10 #include "global-handles.h"
11 #include "cctest.h"
12 
13 using namespace v8::internal;
14 
16 
17 static void InitializeVM() {
18  if (env.IsEmpty()) env = v8::Context::New();
19  v8::HandleScope scope;
20  env->Enter();
21 }
22 
23 
24 static void CheckMap(Map* map, int type, int instance_size) {
25  CHECK(map->IsHeapObject());
26 #ifdef DEBUG
27  CHECK(HEAP->Contains(map));
28 #endif
29  CHECK_EQ(HEAP->meta_map(), map->map());
30  CHECK_EQ(type, map->instance_type());
31  CHECK_EQ(instance_size, map->instance_size());
32 }
33 
34 
35 TEST(HeapMaps) {
36  InitializeVM();
37  CheckMap(HEAP->meta_map(), MAP_TYPE, Map::kSize);
38  CheckMap(HEAP->heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize);
39  CheckMap(HEAP->fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel);
40  CheckMap(HEAP->string_map(), STRING_TYPE, kVariableSizeSentinel);
41 }
42 
43 
44 static void CheckOddball(Object* obj, const char* string) {
45  CHECK(obj->IsOddball());
46  bool exc;
47  Object* print_string = *Execution::ToString(Handle<Object>(obj), &exc);
48  CHECK(String::cast(print_string)->IsEqualTo(CStrVector(string)));
49 }
50 
51 
52 static void CheckSmi(int value, const char* string) {
53  bool exc;
54  Object* print_string =
56  CHECK(String::cast(print_string)->IsEqualTo(CStrVector(string)));
57 }
58 
59 
60 static void CheckNumber(double value, const char* string) {
61  Object* obj = HEAP->NumberFromDouble(value)->ToObjectChecked();
62  CHECK(obj->IsNumber());
63  bool exc;
64  Object* print_string = *Execution::ToString(Handle<Object>(obj), &exc);
65  CHECK(String::cast(print_string)->IsEqualTo(CStrVector(string)));
66 }
67 
68 
69 static void CheckFindCodeObject() {
70  // Test FindCodeObject
71 #define __ assm.
72 
73  Assembler assm(Isolate::Current(), NULL, 0);
74 
75  __ nop(); // supported on all architectures
76 
77  CodeDesc desc;
78  assm.GetCode(&desc);
79  Object* code = HEAP->CreateCode(
80  desc,
82  Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
83  CHECK(code->IsCode());
84 
85  HeapObject* obj = HeapObject::cast(code);
86  Address obj_addr = obj->address();
87 
88  for (int i = 0; i < obj->Size(); i += kPointerSize) {
89  Object* found = HEAP->FindCodeObject(obj_addr + i);
90  CHECK_EQ(code, found);
91  }
92 
93  Object* copy = HEAP->CreateCode(
94  desc,
96  Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
97  CHECK(copy->IsCode());
98  HeapObject* obj_copy = HeapObject::cast(copy);
99  Object* not_right = HEAP->FindCodeObject(obj_copy->address() +
100  obj_copy->Size() / 2);
101  CHECK(not_right != code);
102 }
103 
104 
105 TEST(HeapObjects) {
106  InitializeVM();
107 
108  v8::HandleScope sc;
109  Object* value = HEAP->NumberFromDouble(1.000123)->ToObjectChecked();
110  CHECK(value->IsHeapNumber());
111  CHECK(value->IsNumber());
112  CHECK_EQ(1.000123, value->Number());
113 
114  value = HEAP->NumberFromDouble(1.0)->ToObjectChecked();
115  CHECK(value->IsSmi());
116  CHECK(value->IsNumber());
117  CHECK_EQ(1.0, value->Number());
118 
119  value = HEAP->NumberFromInt32(1024)->ToObjectChecked();
120  CHECK(value->IsSmi());
121  CHECK(value->IsNumber());
122  CHECK_EQ(1024.0, value->Number());
123 
124  value = HEAP->NumberFromInt32(Smi::kMinValue)->ToObjectChecked();
125  CHECK(value->IsSmi());
126  CHECK(value->IsNumber());
127  CHECK_EQ(Smi::kMinValue, Smi::cast(value)->value());
128 
129  value = HEAP->NumberFromInt32(Smi::kMaxValue)->ToObjectChecked();
130  CHECK(value->IsSmi());
131  CHECK(value->IsNumber());
132  CHECK_EQ(Smi::kMaxValue, Smi::cast(value)->value());
133 
134 #ifndef V8_TARGET_ARCH_X64
135  // TODO(lrn): We need a NumberFromIntptr function in order to test this.
136  value = HEAP->NumberFromInt32(Smi::kMinValue - 1)->ToObjectChecked();
137  CHECK(value->IsHeapNumber());
138  CHECK(value->IsNumber());
139  CHECK_EQ(static_cast<double>(Smi::kMinValue - 1), value->Number());
140 #endif
141 
142  MaybeObject* maybe_value =
143  HEAP->NumberFromUint32(static_cast<uint32_t>(Smi::kMaxValue) + 1);
144  value = maybe_value->ToObjectChecked();
145  CHECK(value->IsHeapNumber());
146  CHECK(value->IsNumber());
147  CHECK_EQ(static_cast<double>(static_cast<uint32_t>(Smi::kMaxValue) + 1),
148  value->Number());
149 
150  // nan oddball checks
151  CHECK(HEAP->nan_value()->IsNumber());
152  CHECK(isnan(HEAP->nan_value()->Number()));
153 
154  Handle<String> s = FACTORY->NewStringFromAscii(CStrVector("fisk hest "));
155  CHECK(s->IsString());
156  CHECK_EQ(10, s->length());
157 
158  String* object_symbol = String::cast(HEAP->Object_symbol());
159  CHECK(
160  Isolate::Current()->context()->global()->HasLocalProperty(object_symbol));
161 
162  // Check ToString for oddballs
163  CheckOddball(HEAP->true_value(), "true");
164  CheckOddball(HEAP->false_value(), "false");
165  CheckOddball(HEAP->null_value(), "null");
166  CheckOddball(HEAP->undefined_value(), "undefined");
167 
168  // Check ToString for Smis
169  CheckSmi(0, "0");
170  CheckSmi(42, "42");
171  CheckSmi(-42, "-42");
172 
173  // Check ToString for Numbers
174  CheckNumber(1.1, "1.1");
175 
176  CheckFindCodeObject();
177 }
178 
179 
180 TEST(Tagging) {
181  InitializeVM();
182  int request = 24;
183  CHECK_EQ(request, static_cast<int>(OBJECT_POINTER_ALIGN(request)));
184  CHECK(Smi::FromInt(42)->IsSmi());
185  CHECK(Failure::RetryAfterGC(NEW_SPACE)->IsFailure());
187  Failure::RetryAfterGC(NEW_SPACE)->allocation_space());
189  Failure::RetryAfterGC(OLD_POINTER_SPACE)->allocation_space());
190  CHECK(Failure::Exception()->IsFailure());
191  CHECK(Smi::FromInt(Smi::kMinValue)->IsSmi());
192  CHECK(Smi::FromInt(Smi::kMaxValue)->IsSmi());
193 }
194 
195 
196 TEST(GarbageCollection) {
197  InitializeVM();
198 
199  v8::HandleScope sc;
200  // Check GC.
201  HEAP->CollectGarbage(NEW_SPACE);
202 
203  Handle<String> name = FACTORY->LookupAsciiSymbol("theFunction");
204  Handle<String> prop_name = FACTORY->LookupAsciiSymbol("theSlot");
205  Handle<String> prop_namex = FACTORY->LookupAsciiSymbol("theSlotx");
206  Handle<String> obj_name = FACTORY->LookupAsciiSymbol("theObject");
207 
208  {
209  v8::HandleScope inner_scope;
210  // Allocate a function and keep it in global object's property.
211  Handle<JSFunction> function =
212  FACTORY->NewFunction(name, FACTORY->undefined_value());
213  Handle<Map> initial_map =
215  function->set_initial_map(*initial_map);
216  Isolate::Current()->context()->global()->SetProperty(
217  *name, *function, NONE, kNonStrictMode)->ToObjectChecked();
218  // Allocate an object. Unrooted after leaving the scope.
219  Handle<JSObject> obj = FACTORY->NewJSObject(function);
220  obj->SetProperty(
221  *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
222  obj->SetProperty(
223  *prop_namex, Smi::FromInt(24), NONE, kNonStrictMode)->ToObjectChecked();
224 
225  CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name));
226  CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex));
227  }
228 
229  HEAP->CollectGarbage(NEW_SPACE);
230 
231  // Function should be alive.
232  CHECK(Isolate::Current()->context()->global()->HasLocalProperty(*name));
233  // Check function is retained.
234  Object* func_value = Isolate::Current()->context()->global()->
235  GetProperty(*name)->ToObjectChecked();
236  CHECK(func_value->IsJSFunction());
237  Handle<JSFunction> function(JSFunction::cast(func_value));
238 
239  {
240  HandleScope inner_scope;
241  // Allocate another object, make it reachable from global.
242  Handle<JSObject> obj = FACTORY->NewJSObject(function);
243  Isolate::Current()->context()->global()->SetProperty(
244  *obj_name, *obj, NONE, kNonStrictMode)->ToObjectChecked();
245  obj->SetProperty(
246  *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
247  }
248 
249  // After gc, it should survive.
250  HEAP->CollectGarbage(NEW_SPACE);
251 
252  CHECK(Isolate::Current()->context()->global()->HasLocalProperty(*obj_name));
253  CHECK(Isolate::Current()->context()->global()->
254  GetProperty(*obj_name)->ToObjectChecked()->IsJSObject());
255  Object* obj = Isolate::Current()->context()->global()->
256  GetProperty(*obj_name)->ToObjectChecked();
257  JSObject* js_obj = JSObject::cast(obj);
258  CHECK_EQ(Smi::FromInt(23), js_obj->GetProperty(*prop_name));
259 }
260 
261 
262 static void VerifyStringAllocation(const char* string) {
263  v8::HandleScope scope;
264  Handle<String> s = FACTORY->NewStringFromUtf8(CStrVector(string));
265  CHECK_EQ(StrLength(string), s->length());
266  for (int index = 0; index < s->length(); index++) {
267  CHECK_EQ(static_cast<uint16_t>(string[index]), s->Get(index));
268  }
269 }
270 
271 
273  InitializeVM();
274 
275  VerifyStringAllocation("a");
276  VerifyStringAllocation("ab");
277  VerifyStringAllocation("abc");
278  VerifyStringAllocation("abcd");
279  VerifyStringAllocation("fiskerdrengen er paa havet");
280 }
281 
282 
283 TEST(LocalHandles) {
284  InitializeVM();
285 
286  v8::HandleScope scope;
287  const char* name = "Kasper the spunky";
288  Handle<String> string = FACTORY->NewStringFromAscii(CStrVector(name));
289  CHECK_EQ(StrLength(name), string->length());
290 }
291 
292 
294  InitializeVM();
295  GlobalHandles* global_handles = Isolate::Current()->global_handles();
296 
297  Handle<Object> h1;
298  Handle<Object> h2;
299  Handle<Object> h3;
300  Handle<Object> h4;
301 
302  {
303  HandleScope scope;
304 
305  Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk"));
306  Handle<Object> u = FACTORY->NewNumber(1.12344);
307 
308  h1 = global_handles->Create(*i);
309  h2 = global_handles->Create(*u);
310  h3 = global_handles->Create(*i);
311  h4 = global_handles->Create(*u);
312  }
313 
314  // after gc, it should survive
315  HEAP->CollectGarbage(NEW_SPACE);
316 
317  CHECK((*h1)->IsString());
318  CHECK((*h2)->IsHeapNumber());
319  CHECK((*h3)->IsString());
320  CHECK((*h4)->IsHeapNumber());
321 
322  CHECK_EQ(*h3, *h1);
323  global_handles->Destroy(h1.location());
324  global_handles->Destroy(h3.location());
325 
326  CHECK_EQ(*h4, *h2);
327  global_handles->Destroy(h2.location());
328  global_handles->Destroy(h4.location());
329 }
330 
331 
332 static bool WeakPointerCleared = false;
333 
334 static void TestWeakGlobalHandleCallback(v8::Persistent<v8::Value> handle,
335  void* id) {
336  if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true;
337  handle.Dispose();
338 }
339 
340 
341 TEST(WeakGlobalHandlesScavenge) {
342  InitializeVM();
343  GlobalHandles* global_handles = Isolate::Current()->global_handles();
344 
345  WeakPointerCleared = false;
346 
347  Handle<Object> h1;
348  Handle<Object> h2;
349 
350  {
351  HandleScope scope;
352 
353  Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk"));
354  Handle<Object> u = FACTORY->NewNumber(1.12344);
355 
356  h1 = global_handles->Create(*i);
357  h2 = global_handles->Create(*u);
358  }
359 
360  global_handles->MakeWeak(h2.location(),
361  reinterpret_cast<void*>(1234),
362  &TestWeakGlobalHandleCallback);
363 
364  // Scavenge treats weak pointers as normal roots.
365  HEAP->PerformScavenge();
366 
367  CHECK((*h1)->IsString());
368  CHECK((*h2)->IsHeapNumber());
369 
370  CHECK(!WeakPointerCleared);
371  CHECK(!global_handles->IsNearDeath(h2.location()));
372  CHECK(!global_handles->IsNearDeath(h1.location()));
373 
374  global_handles->Destroy(h1.location());
375  global_handles->Destroy(h2.location());
376 }
377 
378 
379 TEST(WeakGlobalHandlesMark) {
380  InitializeVM();
381  GlobalHandles* global_handles = Isolate::Current()->global_handles();
382 
383  WeakPointerCleared = false;
384 
385  Handle<Object> h1;
386  Handle<Object> h2;
387 
388  {
389  HandleScope scope;
390 
391  Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk"));
392  Handle<Object> u = FACTORY->NewNumber(1.12344);
393 
394  h1 = global_handles->Create(*i);
395  h2 = global_handles->Create(*u);
396  }
397 
398  HEAP->CollectGarbage(OLD_POINTER_SPACE);
399  HEAP->CollectGarbage(NEW_SPACE);
400  // Make sure the object is promoted.
401 
402  global_handles->MakeWeak(h2.location(),
403  reinterpret_cast<void*>(1234),
404  &TestWeakGlobalHandleCallback);
407 
408  HEAP->CollectGarbage(OLD_POINTER_SPACE);
409 
410  CHECK((*h1)->IsString());
411 
412  CHECK(WeakPointerCleared);
414 
415  global_handles->Destroy(h1.location());
416 }
417 
418 TEST(DeleteWeakGlobalHandle) {
419  InitializeVM();
420  GlobalHandles* global_handles = Isolate::Current()->global_handles();
421 
422  WeakPointerCleared = false;
423 
424  Handle<Object> h;
425 
426  {
427  HandleScope scope;
428 
429  Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk"));
430  h = global_handles->Create(*i);
431  }
432 
433  global_handles->MakeWeak(h.location(),
434  reinterpret_cast<void*>(1234),
435  &TestWeakGlobalHandleCallback);
436 
437  // Scanvenge does not recognize weak reference.
438  HEAP->PerformScavenge();
439 
440  CHECK(!WeakPointerCleared);
441 
442  // Mark-compact treats weak reference properly.
443  HEAP->CollectGarbage(OLD_POINTER_SPACE);
444 
445  CHECK(WeakPointerCleared);
446 }
447 
448 static const char* not_so_random_string_table[] = {
449  "abstract",
450  "boolean",
451  "break",
452  "byte",
453  "case",
454  "catch",
455  "char",
456  "class",
457  "const",
458  "continue",
459  "debugger",
460  "default",
461  "delete",
462  "do",
463  "double",
464  "else",
465  "enum",
466  "export",
467  "extends",
468  "false",
469  "final",
470  "finally",
471  "float",
472  "for",
473  "function",
474  "goto",
475  "if",
476  "implements",
477  "import",
478  "in",
479  "instanceof",
480  "int",
481  "interface",
482  "long",
483  "native",
484  "new",
485  "null",
486  "package",
487  "private",
488  "protected",
489  "public",
490  "return",
491  "short",
492  "static",
493  "super",
494  "switch",
495  "synchronized",
496  "this",
497  "throw",
498  "throws",
499  "transient",
500  "true",
501  "try",
502  "typeof",
503  "var",
504  "void",
505  "volatile",
506  "while",
507  "with",
508  0
509 };
510 
511 
512 static void CheckSymbols(const char** strings) {
513  for (const char* string = *strings; *strings != 0; string = *strings++) {
514  Object* a;
515  MaybeObject* maybe_a = HEAP->LookupAsciiSymbol(string);
516  // LookupAsciiSymbol may return a failure if a GC is needed.
517  if (!maybe_a->ToObject(&a)) continue;
518  CHECK(a->IsSymbol());
519  Object* b;
520  MaybeObject* maybe_b = HEAP->LookupAsciiSymbol(string);
521  if (!maybe_b->ToObject(&b)) continue;
522  CHECK_EQ(b, a);
523  CHECK(String::cast(b)->IsEqualTo(CStrVector(string)));
524  }
525 }
526 
527 
529  InitializeVM();
530 
531  CheckSymbols(not_so_random_string_table);
532  CheckSymbols(not_so_random_string_table);
533 }
534 
535 
536 TEST(FunctionAllocation) {
537  InitializeVM();
538 
539  v8::HandleScope sc;
540  Handle<String> name = FACTORY->LookupAsciiSymbol("theFunction");
541  Handle<JSFunction> function =
542  FACTORY->NewFunction(name, FACTORY->undefined_value());
543  Handle<Map> initial_map =
545  function->set_initial_map(*initial_map);
546 
547  Handle<String> prop_name = FACTORY->LookupAsciiSymbol("theSlot");
548  Handle<JSObject> obj = FACTORY->NewJSObject(function);
549  obj->SetProperty(
550  *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
551  CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name));
552  // Check that we can add properties to function objects.
553  function->SetProperty(
554  *prop_name, Smi::FromInt(24), NONE, kNonStrictMode)->ToObjectChecked();
555  CHECK_EQ(Smi::FromInt(24), function->GetProperty(*prop_name));
556 }
557 
558 
559 TEST(ObjectProperties) {
560  InitializeVM();
561 
562  v8::HandleScope sc;
563  String* object_symbol = String::cast(HEAP->Object_symbol());
564  Object* raw_object = Isolate::Current()->context()->global()->
565  GetProperty(object_symbol)->ToObjectChecked();
566  JSFunction* object_function = JSFunction::cast(raw_object);
567  Handle<JSFunction> constructor(object_function);
568  Handle<JSObject> obj = FACTORY->NewJSObject(constructor);
569  Handle<String> first = FACTORY->LookupAsciiSymbol("first");
570  Handle<String> second = FACTORY->LookupAsciiSymbol("second");
571 
572  // check for empty
573  CHECK(!obj->HasLocalProperty(*first));
574 
575  // add first
576  obj->SetProperty(
577  *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
578  CHECK(obj->HasLocalProperty(*first));
579 
580  // delete first
581  CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION));
582  CHECK(!obj->HasLocalProperty(*first));
583 
584  // add first and then second
585  obj->SetProperty(
586  *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
587  obj->SetProperty(
588  *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
589  CHECK(obj->HasLocalProperty(*first));
590  CHECK(obj->HasLocalProperty(*second));
591 
592  // delete first and then second
593  CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION));
594  CHECK(obj->HasLocalProperty(*second));
595  CHECK(obj->DeleteProperty(*second, JSObject::NORMAL_DELETION));
596  CHECK(!obj->HasLocalProperty(*first));
597  CHECK(!obj->HasLocalProperty(*second));
598 
599  // add first and then second
600  obj->SetProperty(
601  *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
602  obj->SetProperty(
603  *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
604  CHECK(obj->HasLocalProperty(*first));
605  CHECK(obj->HasLocalProperty(*second));
606 
607  // delete second and then first
608  CHECK(obj->DeleteProperty(*second, JSObject::NORMAL_DELETION));
609  CHECK(obj->HasLocalProperty(*first));
610  CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION));
611  CHECK(!obj->HasLocalProperty(*first));
612  CHECK(!obj->HasLocalProperty(*second));
613 
614  // check string and symbol match
615  const char* string1 = "fisk";
616  Handle<String> s1 = FACTORY->NewStringFromAscii(CStrVector(string1));
617  obj->SetProperty(
618  *s1, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
619  Handle<String> s1_symbol = FACTORY->LookupAsciiSymbol(string1);
620  CHECK(obj->HasLocalProperty(*s1_symbol));
621 
622  // check symbol and string match
623  const char* string2 = "fugl";
624  Handle<String> s2_symbol = FACTORY->LookupAsciiSymbol(string2);
625  obj->SetProperty(
626  *s2_symbol, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
627  Handle<String> s2 = FACTORY->NewStringFromAscii(CStrVector(string2));
628  CHECK(obj->HasLocalProperty(*s2));
629 }
630 
631 
632 TEST(JSObjectMaps) {
633  InitializeVM();
634 
635  v8::HandleScope sc;
636  Handle<String> name = FACTORY->LookupAsciiSymbol("theFunction");
637  Handle<JSFunction> function =
638  FACTORY->NewFunction(name, FACTORY->undefined_value());
639  Handle<Map> initial_map =
641  function->set_initial_map(*initial_map);
642 
643  Handle<String> prop_name = FACTORY->LookupAsciiSymbol("theSlot");
644  Handle<JSObject> obj = FACTORY->NewJSObject(function);
645 
646  // Set a propery
647  obj->SetProperty(
648  *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
649  CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name));
650 
651  // Check the map has changed
652  CHECK(*initial_map != obj->map());
653 }
654 
655 
657  InitializeVM();
658 
659  v8::HandleScope sc;
660  Handle<String> name = FACTORY->LookupAsciiSymbol("Array");
661  Object* raw_object = Isolate::Current()->context()->global()->
662  GetProperty(*name)->ToObjectChecked();
664  JSFunction::cast(raw_object));
665 
666  // Allocate the object.
667  Handle<JSObject> object = FACTORY->NewJSObject(function);
668  Handle<JSArray> array = Handle<JSArray>::cast(object);
669  // We just initialized the VM, no heap allocation failure yet.
670  array->Initialize(0)->ToObjectChecked();
671 
672  // Set array length to 0.
673  array->SetElementsLength(Smi::FromInt(0))->ToObjectChecked();
674  CHECK_EQ(Smi::FromInt(0), array->length());
675  // Must be in fast mode.
676  CHECK(array->HasFastSmiOrObjectElements());
677 
678  // array[length] = name.
679  array->SetElement(0, *name, NONE, kNonStrictMode)->ToObjectChecked();
680  CHECK_EQ(Smi::FromInt(1), array->length());
681  CHECK_EQ(array->GetElement(0), *name);
682 
683  // Set array length with larger than smi value.
684  Handle<Object> length =
685  FACTORY->NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1);
686  array->SetElementsLength(*length)->ToObjectChecked();
687 
688  uint32_t int_length = 0;
689  CHECK(length->ToArrayIndex(&int_length));
690  CHECK_EQ(*length, array->length());
691  CHECK(array->HasDictionaryElements()); // Must be in slow mode.
692 
693  // array[length] = name.
694  array->SetElement(int_length, *name, NONE, kNonStrictMode)->ToObjectChecked();
695  uint32_t new_int_length = 0;
696  CHECK(array->length()->ToArrayIndex(&new_int_length));
697  CHECK_EQ(static_cast<double>(int_length), new_int_length - 1);
698  CHECK_EQ(array->GetElement(int_length), *name);
699  CHECK_EQ(array->GetElement(0), *name);
700 }
701 
702 
703 TEST(JSObjectCopy) {
704  InitializeVM();
705 
706  v8::HandleScope sc;
707  String* object_symbol = String::cast(HEAP->Object_symbol());
708  Object* raw_object = Isolate::Current()->context()->global()->
709  GetProperty(object_symbol)->ToObjectChecked();
710  JSFunction* object_function = JSFunction::cast(raw_object);
711  Handle<JSFunction> constructor(object_function);
712  Handle<JSObject> obj = FACTORY->NewJSObject(constructor);
713  Handle<String> first = FACTORY->LookupAsciiSymbol("first");
714  Handle<String> second = FACTORY->LookupAsciiSymbol("second");
715 
716  obj->SetProperty(
717  *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
718  obj->SetProperty(
719  *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
720 
721  obj->SetElement(0, *first, NONE, kNonStrictMode)->ToObjectChecked();
722  obj->SetElement(1, *second, NONE, kNonStrictMode)->ToObjectChecked();
723 
724  // Make the clone.
725  Handle<JSObject> clone = Copy(obj);
726  CHECK(!clone.is_identical_to(obj));
727 
728  CHECK_EQ(obj->GetElement(0), clone->GetElement(0));
729  CHECK_EQ(obj->GetElement(1), clone->GetElement(1));
730 
731  CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*first));
732  CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*second));
733 
734  // Flip the values.
735  clone->SetProperty(
736  *first, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
737  clone->SetProperty(
738  *second, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
739 
740  clone->SetElement(0, *second, NONE, kNonStrictMode)->ToObjectChecked();
741  clone->SetElement(1, *first, NONE, kNonStrictMode)->ToObjectChecked();
742 
743  CHECK_EQ(obj->GetElement(1), clone->GetElement(0));
744  CHECK_EQ(obj->GetElement(0), clone->GetElement(1));
745 
746  CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*first));
747  CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*second));
748 }
749 
750 
751 TEST(StringAllocation) {
752  InitializeVM();
753 
754 
755  const unsigned char chars[] = { 0xe5, 0xa4, 0xa7 };
756  for (int length = 0; length < 100; length++) {
757  v8::HandleScope scope;
758  char* non_ascii = NewArray<char>(3 * length + 1);
759  char* ascii = NewArray<char>(length + 1);
760  non_ascii[3 * length] = 0;
761  ascii[length] = 0;
762  for (int i = 0; i < length; i++) {
763  ascii[i] = 'a';
764  non_ascii[3 * i] = chars[0];
765  non_ascii[3 * i + 1] = chars[1];
766  non_ascii[3 * i + 2] = chars[2];
767  }
768  Handle<String> non_ascii_sym =
769  FACTORY->LookupSymbol(Vector<const char>(non_ascii, 3 * length));
770  CHECK_EQ(length, non_ascii_sym->length());
771  Handle<String> ascii_sym =
772  FACTORY->LookupSymbol(Vector<const char>(ascii, length));
773  CHECK_EQ(length, ascii_sym->length());
774  Handle<String> non_ascii_str =
775  FACTORY->NewStringFromUtf8(Vector<const char>(non_ascii, 3 * length));
776  non_ascii_str->Hash();
777  CHECK_EQ(length, non_ascii_str->length());
778  Handle<String> ascii_str =
779  FACTORY->NewStringFromUtf8(Vector<const char>(ascii, length));
780  ascii_str->Hash();
781  CHECK_EQ(length, ascii_str->length());
782  DeleteArray(non_ascii);
783  DeleteArray(ascii);
784  }
785 }
786 
787 
788 static int ObjectsFoundInHeap(Handle<Object> objs[], int size) {
789  // Count the number of objects found in the heap.
790  int found_count = 0;
791  HeapIterator iterator;
792  for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
793  for (int i = 0; i < size; i++) {
794  if (*objs[i] == obj) {
795  found_count++;
796  }
797  }
798  }
799  return found_count;
800 }
801 
802 
803 TEST(Iteration) {
804  InitializeVM();
805  v8::HandleScope scope;
806 
807  // Array of objects to scan haep for.
808  const int objs_count = 6;
809  Handle<Object> objs[objs_count];
810  int next_objs_index = 0;
811 
812  // Allocate a JS array to OLD_POINTER_SPACE and NEW_SPACE
813  objs[next_objs_index++] = FACTORY->NewJSArray(10);
814  objs[next_objs_index++] = FACTORY->NewJSArray(10,
816  TENURED);
817 
818  // Allocate a small string to OLD_DATA_SPACE and NEW_SPACE
819  objs[next_objs_index++] =
820  FACTORY->NewStringFromAscii(CStrVector("abcdefghij"));
821  objs[next_objs_index++] =
822  FACTORY->NewStringFromAscii(CStrVector("abcdefghij"), TENURED);
823 
824  // Allocate a large string (for large object space).
825  int large_size = Page::kMaxNonCodeHeapObjectSize + 1;
826  char* str = new char[large_size];
827  for (int i = 0; i < large_size - 1; ++i) str[i] = 'a';
828  str[large_size - 1] = '\0';
829  objs[next_objs_index++] =
830  FACTORY->NewStringFromAscii(CStrVector(str), TENURED);
831  delete[] str;
832 
833  // Add a Map object to look for.
834  objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map());
835 
836  CHECK_EQ(objs_count, next_objs_index);
837  CHECK_EQ(objs_count, ObjectsFoundInHeap(objs, objs_count));
838 }
839 
840 
841 TEST(EmptyHandleEscapeFrom) {
842  InitializeVM();
843 
844  v8::HandleScope scope;
845  Handle<JSObject> runaway;
846 
847  {
848  v8::HandleScope nested;
849  Handle<JSObject> empty;
850  runaway = empty.EscapeFrom(&nested);
851  }
852 
853  CHECK(runaway.is_null());
854 }
855 
856 
857 static int LenFromSize(int size) {
858  return (size - FixedArray::kHeaderSize) / kPointerSize;
859 }
860 
861 
862 TEST(Regression39128) {
863  // Test case for crbug.com/39128.
864  InitializeVM();
865 
866  // Increase the chance of 'bump-the-pointer' allocation in old space.
867  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
868 
869  v8::HandleScope scope;
870 
871  // The plan: create JSObject which references objects in new space.
872  // Then clone this object (forcing it to go into old space) and check
873  // that region dirty marks are updated correctly.
874 
875  // Step 1: prepare a map for the object. We add 1 inobject property to it.
876  Handle<JSFunction> object_ctor(
877  Isolate::Current()->global_context()->object_function());
878  CHECK(object_ctor->has_initial_map());
879  Handle<Map> object_map(object_ctor->initial_map());
880  // Create a map with single inobject property.
881  Handle<Map> my_map = FACTORY->CopyMap(object_map, 1);
882  int n_properties = my_map->inobject_properties();
883  CHECK_GT(n_properties, 0);
884 
885  int object_size = my_map->instance_size();
886 
887  // Step 2: allocate a lot of objects so to almost fill new space: we need
888  // just enough room to allocate JSObject and thus fill the newspace.
889 
890  int allocation_amount = Min(FixedArray::kMaxSize,
891  HEAP->MaxObjectSizeInNewSpace());
892  int allocation_len = LenFromSize(allocation_amount);
893  NewSpace* new_space = HEAP->new_space();
894  Address* top_addr = new_space->allocation_top_address();
895  Address* limit_addr = new_space->allocation_limit_address();
896  while ((*limit_addr - *top_addr) > allocation_amount) {
897  CHECK(!HEAP->always_allocate());
898  Object* array = HEAP->AllocateFixedArray(allocation_len)->ToObjectChecked();
899  CHECK(!array->IsFailure());
900  CHECK(new_space->Contains(array));
901  }
902 
903  // Step 3: now allocate fixed array and JSObject to fill the whole new space.
904  int to_fill = static_cast<int>(*limit_addr - *top_addr - object_size);
905  int fixed_array_len = LenFromSize(to_fill);
906  CHECK(fixed_array_len < FixedArray::kMaxLength);
907 
908  CHECK(!HEAP->always_allocate());
909  Object* array = HEAP->AllocateFixedArray(fixed_array_len)->ToObjectChecked();
910  CHECK(!array->IsFailure());
911  CHECK(new_space->Contains(array));
912 
913  Object* object = HEAP->AllocateJSObjectFromMap(*my_map)->ToObjectChecked();
914  CHECK(new_space->Contains(object));
915  JSObject* jsobject = JSObject::cast(object);
916  CHECK_EQ(0, FixedArray::cast(jsobject->elements())->length());
917  CHECK_EQ(0, jsobject->properties()->length());
918  // Create a reference to object in new space in jsobject.
919  jsobject->FastPropertyAtPut(-1, array);
920 
921  CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr));
922 
923  // Step 4: clone jsobject, but force always allocate first to create a clone
924  // in old pointer space.
925  Address old_pointer_space_top = HEAP->old_pointer_space()->top();
926  AlwaysAllocateScope aa_scope;
927  Object* clone_obj = HEAP->CopyJSObject(jsobject)->ToObjectChecked();
928  JSObject* clone = JSObject::cast(clone_obj);
929  if (clone->address() != old_pointer_space_top) {
930  // Alas, got allocated from free list, we cannot do checks.
931  return;
932  }
933  CHECK(HEAP->old_pointer_space()->Contains(clone->address()));
934 }
935 
936 
937 TEST(TestCodeFlushing) {
938  i::FLAG_allow_natives_syntax = true;
939  // If we do not flush code this test is invalid.
940  if (!FLAG_flush_code) return;
941  InitializeVM();
942  v8::HandleScope scope;
943  const char* source = "function foo() {"
944  " var x = 42;"
945  " var y = 42;"
946  " var z = x + y;"
947  "};"
948  "foo()";
949  Handle<String> foo_name = FACTORY->LookupAsciiSymbol("foo");
950 
951  // This compile will add the code to the compilation cache.
952  { v8::HandleScope scope;
953  CompileRun(source);
954  }
955 
956  // Check function is compiled.
957  Object* func_value = Isolate::Current()->context()->global()->
958  GetProperty(*foo_name)->ToObjectChecked();
959  CHECK(func_value->IsJSFunction());
960  Handle<JSFunction> function(JSFunction::cast(func_value));
961  CHECK(function->shared()->is_compiled());
962 
963  // TODO(1609) Currently incremental marker does not support code flushing.
964  HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
965  HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
966 
967  CHECK(function->shared()->is_compiled());
968 
969  HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
970  HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
971  HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
972  HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
973  HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
974  HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
975 
976  // foo should no longer be in the compilation cache
977  CHECK(!function->shared()->is_compiled() || function->IsOptimized());
978  CHECK(!function->is_compiled() || function->IsOptimized());
979  // Call foo to get it recompiled.
980  CompileRun("foo()");
981  CHECK(function->shared()->is_compiled());
982  CHECK(function->is_compiled());
983 }
984 
985 
986 // Count the number of global contexts in the weak list of global contexts.
987 static int CountGlobalContexts() {
988  int count = 0;
989  Object* object = HEAP->global_contexts_list();
990  while (!object->IsUndefined()) {
991  count++;
992  object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK);
993  }
994  return count;
995 }
996 
997 
998 // Count the number of user functions in the weak list of optimized
999 // functions attached to a global context.
1000 static int CountOptimizedUserFunctions(v8::Handle<v8::Context> context) {
1001  int count = 0;
1002  Handle<Context> icontext = v8::Utils::OpenHandle(*context);
1003  Object* object = icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST);
1004  while (object->IsJSFunction() && !JSFunction::cast(object)->IsBuiltin()) {
1005  count++;
1006  object = JSFunction::cast(object)->next_function_link();
1007  }
1008  return count;
1009 }
1010 
1011 
1012 TEST(TestInternalWeakLists) {
1014 
1015  static const int kNumTestContexts = 10;
1016 
1017  v8::HandleScope scope;
1018  v8::Persistent<v8::Context> ctx[kNumTestContexts];
1019 
1020  CHECK_EQ(0, CountGlobalContexts());
1021 
1022  // Create a number of global contests which gets linked together.
1023  for (int i = 0; i < kNumTestContexts; i++) {
1024  ctx[i] = v8::Context::New();
1025 
1026  bool opt = (FLAG_always_opt && i::V8::UseCrankshaft());
1027 
1028  CHECK_EQ(i + 1, CountGlobalContexts());
1029 
1030  ctx[i]->Enter();
1031 
1032  // Create a handle scope so no function objects get stuch in the outer
1033  // handle scope
1034  v8::HandleScope scope;
1035  const char* source = "function f1() { };"
1036  "function f2() { };"
1037  "function f3() { };"
1038  "function f4() { };"
1039  "function f5() { };";
1040  CompileRun(source);
1041  CHECK_EQ(0, CountOptimizedUserFunctions(ctx[i]));
1042  CompileRun("f1()");
1043  CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctions(ctx[i]));
1044  CompileRun("f2()");
1045  CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i]));
1046  CompileRun("f3()");
1047  CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
1048  CompileRun("f4()");
1049  CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
1050  CompileRun("f5()");
1051  CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i]));
1052 
1053  // Remove function f1, and
1054  CompileRun("f1=null");
1055 
1056  // Scavenge treats these references as strong.
1057  for (int j = 0; j < 10; j++) {
1058  HEAP->PerformScavenge();
1059  CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i]));
1060  }
1061 
1062  // Mark compact handles the weak references.
1063  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1064  CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
1065 
1066  // Get rid of f3 and f5 in the same way.
1067  CompileRun("f3=null");
1068  for (int j = 0; j < 10; j++) {
1069  HEAP->PerformScavenge();
1070  CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
1071  }
1072  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1073  CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
1074  CompileRun("f5=null");
1075  for (int j = 0; j < 10; j++) {
1076  HEAP->PerformScavenge();
1077  CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
1078  }
1079  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1080  CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i]));
1081 
1082  ctx[i]->Exit();
1083  }
1084 
1085  // Force compilation cache cleanup.
1086  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1087 
1088  // Dispose the global contexts one by one.
1089  for (int i = 0; i < kNumTestContexts; i++) {
1090  ctx[i].Dispose();
1091  ctx[i].Clear();
1092 
1093  // Scavenge treats these references as strong.
1094  for (int j = 0; j < 10; j++) {
1095  HEAP->PerformScavenge();
1096  CHECK_EQ(kNumTestContexts - i, CountGlobalContexts());
1097  }
1098 
1099  // Mark compact handles the weak references.
1100  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1101  CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts());
1102  }
1103 
1104  CHECK_EQ(0, CountGlobalContexts());
1105 }
1106 
1107 
1108 // Count the number of global contexts in the weak list of global contexts
1109 // causing a GC after the specified number of elements.
1110 static int CountGlobalContextsWithGC(int n) {
1111  int count = 0;
1112  Handle<Object> object(HEAP->global_contexts_list());
1113  while (!object->IsUndefined()) {
1114  count++;
1115  if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1116  object =
1118  }
1119  return count;
1120 }
1121 
1122 
1123 // Count the number of user functions in the weak list of optimized
1124 // functions attached to a global context causing a GC after the
1125 // specified number of elements.
1126 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context,
1127  int n) {
1128  int count = 0;
1129  Handle<Context> icontext = v8::Utils::OpenHandle(*context);
1130  Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST));
1131  while (object->IsJSFunction() &&
1132  !Handle<JSFunction>::cast(object)->IsBuiltin()) {
1133  count++;
1134  if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1135  object = Handle<Object>(
1136  Object::cast(JSFunction::cast(*object)->next_function_link()));
1137  }
1138  return count;
1139 }
1140 
1141 
1142 TEST(TestInternalWeakListsTraverseWithGC) {
1144 
1145  static const int kNumTestContexts = 10;
1146 
1147  v8::HandleScope scope;
1148  v8::Persistent<v8::Context> ctx[kNumTestContexts];
1149 
1150  CHECK_EQ(0, CountGlobalContexts());
1151 
1152  // Create an number of contexts and check the length of the weak list both
1153  // with and without GCs while iterating the list.
1154  for (int i = 0; i < kNumTestContexts; i++) {
1155  ctx[i] = v8::Context::New();
1156  CHECK_EQ(i + 1, CountGlobalContexts());
1157  CHECK_EQ(i + 1, CountGlobalContextsWithGC(i / 2 + 1));
1158  }
1159 
1160  bool opt = (FLAG_always_opt && i::V8::UseCrankshaft());
1161 
1162  // Compile a number of functions the length of the weak list of optimized
1163  // functions both with and without GCs while iterating the list.
1164  ctx[0]->Enter();
1165  const char* source = "function f1() { };"
1166  "function f2() { };"
1167  "function f3() { };"
1168  "function f4() { };"
1169  "function f5() { };";
1170  CompileRun(source);
1171  CHECK_EQ(0, CountOptimizedUserFunctions(ctx[0]));
1172  CompileRun("f1()");
1173  CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctions(ctx[0]));
1174  CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1));
1175  CompileRun("f2()");
1176  CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[0]));
1177  CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1));
1178  CompileRun("f3()");
1179  CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[0]));
1180  CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1));
1181  CompileRun("f4()");
1182  CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[0]));
1183  CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 2));
1184  CompileRun("f5()");
1185  CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[0]));
1186  CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 4));
1187 
1188  ctx[0]->Exit();
1189 }
1190 
1191 
1192 TEST(TestSizeOfObjects) {
1194 
1195  // Get initial heap size after several full GCs, which will stabilize
1196  // the heap size and return with sweeping finished completely.
1197  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1198  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1199  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1200  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1201  CHECK(HEAP->old_pointer_space()->IsSweepingComplete());
1202  int initial_size = static_cast<int>(HEAP->SizeOfObjects());
1203 
1204  {
1205  // Allocate objects on several different old-space pages so that
1206  // lazy sweeping kicks in for subsequent GC runs.
1207  AlwaysAllocateScope always_allocate;
1208  int filler_size = static_cast<int>(FixedArray::SizeFor(8192));
1209  for (int i = 1; i <= 100; i++) {
1210  HEAP->AllocateFixedArray(8192, TENURED)->ToObjectChecked();
1211  CHECK_EQ(initial_size + i * filler_size,
1212  static_cast<int>(HEAP->SizeOfObjects()));
1213  }
1214  }
1215 
1216  // The heap size should go back to initial size after a full GC, even
1217  // though sweeping didn't finish yet.
1218  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1219 
1220  // Normally sweeping would not be complete here, but no guarantees.
1221 
1222  CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects()));
1223 
1224  // Advancing the sweeper step-wise should not change the heap size.
1225  while (!HEAP->old_pointer_space()->IsSweepingComplete()) {
1226  HEAP->old_pointer_space()->AdvanceSweeper(KB);
1227  CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects()));
1228  }
1229 }
1230 
1231 
1232 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
1233  InitializeVM();
1234  HEAP->EnsureHeapIsIterable();
1235  intptr_t size_of_objects_1 = HEAP->SizeOfObjects();
1236  HeapIterator iterator;
1237  intptr_t size_of_objects_2 = 0;
1238  for (HeapObject* obj = iterator.next();
1239  obj != NULL;
1240  obj = iterator.next()) {
1241  size_of_objects_2 += obj->Size();
1242  }
1243  // Delta must be within 5% of the larger result.
1244  // TODO(gc): Tighten this up by distinguishing between byte
1245  // arrays that are real and those that merely mark free space
1246  // on the heap.
1247  if (size_of_objects_1 > size_of_objects_2) {
1248  intptr_t delta = size_of_objects_1 - size_of_objects_2;
1249  PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, "
1250  "Iterator: %" V8_PTR_PREFIX "d, "
1251  "delta: %" V8_PTR_PREFIX "d\n",
1252  size_of_objects_1, size_of_objects_2, delta);
1253  CHECK_GT(size_of_objects_1 / 20, delta);
1254  } else {
1255  intptr_t delta = size_of_objects_2 - size_of_objects_1;
1256  PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, "
1257  "Iterator: %" V8_PTR_PREFIX "d, "
1258  "delta: %" V8_PTR_PREFIX "d\n",
1259  size_of_objects_1, size_of_objects_2, delta);
1260  CHECK_GT(size_of_objects_2 / 20, delta);
1261  }
1262 }
1263 
1264 
1265 static void FillUpNewSpace(NewSpace* new_space) {
1266  // Fill up new space to the point that it is completely full. Make sure
1267  // that the scavenger does not undo the filling.
1268  v8::HandleScope scope;
1269  AlwaysAllocateScope always_allocate;
1270  intptr_t available = new_space->EffectiveCapacity() - new_space->Size();
1271  intptr_t number_of_fillers = (available / FixedArray::SizeFor(32)) - 1;
1272  for (intptr_t i = 0; i < number_of_fillers; i++) {
1273  CHECK(HEAP->InNewSpace(*FACTORY->NewFixedArray(32, NOT_TENURED)));
1274  }
1275 }
1276 
1277 
1278 TEST(GrowAndShrinkNewSpace) {
1279  InitializeVM();
1280  NewSpace* new_space = HEAP->new_space();
1281 
1282  if (HEAP->ReservedSemiSpaceSize() == HEAP->InitialSemiSpaceSize()) {
1283  // The max size cannot exceed the reserved size, since semispaces must be
1284  // always within the reserved space. We can't test new space growing and
1285  // shrinking if the reserved size is the same as the minimum (initial) size.
1286  return;
1287  }
1288 
1289  // Explicitly growing should double the space capacity.
1290  intptr_t old_capacity, new_capacity;
1291  old_capacity = new_space->Capacity();
1292  new_space->Grow();
1293  new_capacity = new_space->Capacity();
1294  CHECK(2 * old_capacity == new_capacity);
1295 
1296  old_capacity = new_space->Capacity();
1297  FillUpNewSpace(new_space);
1298  new_capacity = new_space->Capacity();
1299  CHECK(old_capacity == new_capacity);
1300 
1301  // Explicitly shrinking should not affect space capacity.
1302  old_capacity = new_space->Capacity();
1303  new_space->Shrink();
1304  new_capacity = new_space->Capacity();
1305  CHECK(old_capacity == new_capacity);
1306 
1307  // Let the scavenger empty the new space.
1308  HEAP->CollectGarbage(NEW_SPACE);
1309  CHECK_LE(new_space->Size(), old_capacity);
1310 
1311  // Explicitly shrinking should halve the space capacity.
1312  old_capacity = new_space->Capacity();
1313  new_space->Shrink();
1314  new_capacity = new_space->Capacity();
1315  CHECK(old_capacity == 2 * new_capacity);
1316 
1317  // Consecutive shrinking should not affect space capacity.
1318  old_capacity = new_space->Capacity();
1319  new_space->Shrink();
1320  new_space->Shrink();
1321  new_space->Shrink();
1322  new_capacity = new_space->Capacity();
1323  CHECK(old_capacity == new_capacity);
1324 }
1325 
1326 
1327 TEST(CollectingAllAvailableGarbageShrinksNewSpace) {
1328  InitializeVM();
1329 
1330  if (HEAP->ReservedSemiSpaceSize() == HEAP->InitialSemiSpaceSize()) {
1331  // The max size cannot exceed the reserved size, since semispaces must be
1332  // always within the reserved space. We can't test new space growing and
1333  // shrinking if the reserved size is the same as the minimum (initial) size.
1334  return;
1335  }
1336 
1337  v8::HandleScope scope;
1338  NewSpace* new_space = HEAP->new_space();
1339  intptr_t old_capacity, new_capacity;
1340  old_capacity = new_space->Capacity();
1341  new_space->Grow();
1342  new_capacity = new_space->Capacity();
1343  CHECK(2 * old_capacity == new_capacity);
1344  FillUpNewSpace(new_space);
1345  HEAP->CollectAllAvailableGarbage();
1346  new_capacity = new_space->Capacity();
1347  CHECK(old_capacity == new_capacity);
1348 }
1349 
1350 
1351 static int NumberOfGlobalObjects() {
1352  int count = 0;
1353  HeapIterator iterator;
1354  for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
1355  if (obj->IsGlobalObject()) count++;
1356  }
1357  return count;
1358 }
1359 
1360 
1361 // Test that we don't embed maps from foreign contexts into
1362 // optimized code.
1363 TEST(LeakGlobalContextViaMap) {
1364  i::FLAG_allow_natives_syntax = true;
1365  v8::HandleScope outer_scope;
1368  ctx1->Enter();
1369 
1370  HEAP->CollectAllAvailableGarbage();
1371  CHECK_EQ(4, NumberOfGlobalObjects());
1372 
1373  {
1374  v8::HandleScope inner_scope;
1375  CompileRun("var v = {x: 42}");
1376  v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v"));
1377  ctx2->Enter();
1378  ctx2->Global()->Set(v8_str("o"), v);
1379  v8::Local<v8::Value> res = CompileRun(
1380  "function f() { return o.x; }"
1381  "for (var i = 0; i < 10; ++i) f();"
1382  "%OptimizeFunctionOnNextCall(f);"
1383  "f();");
1384  CHECK_EQ(42, res->Int32Value());
1385  ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
1386  ctx2->Exit();
1387  ctx1->Exit();
1388  ctx1.Dispose();
1389  }
1390  HEAP->CollectAllAvailableGarbage();
1391  CHECK_EQ(2, NumberOfGlobalObjects());
1392  ctx2.Dispose();
1393  HEAP->CollectAllAvailableGarbage();
1394  CHECK_EQ(0, NumberOfGlobalObjects());
1395 }
1396 
1397 
1398 // Test that we don't embed functions from foreign contexts into
1399 // optimized code.
1400 TEST(LeakGlobalContextViaFunction) {
1401  i::FLAG_allow_natives_syntax = true;
1402  v8::HandleScope outer_scope;
1405  ctx1->Enter();
1406 
1407  HEAP->CollectAllAvailableGarbage();
1408  CHECK_EQ(4, NumberOfGlobalObjects());
1409 
1410  {
1411  v8::HandleScope inner_scope;
1412  CompileRun("var v = function() { return 42; }");
1413  v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v"));
1414  ctx2->Enter();
1415  ctx2->Global()->Set(v8_str("o"), v);
1416  v8::Local<v8::Value> res = CompileRun(
1417  "function f(x) { return x(); }"
1418  "for (var i = 0; i < 10; ++i) f(o);"
1419  "%OptimizeFunctionOnNextCall(f);"
1420  "f(o);");
1421  CHECK_EQ(42, res->Int32Value());
1422  ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
1423  ctx2->Exit();
1424  ctx1->Exit();
1425  ctx1.Dispose();
1426  }
1427  HEAP->CollectAllAvailableGarbage();
1428  CHECK_EQ(2, NumberOfGlobalObjects());
1429  ctx2.Dispose();
1430  HEAP->CollectAllAvailableGarbage();
1431  CHECK_EQ(0, NumberOfGlobalObjects());
1432 }
1433 
1434 
1435 TEST(LeakGlobalContextViaMapKeyed) {
1436  i::FLAG_allow_natives_syntax = true;
1437  v8::HandleScope outer_scope;
1440  ctx1->Enter();
1441 
1442  HEAP->CollectAllAvailableGarbage();
1443  CHECK_EQ(4, NumberOfGlobalObjects());
1444 
1445  {
1446  v8::HandleScope inner_scope;
1447  CompileRun("var v = [42, 43]");
1448  v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v"));
1449  ctx2->Enter();
1450  ctx2->Global()->Set(v8_str("o"), v);
1451  v8::Local<v8::Value> res = CompileRun(
1452  "function f() { return o[0]; }"
1453  "for (var i = 0; i < 10; ++i) f();"
1454  "%OptimizeFunctionOnNextCall(f);"
1455  "f();");
1456  CHECK_EQ(42, res->Int32Value());
1457  ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
1458  ctx2->Exit();
1459  ctx1->Exit();
1460  ctx1.Dispose();
1461  }
1462  HEAP->CollectAllAvailableGarbage();
1463  CHECK_EQ(2, NumberOfGlobalObjects());
1464  ctx2.Dispose();
1465  HEAP->CollectAllAvailableGarbage();
1466  CHECK_EQ(0, NumberOfGlobalObjects());
1467 }
1468 
1469 
1470 TEST(LeakGlobalContextViaMapProto) {
1471  i::FLAG_allow_natives_syntax = true;
1472  v8::HandleScope outer_scope;
1475  ctx1->Enter();
1476 
1477  HEAP->CollectAllAvailableGarbage();
1478  CHECK_EQ(4, NumberOfGlobalObjects());
1479 
1480  {
1481  v8::HandleScope inner_scope;
1482  CompileRun("var v = { y: 42}");
1483  v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v"));
1484  ctx2->Enter();
1485  ctx2->Global()->Set(v8_str("o"), v);
1486  v8::Local<v8::Value> res = CompileRun(
1487  "function f() {"
1488  " var p = {x: 42};"
1489  " p.__proto__ = o;"
1490  " return p.x;"
1491  "}"
1492  "for (var i = 0; i < 10; ++i) f();"
1493  "%OptimizeFunctionOnNextCall(f);"
1494  "f();");
1495  CHECK_EQ(42, res->Int32Value());
1496  ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
1497  ctx2->Exit();
1498  ctx1->Exit();
1499  ctx1.Dispose();
1500  }
1501  HEAP->CollectAllAvailableGarbage();
1502  CHECK_EQ(2, NumberOfGlobalObjects());
1503  ctx2.Dispose();
1504  HEAP->CollectAllAvailableGarbage();
1505  CHECK_EQ(0, NumberOfGlobalObjects());
1506 }
1507 
1508 
1509 TEST(InstanceOfStubWriteBarrier) {
1510  i::FLAG_allow_natives_syntax = true;
1511 #ifdef DEBUG
1512  i::FLAG_verify_heap = true;
1513 #endif
1514  InitializeVM();
1515  if (!i::V8::UseCrankshaft()) return;
1516  v8::HandleScope outer_scope;
1517 
1518  {
1519  v8::HandleScope scope;
1520  CompileRun(
1521  "function foo () { }"
1522  "function mkbar () { return new (new Function(\"\")) (); }"
1523  "function f (x) { return (x instanceof foo); }"
1524  "function g () { f(mkbar()); }"
1525  "f(new foo()); f(new foo());"
1526  "%OptimizeFunctionOnNextCall(f);"
1527  "f(new foo()); g();");
1528  }
1529 
1530  IncrementalMarking* marking = HEAP->incremental_marking();
1531  marking->Abort();
1532  marking->Start();
1533 
1534  Handle<JSFunction> f =
1537  v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
1538 
1539  CHECK(f->IsOptimized());
1540 
1541  while (!Marking::IsBlack(Marking::MarkBitFrom(f->code())) &&
1542  !marking->IsStopped()) {
1543  // Discard any pending GC requests otherwise we will get GC when we enter
1544  // code below.
1546  }
1547 
1548  CHECK(marking->IsMarking());
1549 
1550  {
1551  v8::HandleScope scope;
1552  v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global();
1554  v8::Handle<v8::Function>::Cast(global->Get(v8_str("g")));
1555  g->Call(global, 0, NULL);
1556  }
1557 
1558  HEAP->incremental_marking()->set_should_hurry(true);
1559  HEAP->CollectGarbage(OLD_POINTER_SPACE);
1560 }
1561 
1562 
1563 TEST(PrototypeTransitionClearing) {
1564  InitializeVM();
1565  v8::HandleScope scope;
1566 
1567  CompileRun(
1568  "var base = {};"
1569  "var live = [];"
1570  "for (var i = 0; i < 10; i++) {"
1571  " var object = {};"
1572  " var prototype = {};"
1573  " object.__proto__ = prototype;"
1574  " if (i >= 3) live.push(object, prototype);"
1575  "}");
1576 
1577  Handle<JSObject> baseObject =
1580  v8::Context::GetCurrent()->Global()->Get(v8_str("base"))));
1581 
1582  // Verify that only dead prototype transitions are cleared. There is an
1583  // extra, 11th, prototype transition on the Object map, which is the
1584  // transition to a map with the used_for_prototype flag set (the key is
1585  // the_hole).
1586  CHECK_EQ(11, baseObject->map()->NumberOfProtoTransitions());
1587  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1588  const int transitions = 11 - 3;
1589  CHECK_EQ(transitions, baseObject->map()->NumberOfProtoTransitions());
1590 
1591  // Verify that prototype transitions array was compacted.
1592  FixedArray* trans = baseObject->map()->prototype_transitions();
1593  for (int i = 0; i < transitions; i++) {
1596  CHECK(trans->get(j + Map::kProtoTransitionMapOffset)->IsMap());
1597  Object* proto = trans->get(j + Map::kProtoTransitionPrototypeOffset);
1598  CHECK(proto->IsTheHole() || proto->IsJSObject());
1599  }
1600 
1601  // Make sure next prototype is placed on an old-space evacuation candidate.
1602  Handle<JSObject> prototype;
1603  PagedSpace* space = HEAP->old_pointer_space();
1604  do {
1605  prototype = FACTORY->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED);
1606  } while (space->FirstPage() == space->LastPage() ||
1607  !space->LastPage()->Contains(prototype->address()));
1608 
1609  // Add a prototype on an evacuation candidate and verify that transition
1610  // clearing correctly records slots in prototype transition array.
1611  i::FLAG_always_compact = true;
1612  Handle<Map> map(baseObject->map());
1613  CHECK(!space->LastPage()->Contains(map->prototype_transitions()->address()));
1614  CHECK(space->LastPage()->Contains(prototype->address()));
1615  baseObject->SetPrototype(*prototype, false)->ToObjectChecked();
1616  CHECK(map->GetPrototypeTransition(*prototype)->IsMap());
1617  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1618  CHECK(map->GetPrototypeTransition(*prototype)->IsMap());
1619 }
1620 
1621 
1622 TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) {
1623  i::FLAG_allow_natives_syntax = true;
1624 #ifdef DEBUG
1625  i::FLAG_verify_heap = true;
1626 #endif
1627  InitializeVM();
1628  if (!i::V8::UseCrankshaft()) return;
1629  v8::HandleScope outer_scope;
1630 
1631  {
1632  v8::HandleScope scope;
1633  CompileRun(
1634  "function f () {"
1635  " var s = 0;"
1636  " for (var i = 0; i < 100; i++) s += i;"
1637  " return s;"
1638  "}"
1639  "f(); f();"
1640  "%OptimizeFunctionOnNextCall(f);"
1641  "f();");
1642  }
1643  Handle<JSFunction> f =
1646  v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
1647  CHECK(f->IsOptimized());
1648 
1649  IncrementalMarking* marking = HEAP->incremental_marking();
1650  marking->Abort();
1651  marking->Start();
1652 
1653  // The following two calls will increment HEAP->global_ic_age().
1654  const int kLongIdlePauseInMs = 1000;
1656  v8::V8::IdleNotification(kLongIdlePauseInMs);
1657 
1658  while (!marking->IsStopped() && !marking->IsComplete()) {
1659  marking->Step(1 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
1660  }
1661  if (!marking->IsStopped() || marking->should_hurry()) {
1662  // We don't normally finish a GC via Step(), we normally finish by
1663  // setting the stack guard and then do the final steps in the stack
1664  // guard interrupt. But here we didn't ask for that, and there is no
1665  // JS code running to trigger the interrupt, so we explicitly finalize
1666  // here.
1667  HEAP->CollectAllGarbage(Heap::kNoGCFlags,
1668  "Test finalizing incremental mark-sweep");
1669  }
1670 
1671  CHECK_EQ(HEAP->global_ic_age(), f->shared()->ic_age());
1672  CHECK_EQ(0, f->shared()->opt_count());
1673  CHECK_EQ(0, f->shared()->code()->profiler_ticks());
1674 }
1675 
1676 
1677 TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) {
1678  i::FLAG_allow_natives_syntax = true;
1679 #ifdef DEBUG
1680  i::FLAG_verify_heap = true;
1681 #endif
1682  InitializeVM();
1683  if (!i::V8::UseCrankshaft()) return;
1684  v8::HandleScope outer_scope;
1685 
1686  {
1687  v8::HandleScope scope;
1688  CompileRun(
1689  "function f () {"
1690  " var s = 0;"
1691  " for (var i = 0; i < 100; i++) s += i;"
1692  " return s;"
1693  "}"
1694  "f(); f();"
1695  "%OptimizeFunctionOnNextCall(f);"
1696  "f();");
1697  }
1698  Handle<JSFunction> f =
1701  v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
1702  CHECK(f->IsOptimized());
1703 
1704  HEAP->incremental_marking()->Abort();
1705 
1706  // The following two calls will increment HEAP->global_ic_age().
1707  // Since incremental marking is off, IdleNotification will do full GC.
1708  const int kLongIdlePauseInMs = 1000;
1710  v8::V8::IdleNotification(kLongIdlePauseInMs);
1711 
1712  CHECK_EQ(HEAP->global_ic_age(), f->shared()->ic_age());
1713  CHECK_EQ(0, f->shared()->opt_count());
1714  CHECK_EQ(0, f->shared()->code()->profiler_ticks());
1715 }
1716 
1717 
1718 // Test that HAllocateObject will always return an object in new-space.
1719 TEST(OptimizedAllocationAlwaysInNewSpace) {
1720  i::FLAG_allow_natives_syntax = true;
1721  InitializeVM();
1722  if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
1723  v8::HandleScope scope;
1724 
1725  FillUpNewSpace(HEAP->new_space());
1726  AlwaysAllocateScope always_allocate;
1727  v8::Local<v8::Value> res = CompileRun(
1728  "function c(x) {"
1729  " this.x = x;"
1730  " for (var i = 0; i < 32; i++) {"
1731  " this['x' + i] = x;"
1732  " }"
1733  "}"
1734  "function f(x) { return new c(x); };"
1735  "f(1); f(2); f(3);"
1736  "%OptimizeFunctionOnNextCall(f);"
1737  "f(4);");
1738  CHECK_EQ(4, res->ToObject()->GetRealNamedProperty(v8_str("x"))->Int32Value());
1739 
1740  Handle<JSObject> o =
1742 
1743  CHECK(HEAP->InNewSpace(*o));
1744 }
1745 
1746 
1747 static int CountMapTransitions(Map* map) {
1748  int result = 0;
1749  DescriptorArray* descs = map->instance_descriptors();
1750  for (int i = 0; i < descs->number_of_descriptors(); i++) {
1751  if (descs->IsTransitionOnly(i)) {
1752  result++;
1753  }
1754  }
1755  return result;
1756 }
1757 
1758 
1759 // Test that map transitions are cleared and maps are collected with
1760 // incremental marking as well.
1761 TEST(Regress1465) {
1762  i::FLAG_allow_natives_syntax = true;
1763  i::FLAG_trace_incremental_marking = true;
1764  InitializeVM();
1765  v8::HandleScope scope;
1766 
1767  #define TRANSITION_COUNT 256
1768  for (int i = 0; i < TRANSITION_COUNT; i++) {
1769  EmbeddedVector<char, 64> buffer;
1770  OS::SNPrintF(buffer, "var o = new Object; o.prop%d = %d;", i, i);
1771  CompileRun(buffer.start());
1772  }
1773  CompileRun("var root = new Object;");
1774  Handle<JSObject> root =
1777  v8::Context::GetCurrent()->Global()->Get(v8_str("root"))));
1778 
1779  // Count number of live transitions before marking.
1780  int transitions_before = CountMapTransitions(root->map());
1781  CompileRun("%DebugPrint(root);");
1782  CHECK_EQ(TRANSITION_COUNT, transitions_before);
1783 
1784  // Go through all incremental marking steps in one swoop.
1785  IncrementalMarking* marking = HEAP->incremental_marking();
1786  CHECK(marking->IsStopped());
1787  marking->Start();
1788  CHECK(marking->IsMarking());
1789  while (!marking->IsComplete()) {
1791  }
1792  CHECK(marking->IsComplete());
1793  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1794  CHECK(marking->IsStopped());
1795 
1796  // Count number of live transitions after marking. Note that one transition
1797  // is left, because 'o' still holds an instance of one transition target.
1798  int transitions_after = CountMapTransitions(root->map());
1799  CompileRun("%DebugPrint(root);");
1800  CHECK_EQ(1, transitions_after);
1801 }
1802 
1803 
1804 TEST(Regress2143a) {
1805  i::FLAG_collect_maps = true;
1806  i::FLAG_incremental_marking = true;
1807  InitializeVM();
1808  v8::HandleScope scope;
1809 
1810  // Prepare a map transition from the root object together with a yet
1811  // untransitioned root object.
1812  CompileRun("var root = new Object;"
1813  "root.foo = 0;"
1814  "root = new Object;");
1815 
1816  // Go through all incremental marking steps in one swoop.
1817  IncrementalMarking* marking = HEAP->incremental_marking();
1818  CHECK(marking->IsStopped());
1819  marking->Start();
1820  CHECK(marking->IsMarking());
1821  while (!marking->IsComplete()) {
1823  }
1824  CHECK(marking->IsComplete());
1825 
1826  // Compile a StoreIC that performs the prepared map transition. This
1827  // will restart incremental marking and should make sure the root is
1828  // marked grey again.
1829  CompileRun("function f(o) {"
1830  " o.foo = 0;"
1831  "}"
1832  "f(new Object);"
1833  "f(root);");
1834 
1835  // This bug only triggers with aggressive IC clearing.
1836  HEAP->AgeInlineCaches();
1837 
1838  // Explicitly request GC to perform final marking step and sweeping.
1839  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1840  CHECK(marking->IsStopped());
1841 
1842  Handle<JSObject> root =
1845  v8::Context::GetCurrent()->Global()->Get(v8_str("root"))));
1846 
1847  // The root object should be in a sane state.
1848  CHECK(root->IsJSObject());
1849  CHECK(root->map()->IsMap());
1850 }
1851 
1852 
1853 TEST(Regress2143b) {
1854  i::FLAG_collect_maps = true;
1855  i::FLAG_incremental_marking = true;
1856  i::FLAG_allow_natives_syntax = true;
1857  InitializeVM();
1858  v8::HandleScope scope;
1859 
1860  // Prepare a map transition from the root object together with a yet
1861  // untransitioned root object.
1862  CompileRun("var root = new Object;"
1863  "root.foo = 0;"
1864  "root = new Object;");
1865 
1866  // Go through all incremental marking steps in one swoop.
1867  IncrementalMarking* marking = HEAP->incremental_marking();
1868  CHECK(marking->IsStopped());
1869  marking->Start();
1870  CHECK(marking->IsMarking());
1871  while (!marking->IsComplete()) {
1873  }
1874  CHECK(marking->IsComplete());
1875 
1876  // Compile an optimized LStoreNamedField that performs the prepared
1877  // map transition. This will restart incremental marking and should
1878  // make sure the root is marked grey again.
1879  CompileRun("function f(o) {"
1880  " o.foo = 0;"
1881  "}"
1882  "f(new Object);"
1883  "f(new Object);"
1884  "%OptimizeFunctionOnNextCall(f);"
1885  "f(root);"
1886  "%DeoptimizeFunction(f);");
1887 
1888  // This bug only triggers with aggressive IC clearing.
1889  HEAP->AgeInlineCaches();
1890 
1891  // Explicitly request GC to perform final marking step and sweeping.
1892  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1893  CHECK(marking->IsStopped());
1894 
1895  Handle<JSObject> root =
1898  v8::Context::GetCurrent()->Global()->Get(v8_str("root"))));
1899 
1900  // The root object should be in a sane state.
1901  CHECK(root->IsJSObject());
1902  CHECK(root->map()->IsMap());
1903 }
static bool IsBlack(MarkBit mark_bit)
Definition: mark-compact.h:70
byte * Address
Definition: globals.h:172
static Local< Context > GetCurrent()
Definition: api.cc:4442
const SwVfpRegister s2
static const int kMaxLength
Definition: objects.h:2301
void Destroy(Object **location)
#define CHECK_EQ(expected, value)
Definition: checks.h:219
void Dispose()
Definition: v8.h:4065
bool Contains(Address addr)
Definition: spaces.h:365
void PrintF(const char *format,...)
Definition: v8utils.cc:40
static String * cast(Object *obj)
static bool UseCrankshaft()
Definition: v8.h:86
V8EXPORT Local< Value > Get(Handle< Value > key)
Definition: api.cc:2845
static Smi * FromInt(int value)
Definition: objects-inl.h:973
const int KB
Definition: globals.h:221
#define CHECK_GT(a, b)
Definition: checks.h:227
value format" "after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false, "print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false, "print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false, "report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true, "garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true, "flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true, "use incremental marking") DEFINE_bool(incremental_marking_steps, true, "do incremental marking steps") DEFINE_bool(trace_incremental_marking, false, "trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true, "Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false, "Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true, "use inline caching") DEFINE_bool(native_code_counters, false, "generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false, "Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true, "Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false, "Never perform compaction on full GC-testing only") DEFINE_bool(compact_code_space, true, "Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true, "Flush inline caches prior to mark compact collection and" "flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0, "Default seed for initializing random generator" "(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true, "allows verbose printing") DEFINE_bool(allow_natives_syntax, false, "allow natives syntax") DEFINE_bool(trace_sim, false, "Trace simulator execution") DEFINE_bool(check_icache, false, "Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0, "Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8, "Stack alingment in bytes in simulator(4 or 8, 8 is default)") DEFINE_bool(trace_exception, false, "print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false, "preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true, "randomize hashes to avoid predictable hash collisions" "(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0, "Fixed seed to use to hash property keys(0 means random)" "(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false, "activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true, "generate optimized regexp code") DEFINE_bool(testing_bool_flag, true, "testing_bool_flag") DEFINE_int(testing_int_flag, 13, "testing_int_flag") DEFINE_float(testing_float_flag, 2.5, "float-flag") DEFINE_string(testing_string_flag, "Hello, world!", "string-flag") DEFINE_int(testing_prng_seed, 42, "Seed used for threading test randomness") DEFINE_string(testing_serialization_file, "/tmp/serdes", "file in which to serialize heap") DEFINE_bool(help, false, "Print usage message, including flags, on console") DEFINE_bool(dump_counters, false, "Dump counters on exit") DEFINE_string(map_counters, "", "Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT, "Pass all remaining arguments to the script.Alias for\"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#43"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2#define FLAG_MODE_DEFINE_DEFAULTS#1"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flag-definitions.h"1#define FLAG_FULL(ftype, ctype, nam, def, cmt)#define FLAG_READONLY(ftype, ctype, nam, def, cmt)#define DEFINE_implication(whenflag, thenflag)#define DEFINE_bool(nam, def, cmt)#define DEFINE_int(nam, def, cmt)#define DEFINE_float(nam, def, cmt)#define DEFINE_string(nam, def, cmt)#define DEFINE_args(nam, def, cmt)#define FLAG DEFINE_bool(use_strict, false,"enforce strict mode") DEFINE_bool(es5_readonly, false,"activate correct semantics for inheriting readonliness") DEFINE_bool(es52_globals, false,"activate new semantics for global var declarations") DEFINE_bool(harmony_typeof, false,"enable harmony semantics for typeof") DEFINE_bool(harmony_scoping, false,"enable harmony block scoping") DEFINE_bool(harmony_modules, false,"enable harmony modules (implies block scoping)") DEFINE_bool(harmony_proxies, false,"enable harmony proxies") DEFINE_bool(harmony_collections, false,"enable harmony collections (sets, maps, and weak maps)") DEFINE_bool(harmony, false,"enable all harmony features (except typeof)") DEFINE_implication(harmony, harmony_scoping) DEFINE_implication(harmony, harmony_modules) DEFINE_implication(harmony, harmony_proxies) DEFINE_implication(harmony, harmony_collections) DEFINE_implication(harmony_modules, harmony_scoping) DEFINE_bool(packed_arrays, false,"optimizes arrays that have no holes") DEFINE_bool(smi_only_arrays, true,"tracks arrays with only smi values") DEFINE_bool(clever_optimizations, true,"Optimize object size, Array shift, DOM strings and string +") DEFINE_bool(unbox_double_arrays, true,"automatically unbox arrays of doubles") DEFINE_bool(string_slices, true,"use string slices") DEFINE_bool(crankshaft, true,"use crankshaft") DEFINE_string(hydrogen_filter,"","optimization filter") DEFINE_bool(use_range, true,"use hydrogen range analysis") DEFINE_bool(eliminate_dead_phis, true,"eliminate dead phis") DEFINE_bool(use_gvn, true,"use hydrogen global value numbering") DEFINE_bool(use_canonicalizing, true,"use hydrogen instruction canonicalizing") DEFINE_bool(use_inlining, true,"use function inlining") DEFINE_int(max_inlined_source_size, 600,"maximum source size in bytes considered for a single inlining") DEFINE_int(max_inlined_nodes, 196,"maximum number of AST nodes considered for a single inlining") DEFINE_int(max_inlined_nodes_cumulative, 196,"maximum cumulative number of AST nodes considered for inlining") DEFINE_bool(loop_invariant_code_motion, true,"loop invariant code motion") DEFINE_bool(collect_megamorphic_maps_from_stub_cache, true,"crankshaft harvests type feedback from stub cache") DEFINE_bool(hydrogen_stats, false,"print statistics for hydrogen") DEFINE_bool(trace_hydrogen, false,"trace generated hydrogen to file") DEFINE_string(trace_phase,"Z","trace generated IR for specified phases") DEFINE_bool(trace_inlining, false,"trace inlining decisions") DEFINE_bool(trace_alloc, false,"trace register allocator") DEFINE_bool(trace_all_uses, false,"trace all use positions") DEFINE_bool(trace_range, false,"trace range analysis") DEFINE_bool(trace_gvn, false,"trace global value numbering") DEFINE_bool(trace_representation, false,"trace representation types") DEFINE_bool(stress_pointer_maps, false,"pointer map for every instruction") DEFINE_bool(stress_environments, false,"environment for every instruction") DEFINE_int(deopt_every_n_times, 0,"deoptimize every n times a deopt point is passed") DEFINE_bool(trap_on_deopt, false,"put a break point before deoptimizing") DEFINE_bool(deoptimize_uncommon_cases, true,"deoptimize uncommon cases") DEFINE_bool(polymorphic_inlining, true,"polymorphic inlining") DEFINE_bool(use_osr, true,"use on-stack replacement") DEFINE_bool(array_bounds_checks_elimination, false,"perform array bounds checks elimination") DEFINE_bool(array_index_dehoisting, false,"perform array index dehoisting") DEFINE_bool(trace_osr, false,"trace on-stack replacement") DEFINE_int(stress_runs, 0,"number of stress runs") DEFINE_bool(optimize_closures, true,"optimize closures") DEFINE_bool(inline_construct, true,"inline constructor calls") DEFINE_bool(inline_arguments, true,"inline functions with arguments object") DEFINE_int(loop_weight, 1,"loop weight for representation inference") DEFINE_bool(optimize_for_in, true,"optimize functions containing for-in loops") DEFINE_bool(experimental_profiler, true,"enable all profiler experiments") DEFINE_bool(watch_ic_patching, false,"profiler considers IC stability") DEFINE_int(frame_count, 1,"number of stack frames inspected by the profiler") DEFINE_bool(self_optimization, false,"primitive functions trigger their own optimization") DEFINE_bool(direct_self_opt, false,"call recompile stub directly when self-optimizing") DEFINE_bool(retry_self_opt, false,"re-try self-optimization if it failed") DEFINE_bool(count_based_interrupts, false,"trigger profiler ticks based on counting instead of timing") DEFINE_bool(interrupt_at_exit, false,"insert an interrupt check at function exit") DEFINE_bool(weighted_back_edges, false,"weight back edges by jump distance for interrupt triggering") DEFINE_int(interrupt_budget, 5900,"execution budget before interrupt is triggered") DEFINE_int(type_info_threshold, 15,"percentage of ICs that must have type info to allow optimization") DEFINE_int(self_opt_count, 130,"call count before self-optimization") DEFINE_implication(experimental_profiler, watch_ic_patching) DEFINE_implication(experimental_profiler, self_optimization) DEFINE_implication(experimental_profiler, retry_self_opt) DEFINE_implication(experimental_profiler, count_based_interrupts) DEFINE_implication(experimental_profiler, interrupt_at_exit) DEFINE_implication(experimental_profiler, weighted_back_edges) DEFINE_bool(trace_opt_verbose, false,"extra verbose compilation tracing") DEFINE_implication(trace_opt_verbose, trace_opt) DEFINE_bool(debug_code, false,"generate extra code (assertions) for debugging") DEFINE_bool(code_comments, false,"emit comments in code disassembly") DEFINE_bool(enable_sse2, true,"enable use of SSE2 instructions if available") DEFINE_bool(enable_sse3, true,"enable use of SSE3 instructions if available") DEFINE_bool(enable_sse4_1, true,"enable use of SSE4.1 instructions if available") DEFINE_bool(enable_cmov, true,"enable use of CMOV instruction if available") DEFINE_bool(enable_rdtsc, true,"enable use of RDTSC instruction if available") DEFINE_bool(enable_sahf, true,"enable use of SAHF instruction if available (X64 only)") DEFINE_bool(enable_vfp3, true,"enable use of VFP3 instructions if available - this implies ""enabling ARMv7 instructions (ARM only)") DEFINE_bool(enable_armv7, true,"enable use of ARMv7 instructions if available (ARM only)") DEFINE_bool(enable_fpu, true,"enable use of MIPS FPU instructions if available (MIPS only)") DEFINE_string(expose_natives_as, NULL,"expose natives in global object") DEFINE_string(expose_debug_as, NULL,"expose debug in global object") DEFINE_bool(expose_gc, false,"expose gc extension") DEFINE_bool(expose_externalize_string, false,"expose externalize string extension") DEFINE_int(stack_trace_limit, 10,"number of stack frames to capture") DEFINE_bool(builtins_in_stack_traces, false,"show built-in functions in stack traces") DEFINE_bool(disable_native_files, false,"disable builtin natives files") DEFINE_bool(inline_new, true,"use fast inline allocation") DEFINE_bool(stack_trace_on_abort, true,"print a stack trace if an assertion failure occurs") DEFINE_bool(trace, false,"trace function calls") DEFINE_bool(mask_constants_with_cookie, true,"use random jit cookie to mask large constants") DEFINE_bool(lazy, true,"use lazy compilation") DEFINE_bool(trace_opt, false,"trace lazy optimization") DEFINE_bool(trace_opt_stats, false,"trace lazy optimization statistics") DEFINE_bool(opt, true,"use adaptive optimizations") DEFINE_bool(always_opt, false,"always try to optimize functions") DEFINE_bool(prepare_always_opt, false,"prepare for turning on always opt") DEFINE_bool(trace_deopt, false,"trace deoptimization") DEFINE_int(min_preparse_length, 1024,"minimum length for automatic enable preparsing") DEFINE_bool(always_full_compiler, false,"try to use the dedicated run-once backend for all code") DEFINE_bool(trace_bailout, false,"print reasons for falling back to using the classic V8 backend") DEFINE_bool(compilation_cache, true,"enable compilation cache") DEFINE_bool(cache_prototype_transitions, true,"cache prototype transitions") DEFINE_bool(trace_debug_json, false,"trace debugging JSON request/response") DEFINE_bool(debugger_auto_break, true,"automatically set the debug break flag when debugger commands are ""in the queue") DEFINE_bool(enable_liveedit, true,"enable liveedit experimental feature") DEFINE_bool(break_on_abort, true,"always cause a debug break before aborting") DEFINE_int(stack_size, kPointerSize *123,"default size of stack region v8 is allowed to use (in kBytes)") DEFINE_int(max_stack_trace_source_length, 300,"maximum length of function source code printed in a stack trace.") DEFINE_bool(always_inline_smi_code, false,"always inline smi code in non-opt code") DEFINE_int(max_new_space_size, 0,"max size of the new generation (in kBytes)") DEFINE_int(max_old_space_size, 0,"max size of the old generation (in Mbytes)") DEFINE_int(max_executable_size, 0,"max size of executable memory (in Mbytes)") DEFINE_bool(gc_global, false,"always perform global GCs") DEFINE_int(gc_interval,-1,"garbage collect after <n> allocations") DEFINE_bool(trace_gc, false,"print one trace line following each garbage collection") DEFINE_bool(trace_gc_nvp, false,"print one detailed trace line in name=value format ""after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false,"print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false,"print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false,"report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true,"garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true,"flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true,"use incremental marking") DEFINE_bool(incremental_marking_steps, true,"do incremental marking steps") DEFINE_bool(trace_incremental_marking, false,"trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true,"Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false,"Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true,"use inline caching") DEFINE_bool(native_code_counters, false,"generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false,"Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true,"Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false,"Never perform compaction on full GC - testing only") DEFINE_bool(compact_code_space, true,"Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true,"Flush inline caches prior to mark compact collection and ""flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0,"Default seed for initializing random generator ""(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true,"allows verbose printing") DEFINE_bool(allow_natives_syntax, false,"allow natives syntax") DEFINE_bool(trace_sim, false,"Trace simulator execution") DEFINE_bool(check_icache, false,"Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0,"Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8,"Stack alingment in bytes in simulator (4 or 8, 8 is default)") DEFINE_bool(trace_exception, false,"print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false,"preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true,"randomize hashes to avoid predictable hash collisions ""(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0,"Fixed seed to use to hash property keys (0 means random)""(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false,"activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true,"generate optimized regexp code") DEFINE_bool(testing_bool_flag, true,"testing_bool_flag") DEFINE_int(testing_int_flag, 13,"testing_int_flag") DEFINE_float(testing_float_flag, 2.5,"float-flag") DEFINE_string(testing_string_flag,"Hello, world!","string-flag") DEFINE_int(testing_prng_seed, 42,"Seed used for threading test randomness") DEFINE_string(testing_serialization_file,"/tmp/serdes","file in which to serialize heap") DEFINE_bool(help, false,"Print usage message, including flags, on console") DEFINE_bool(dump_counters, false,"Dump counters on exit") DEFINE_string(map_counters,"","Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT,"Pass all remaining arguments to the script. Alias for \"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#47"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2 namespace{struct Flag{enum FlagType{TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_ARGS} name
Definition: flags.cc:1349
static HeapObject * cast(Object *obj)
static Handle< T > cast(Handle< S > that)
Definition: handles.h:81
static const int kProtoTransitionElementsPerEntry
Definition: objects.h:4802
const int kVariableSizeSentinel
Definition: objects.h:182
bool is_identical_to(const Handle< T > other) const
Definition: handles.h:67
Address * allocation_top_address()
Definition: spaces.h:2183
bool IsTransitionOnly(int descriptor_number)
Definition: objects-inl.h:2043
static bool IsNearDeath(Object **location)
static Failure * Exception()
Definition: objects-inl.h:1016
static Handle< T > Cast(Handle< S > that)
Definition: v8.h:243
V8EXPORT Local< Value > Call(Handle< Object > recv, int argc, Handle< Value > argv[])
Definition: api.cc:3629
void Clear()
Definition: v8.h:213
Map * GetPrototypeTransition(Object *prototype)
Definition: objects.cc:8733
void Step(intptr_t allocated, CompletionAction action)
static Context * cast(Object *context)
Definition: contexts.h:207
#define CHECK(condition)
Definition: checks.h:56
int isnan(double x)
Handle< Object > GetProperty(Handle< JSReceiver > obj, const char *name)
Definition: handles.cc:282
static const int kMaxSize
Definition: objects.h:2299
intptr_t EffectiveCapacity()
Definition: spaces.h:2119
static Smi * cast(Object *object)
static MarkBit MarkBitFrom(Address addr)
T ** location() const
Definition: handles.h:75
T * start() const
Definition: utils.h:389
bool Contains(Address a)
Definition: spaces.h:2097
static const int kProtoTransitionMapOffset
Definition: objects.h:4804
Handle< Object > Create(Object *value)
static Failure * RetryAfterGC()
Definition: objects-inl.h:1032
static const int kMinValue
Definition: objects.h:1004
static const int kNoGCFlags
Definition: heap.h:1049
const int kPointerSize
Definition: globals.h:234
virtual intptr_t Size()
Definition: spaces.h:2108
static int ContextDisposedNotification()
Definition: api.cc:4284
#define __
V8EXPORT int32_t Int32Value() const
Definition: api.cc:2654
static const int kSize
Definition: objects.h:4972
static const int kMaxNonCodeHeapObjectSize
Definition: spaces.h:701
#define V8_PTR_PREFIX
Definition: globals.h:196
static const int kAbortIncrementalMarkingMask
Definition: heap.h:1052
Vector< const char > CStrVector(const char *data)
Definition: utils.h:525
int StrLength(const char *string)
Definition: utils.h:234
#define CHECK_LE(a, b)
Definition: checks.h:230
static int SizeFor(int length)
Definition: objects.h:2288
static const int kProtoTransitionHeaderSize
Definition: objects.h:4799
const SwVfpRegister s1
static const int kHeaderSize
Definition: objects.h:2233
static int SNPrintF(Vector< char > str, const char *format,...)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if available(X64 only)") DEFINE_bool(enable_vfp3
intptr_t Capacity()
Definition: spaces.h:2125
static const int kSize
Definition: objects.h:1315
bool is_null() const
Definition: handles.h:87
#define OBJECT_POINTER_ALIGN(value)
Definition: v8globals.h:397
static Object * cast(Object *value)
Definition: objects.h:962
static Flags ComputeFlags(Kind kind, InlineCacheState ic_state=UNINITIALIZED, ExtraICState extra_ic_state=kNoExtraICState, PropertyType type=NORMAL, int argc=-1, InlineCacheHolderFlag holder=OWN_MAP)
Definition: objects-inl.h:3312
Handle< T > EscapeFrom(v8::HandleScope *scope)
Definition: api.h:254
static const int kProtoTransitionPrototypeOffset
Definition: objects.h:4803
#define HEAP
Definition: isolate.h:1408
MUST_USE_RESULT MaybeObject * GetProperty(String *key)
Definition: objects-inl.h:851
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Definition: flags.cc:274
InstanceType instance_type()
Definition: objects-inl.h:2864
static V8EXPORT Local< Integer > New(int32_t value)
Definition: api.cc:5100
static FixedArray * cast(Object *obj)
static const int kHeaderSize
Definition: objects.h:2115
bool IsEmpty() const
Definition: v8.h:208
#define FACTORY
Definition: isolate.h:1409
Object * get(int index)
Definition: objects-inl.h:1675
static Handle< Object > ToString(Handle< Object > obj, bool *exc)
Definition: execution.cc:614
static Persistent< Context > New(ExtensionConfiguration *extensions=NULL, Handle< ObjectTemplate > global_template=Handle< ObjectTemplate >(), Handle< Value > global_object=Handle< Value >())
Definition: api.cc:4308
V8EXPORT Local< Object > ToObject() const
Definition: api.cc:2345
Address * allocation_limit_address()
Definition: spaces.h:2184
void MakeWeak(Object **location, void *parameter, WeakReferenceCallback callback)
void DeleteArray(T *array)
Definition: allocation.h:91
T Min(T a, T b)
Definition: utils.h:229
static const int kMaxValue
Definition: objects.h:1006
Definition: v8.h:105
static JSObject * cast(Object *obj)
static bool Initialize()
Definition: api.cc:4204
FlagType type() const
Definition: flags.cc:1358
#define TRANSITION_COUNT
static v8::internal::Handle< v8::internal::TemplateInfo > OpenHandle(const Template *that)
Handle< JSObject > Copy(Handle< JSObject > obj)
Definition: handles.cc:335
static bool IdleNotification(int hint=1000)
Definition: api.cc:4268
const int MB
Definition: globals.h:222
static JSFunction * cast(Object *obj)