| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 #include "macro-assembler.h" | 35 #include "macro-assembler.h" |
| 36 #include "global-handles.h" | 36 #include "global-handles.h" |
| 37 #include "stub-cache.h" | 37 #include "stub-cache.h" |
| 38 #include "cctest.h" | 38 #include "cctest.h" |
| 39 | 39 |
| 40 using namespace v8::internal; | 40 using namespace v8::internal; |
| 41 | 41 |
| 42 | 42 |
| 43 // Go through all incremental marking steps in one swoop. | 43 // Go through all incremental marking steps in one swoop. |
| 44 static void SimulateIncrementalMarking() { | 44 static void SimulateIncrementalMarking() { |
| 45 MarkCompactCollector* collector = HEAP->mark_compact_collector(); | 45 MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector(); |
| 46 IncrementalMarking* marking = HEAP->incremental_marking(); | 46 IncrementalMarking* marking = CcTest::heap()->incremental_marking(); |
| 47 if (collector->IsConcurrentSweepingInProgress()) { | 47 if (collector->IsConcurrentSweepingInProgress()) { |
| 48 collector->WaitUntilSweepingCompleted(); | 48 collector->WaitUntilSweepingCompleted(); |
| 49 } | 49 } |
| 50 CHECK(marking->IsMarking() || marking->IsStopped()); | 50 CHECK(marking->IsMarking() || marking->IsStopped()); |
| 51 if (marking->IsStopped()) { | 51 if (marking->IsStopped()) { |
| 52 marking->Start(); | 52 marking->Start(); |
| 53 } | 53 } |
| 54 CHECK(marking->IsMarking()); | 54 CHECK(marking->IsMarking()); |
| 55 while (!marking->IsComplete()) { | 55 while (!marking->IsComplete()) { |
| 56 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | 56 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 57 } | 57 } |
| 58 CHECK(marking->IsComplete()); | 58 CHECK(marking->IsComplete()); |
| 59 } | 59 } |
| 60 | 60 |
| 61 | 61 |
| 62 static void CheckMap(Map* map, int type, int instance_size) { | 62 static void CheckMap(Map* map, int type, int instance_size) { |
| 63 CHECK(map->IsHeapObject()); | 63 CHECK(map->IsHeapObject()); |
| 64 #ifdef DEBUG | 64 #ifdef DEBUG |
| 65 CHECK(HEAP->Contains(map)); | 65 CHECK(CcTest::heap()->Contains(map)); |
| 66 #endif | 66 #endif |
| 67 CHECK_EQ(HEAP->meta_map(), map->map()); | 67 CHECK_EQ(CcTest::heap()->meta_map(), map->map()); |
| 68 CHECK_EQ(type, map->instance_type()); | 68 CHECK_EQ(type, map->instance_type()); |
| 69 CHECK_EQ(instance_size, map->instance_size()); | 69 CHECK_EQ(instance_size, map->instance_size()); |
| 70 } | 70 } |
| 71 | 71 |
| 72 | 72 |
| 73 TEST(HeapMaps) { | 73 TEST(HeapMaps) { |
| 74 CcTest::InitializeVM(); | 74 CcTest::InitializeVM(); |
| 75 CheckMap(HEAP->meta_map(), MAP_TYPE, Map::kSize); | 75 Heap* heap = CcTest::heap(); |
| 76 CheckMap(HEAP->heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize); | 76 CheckMap(heap->meta_map(), MAP_TYPE, Map::kSize); |
| 77 CheckMap(HEAP->fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel); | 77 CheckMap(heap->heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize); |
| 78 CheckMap(HEAP->string_map(), STRING_TYPE, kVariableSizeSentinel); | 78 CheckMap(heap->fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel); |
| 79 CheckMap(heap->string_map(), STRING_TYPE, kVariableSizeSentinel); |
| 79 } | 80 } |
| 80 | 81 |
| 81 | 82 |
| 82 static void CheckOddball(Isolate* isolate, Object* obj, const char* string) { | 83 static void CheckOddball(Isolate* isolate, Object* obj, const char* string) { |
| 83 CHECK(obj->IsOddball()); | 84 CHECK(obj->IsOddball()); |
| 84 bool exc; | 85 bool exc; |
| 85 Handle<Object> handle(obj, isolate); | 86 Handle<Object> handle(obj, isolate); |
| 86 Object* print_string = | 87 Object* print_string = |
| 87 *Execution::ToString(isolate, handle, &exc); | 88 *Execution::ToString(isolate, handle, &exc); |
| 88 CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string))); | 89 CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string))); |
| 89 } | 90 } |
| 90 | 91 |
| 91 | 92 |
| 92 static void CheckSmi(Isolate* isolate, int value, const char* string) { | 93 static void CheckSmi(Isolate* isolate, int value, const char* string) { |
| 93 bool exc; | 94 bool exc; |
| 94 Handle<Object> handle(Smi::FromInt(value), isolate); | 95 Handle<Object> handle(Smi::FromInt(value), isolate); |
| 95 Object* print_string = | 96 Object* print_string = |
| 96 *Execution::ToString(isolate, handle, &exc); | 97 *Execution::ToString(isolate, handle, &exc); |
| 97 CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string))); | 98 CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string))); |
| 98 } | 99 } |
| 99 | 100 |
| 100 | 101 |
| 101 static void CheckNumber(Isolate* isolate, double value, const char* string) { | 102 static void CheckNumber(Isolate* isolate, double value, const char* string) { |
| 102 Object* obj = HEAP->NumberFromDouble(value)->ToObjectChecked(); | 103 Object* obj = CcTest::heap()->NumberFromDouble(value)->ToObjectChecked(); |
| 103 CHECK(obj->IsNumber()); | 104 CHECK(obj->IsNumber()); |
| 104 bool exc; | 105 bool exc; |
| 105 Handle<Object> handle(obj, isolate); | 106 Handle<Object> handle(obj, isolate); |
| 106 Object* print_string = | 107 Object* print_string = |
| 107 *Execution::ToString(isolate, handle, &exc); | 108 *Execution::ToString(isolate, handle, &exc); |
| 108 CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string))); | 109 CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string))); |
| 109 } | 110 } |
| 110 | 111 |
| 111 | 112 |
| 112 static void CheckFindCodeObject(Isolate* isolate) { | 113 static void CheckFindCodeObject(Isolate* isolate) { |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 "volatile", | 583 "volatile", |
| 583 "while", | 584 "while", |
| 584 "with", | 585 "with", |
| 585 0 | 586 0 |
| 586 }; | 587 }; |
| 587 | 588 |
| 588 | 589 |
| 589 static void CheckInternalizedStrings(const char** strings) { | 590 static void CheckInternalizedStrings(const char** strings) { |
| 590 for (const char* string = *strings; *strings != 0; string = *strings++) { | 591 for (const char* string = *strings; *strings != 0; string = *strings++) { |
| 591 Object* a; | 592 Object* a; |
| 592 MaybeObject* maybe_a = HEAP->InternalizeUtf8String(string); | 593 MaybeObject* maybe_a = CcTest::heap()->InternalizeUtf8String(string); |
| 593 // InternalizeUtf8String may return a failure if a GC is needed. | 594 // InternalizeUtf8String may return a failure if a GC is needed. |
| 594 if (!maybe_a->ToObject(&a)) continue; | 595 if (!maybe_a->ToObject(&a)) continue; |
| 595 CHECK(a->IsInternalizedString()); | 596 CHECK(a->IsInternalizedString()); |
| 596 Object* b; | 597 Object* b; |
| 597 MaybeObject* maybe_b = HEAP->InternalizeUtf8String(string); | 598 MaybeObject* maybe_b = CcTest::heap()->InternalizeUtf8String(string); |
| 598 if (!maybe_b->ToObject(&b)) continue; | 599 if (!maybe_b->ToObject(&b)) continue; |
| 599 CHECK_EQ(b, a); | 600 CHECK_EQ(b, a); |
| 600 CHECK(String::cast(b)->IsUtf8EqualTo(CStrVector(string))); | 601 CHECK(String::cast(b)->IsUtf8EqualTo(CStrVector(string))); |
| 601 } | 602 } |
| 602 } | 603 } |
| 603 | 604 |
| 604 | 605 |
| 605 TEST(StringTable) { | 606 TEST(StringTable) { |
| 606 CcTest::InitializeVM(); | 607 CcTest::InitializeVM(); |
| 607 | 608 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 636 CHECK_EQ(Smi::FromInt(24), function->GetProperty(*prop_name)); | 637 CHECK_EQ(Smi::FromInt(24), function->GetProperty(*prop_name)); |
| 637 } | 638 } |
| 638 | 639 |
| 639 | 640 |
| 640 TEST(ObjectProperties) { | 641 TEST(ObjectProperties) { |
| 641 CcTest::InitializeVM(); | 642 CcTest::InitializeVM(); |
| 642 Isolate* isolate = CcTest::i_isolate(); | 643 Isolate* isolate = CcTest::i_isolate(); |
| 643 Factory* factory = isolate->factory(); | 644 Factory* factory = isolate->factory(); |
| 644 | 645 |
| 645 v8::HandleScope sc(CcTest::isolate()); | 646 v8::HandleScope sc(CcTest::isolate()); |
| 646 String* object_string = String::cast(HEAP->Object_string()); | 647 String* object_string = String::cast(CcTest::heap()->Object_string()); |
| 647 Object* raw_object = CcTest::i_isolate()->context()->global_object()-> | 648 Object* raw_object = CcTest::i_isolate()->context()->global_object()-> |
| 648 GetProperty(object_string)->ToObjectChecked(); | 649 GetProperty(object_string)->ToObjectChecked(); |
| 649 JSFunction* object_function = JSFunction::cast(raw_object); | 650 JSFunction* object_function = JSFunction::cast(raw_object); |
| 650 Handle<JSFunction> constructor(object_function); | 651 Handle<JSFunction> constructor(object_function); |
| 651 Handle<JSObject> obj = factory->NewJSObject(constructor); | 652 Handle<JSObject> obj = factory->NewJSObject(constructor); |
| 652 Handle<String> first = factory->InternalizeUtf8String("first"); | 653 Handle<String> first = factory->InternalizeUtf8String("first"); |
| 653 Handle<String> second = factory->InternalizeUtf8String("second"); | 654 Handle<String> second = factory->InternalizeUtf8String("second"); |
| 654 | 655 |
| 655 Handle<Smi> one(Smi::FromInt(1), isolate); | 656 Handle<Smi> one(Smi::FromInt(1), isolate); |
| 656 Handle<Smi> two(Smi::FromInt(2), isolate); | 657 Handle<Smi> two(Smi::FromInt(2), isolate); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 CHECK_EQ(array->GetElement(isolate, 0), *name); | 783 CHECK_EQ(array->GetElement(isolate, 0), *name); |
| 783 } | 784 } |
| 784 | 785 |
| 785 | 786 |
| 786 TEST(JSObjectCopy) { | 787 TEST(JSObjectCopy) { |
| 787 CcTest::InitializeVM(); | 788 CcTest::InitializeVM(); |
| 788 Isolate* isolate = CcTest::i_isolate(); | 789 Isolate* isolate = CcTest::i_isolate(); |
| 789 Factory* factory = isolate->factory(); | 790 Factory* factory = isolate->factory(); |
| 790 | 791 |
| 791 v8::HandleScope sc(CcTest::isolate()); | 792 v8::HandleScope sc(CcTest::isolate()); |
| 792 String* object_string = String::cast(HEAP->Object_string()); | 793 String* object_string = String::cast(CcTest::heap()->Object_string()); |
| 793 Object* raw_object = CcTest::i_isolate()->context()->global_object()-> | 794 Object* raw_object = CcTest::i_isolate()->context()->global_object()-> |
| 794 GetProperty(object_string)->ToObjectChecked(); | 795 GetProperty(object_string)->ToObjectChecked(); |
| 795 JSFunction* object_function = JSFunction::cast(raw_object); | 796 JSFunction* object_function = JSFunction::cast(raw_object); |
| 796 Handle<JSFunction> constructor(object_function); | 797 Handle<JSFunction> constructor(object_function); |
| 797 Handle<JSObject> obj = factory->NewJSObject(constructor); | 798 Handle<JSObject> obj = factory->NewJSObject(constructor); |
| 798 Handle<String> first = factory->InternalizeUtf8String("first"); | 799 Handle<String> first = factory->InternalizeUtf8String("first"); |
| 799 Handle<String> second = factory->InternalizeUtf8String("second"); | 800 Handle<String> second = factory->InternalizeUtf8String("second"); |
| 800 | 801 |
| 801 Handle<Smi> one(Smi::FromInt(1), isolate); | 802 Handle<Smi> one(Smi::FromInt(1), isolate); |
| 802 Handle<Smi> two(Smi::FromInt(2), isolate); | 803 Handle<Smi> two(Smi::FromInt(2), isolate); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 916 for (int i = 0; i < large_size - 1; ++i) str[i] = 'a'; | 917 for (int i = 0; i < large_size - 1; ++i) str[i] = 'a'; |
| 917 str[large_size - 1] = '\0'; | 918 str[large_size - 1] = '\0'; |
| 918 objs[next_objs_index++] = | 919 objs[next_objs_index++] = |
| 919 factory->NewStringFromAscii(CStrVector(str), TENURED); | 920 factory->NewStringFromAscii(CStrVector(str), TENURED); |
| 920 delete[] str; | 921 delete[] str; |
| 921 | 922 |
| 922 // Add a Map object to look for. | 923 // Add a Map object to look for. |
| 923 objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map()); | 924 objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map()); |
| 924 | 925 |
| 925 CHECK_EQ(objs_count, next_objs_index); | 926 CHECK_EQ(objs_count, next_objs_index); |
| 926 CHECK_EQ(objs_count, ObjectsFoundInHeap(HEAP, objs, objs_count)); | 927 CHECK_EQ(objs_count, ObjectsFoundInHeap(CcTest::heap(), objs, objs_count)); |
| 927 } | 928 } |
| 928 | 929 |
| 929 | 930 |
| 930 TEST(EmptyHandleEscapeFrom) { | 931 TEST(EmptyHandleEscapeFrom) { |
| 931 CcTest::InitializeVM(); | 932 CcTest::InitializeVM(); |
| 932 | 933 |
| 933 v8::HandleScope scope(CcTest::isolate()); | 934 v8::HandleScope scope(CcTest::isolate()); |
| 934 Handle<JSObject> runaway; | 935 Handle<JSObject> runaway; |
| 935 | 936 |
| 936 { | 937 { |
| 937 v8::HandleScope nested(CcTest::isolate()); | 938 v8::HandleScope nested(CcTest::isolate()); |
| 938 Handle<JSObject> empty; | 939 Handle<JSObject> empty; |
| 939 runaway = empty.EscapeFrom(&nested); | 940 runaway = empty.EscapeFrom(&nested); |
| 940 } | 941 } |
| 941 | 942 |
| 942 CHECK(runaway.is_null()); | 943 CHECK(runaway.is_null()); |
| 943 } | 944 } |
| 944 | 945 |
| 945 | 946 |
| 946 static int LenFromSize(int size) { | 947 static int LenFromSize(int size) { |
| 947 return (size - FixedArray::kHeaderSize) / kPointerSize; | 948 return (size - FixedArray::kHeaderSize) / kPointerSize; |
| 948 } | 949 } |
| 949 | 950 |
| 950 | 951 |
| 951 TEST(Regression39128) { | 952 TEST(Regression39128) { |
| 952 // Test case for crbug.com/39128. | 953 // Test case for crbug.com/39128. |
| 953 CcTest::InitializeVM(); | 954 CcTest::InitializeVM(); |
| 954 Isolate* isolate = CcTest::i_isolate(); | 955 Isolate* isolate = CcTest::i_isolate(); |
| 955 Factory* factory = isolate->factory(); | 956 Factory* factory = isolate->factory(); |
| 957 Heap* heap = isolate->heap(); |
| 956 | 958 |
| 957 // Increase the chance of 'bump-the-pointer' allocation in old space. | 959 // Increase the chance of 'bump-the-pointer' allocation in old space. |
| 958 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 960 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 959 | 961 |
| 960 v8::HandleScope scope(CcTest::isolate()); | 962 v8::HandleScope scope(CcTest::isolate()); |
| 961 | 963 |
| 962 // The plan: create JSObject which references objects in new space. | 964 // The plan: create JSObject which references objects in new space. |
| 963 // Then clone this object (forcing it to go into old space) and check | 965 // Then clone this object (forcing it to go into old space) and check |
| 964 // that region dirty marks are updated correctly. | 966 // that region dirty marks are updated correctly. |
| 965 | 967 |
| 966 // Step 1: prepare a map for the object. We add 1 inobject property to it. | 968 // Step 1: prepare a map for the object. We add 1 inobject property to it. |
| 967 Handle<JSFunction> object_ctor( | 969 Handle<JSFunction> object_ctor( |
| 968 CcTest::i_isolate()->native_context()->object_function()); | 970 CcTest::i_isolate()->native_context()->object_function()); |
| 969 CHECK(object_ctor->has_initial_map()); | 971 CHECK(object_ctor->has_initial_map()); |
| 970 Handle<Map> object_map(object_ctor->initial_map()); | 972 Handle<Map> object_map(object_ctor->initial_map()); |
| 971 // Create a map with single inobject property. | 973 // Create a map with single inobject property. |
| 972 Handle<Map> my_map = factory->CopyMap(object_map, 1); | 974 Handle<Map> my_map = factory->CopyMap(object_map, 1); |
| 973 int n_properties = my_map->inobject_properties(); | 975 int n_properties = my_map->inobject_properties(); |
| 974 CHECK_GT(n_properties, 0); | 976 CHECK_GT(n_properties, 0); |
| 975 | 977 |
| 976 int object_size = my_map->instance_size(); | 978 int object_size = my_map->instance_size(); |
| 977 | 979 |
| 978 // Step 2: allocate a lot of objects so to almost fill new space: we need | 980 // Step 2: allocate a lot of objects so to almost fill new space: we need |
| 979 // just enough room to allocate JSObject and thus fill the newspace. | 981 // just enough room to allocate JSObject and thus fill the newspace. |
| 980 | 982 |
| 981 int allocation_amount = Min(FixedArray::kMaxSize, | 983 int allocation_amount = Min(FixedArray::kMaxSize, |
| 982 Page::kMaxNonCodeHeapObjectSize + kPointerSize); | 984 Page::kMaxNonCodeHeapObjectSize + kPointerSize); |
| 983 int allocation_len = LenFromSize(allocation_amount); | 985 int allocation_len = LenFromSize(allocation_amount); |
| 984 NewSpace* new_space = HEAP->new_space(); | 986 NewSpace* new_space = heap->new_space(); |
| 985 Address* top_addr = new_space->allocation_top_address(); | 987 Address* top_addr = new_space->allocation_top_address(); |
| 986 Address* limit_addr = new_space->allocation_limit_address(); | 988 Address* limit_addr = new_space->allocation_limit_address(); |
| 987 while ((*limit_addr - *top_addr) > allocation_amount) { | 989 while ((*limit_addr - *top_addr) > allocation_amount) { |
| 988 CHECK(!HEAP->always_allocate()); | 990 CHECK(!heap->always_allocate()); |
| 989 Object* array = HEAP->AllocateFixedArray(allocation_len)->ToObjectChecked(); | 991 Object* array = heap->AllocateFixedArray(allocation_len)->ToObjectChecked(); |
| 990 CHECK(!array->IsFailure()); | 992 CHECK(!array->IsFailure()); |
| 991 CHECK(new_space->Contains(array)); | 993 CHECK(new_space->Contains(array)); |
| 992 } | 994 } |
| 993 | 995 |
| 994 // Step 3: now allocate fixed array and JSObject to fill the whole new space. | 996 // Step 3: now allocate fixed array and JSObject to fill the whole new space. |
| 995 int to_fill = static_cast<int>(*limit_addr - *top_addr - object_size); | 997 int to_fill = static_cast<int>(*limit_addr - *top_addr - object_size); |
| 996 int fixed_array_len = LenFromSize(to_fill); | 998 int fixed_array_len = LenFromSize(to_fill); |
| 997 CHECK(fixed_array_len < FixedArray::kMaxLength); | 999 CHECK(fixed_array_len < FixedArray::kMaxLength); |
| 998 | 1000 |
| 999 CHECK(!HEAP->always_allocate()); | 1001 CHECK(!heap->always_allocate()); |
| 1000 Object* array = HEAP->AllocateFixedArray(fixed_array_len)->ToObjectChecked(); | 1002 Object* array = heap->AllocateFixedArray(fixed_array_len)->ToObjectChecked(); |
| 1001 CHECK(!array->IsFailure()); | 1003 CHECK(!array->IsFailure()); |
| 1002 CHECK(new_space->Contains(array)); | 1004 CHECK(new_space->Contains(array)); |
| 1003 | 1005 |
| 1004 Object* object = HEAP->AllocateJSObjectFromMap(*my_map)->ToObjectChecked(); | 1006 Object* object = heap->AllocateJSObjectFromMap(*my_map)->ToObjectChecked(); |
| 1005 CHECK(new_space->Contains(object)); | 1007 CHECK(new_space->Contains(object)); |
| 1006 JSObject* jsobject = JSObject::cast(object); | 1008 JSObject* jsobject = JSObject::cast(object); |
| 1007 CHECK_EQ(0, FixedArray::cast(jsobject->elements())->length()); | 1009 CHECK_EQ(0, FixedArray::cast(jsobject->elements())->length()); |
| 1008 CHECK_EQ(0, jsobject->properties()->length()); | 1010 CHECK_EQ(0, jsobject->properties()->length()); |
| 1009 // Create a reference to object in new space in jsobject. | 1011 // Create a reference to object in new space in jsobject. |
| 1010 jsobject->FastPropertyAtPut(-1, array); | 1012 jsobject->FastPropertyAtPut(-1, array); |
| 1011 | 1013 |
| 1012 CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr)); | 1014 CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr)); |
| 1013 | 1015 |
| 1014 // Step 4: clone jsobject, but force always allocate first to create a clone | 1016 // Step 4: clone jsobject, but force always allocate first to create a clone |
| 1015 // in old pointer space. | 1017 // in old pointer space. |
| 1016 Address old_pointer_space_top = HEAP->old_pointer_space()->top(); | 1018 Address old_pointer_space_top = heap->old_pointer_space()->top(); |
| 1017 AlwaysAllocateScope aa_scope; | 1019 AlwaysAllocateScope aa_scope; |
| 1018 Object* clone_obj = HEAP->CopyJSObject(jsobject)->ToObjectChecked(); | 1020 Object* clone_obj = heap->CopyJSObject(jsobject)->ToObjectChecked(); |
| 1019 JSObject* clone = JSObject::cast(clone_obj); | 1021 JSObject* clone = JSObject::cast(clone_obj); |
| 1020 if (clone->address() != old_pointer_space_top) { | 1022 if (clone->address() != old_pointer_space_top) { |
| 1021 // Alas, got allocated from free list, we cannot do checks. | 1023 // Alas, got allocated from free list, we cannot do checks. |
| 1022 return; | 1024 return; |
| 1023 } | 1025 } |
| 1024 CHECK(HEAP->old_pointer_space()->Contains(clone->address())); | 1026 CHECK(heap->old_pointer_space()->Contains(clone->address())); |
| 1025 } | 1027 } |
| 1026 | 1028 |
| 1027 | 1029 |
| 1028 TEST(TestCodeFlushing) { | 1030 TEST(TestCodeFlushing) { |
| 1029 // If we do not flush code this test is invalid. | 1031 // If we do not flush code this test is invalid. |
| 1030 if (!FLAG_flush_code) return; | 1032 if (!FLAG_flush_code) return; |
| 1031 i::FLAG_allow_natives_syntax = true; | 1033 i::FLAG_allow_natives_syntax = true; |
| 1032 CcTest::InitializeVM(); | 1034 CcTest::InitializeVM(); |
| 1033 Isolate* isolate = CcTest::i_isolate(); | 1035 Isolate* isolate = CcTest::i_isolate(); |
| 1034 Factory* factory = isolate->factory(); | 1036 Factory* factory = isolate->factory(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1047 } | 1049 } |
| 1048 | 1050 |
| 1049 // Check function is compiled. | 1051 // Check function is compiled. |
| 1050 Object* func_value = CcTest::i_isolate()->context()->global_object()-> | 1052 Object* func_value = CcTest::i_isolate()->context()->global_object()-> |
| 1051 GetProperty(*foo_name)->ToObjectChecked(); | 1053 GetProperty(*foo_name)->ToObjectChecked(); |
| 1052 CHECK(func_value->IsJSFunction()); | 1054 CHECK(func_value->IsJSFunction()); |
| 1053 Handle<JSFunction> function(JSFunction::cast(func_value)); | 1055 Handle<JSFunction> function(JSFunction::cast(func_value)); |
| 1054 CHECK(function->shared()->is_compiled()); | 1056 CHECK(function->shared()->is_compiled()); |
| 1055 | 1057 |
| 1056 // The code will survive at least two GCs. | 1058 // The code will survive at least two GCs. |
| 1057 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1059 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1058 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1060 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1059 CHECK(function->shared()->is_compiled()); | 1061 CHECK(function->shared()->is_compiled()); |
| 1060 | 1062 |
| 1061 // Simulate several GCs that use full marking. | 1063 // Simulate several GCs that use full marking. |
| 1062 const int kAgingThreshold = 6; | 1064 const int kAgingThreshold = 6; |
| 1063 for (int i = 0; i < kAgingThreshold; i++) { | 1065 for (int i = 0; i < kAgingThreshold; i++) { |
| 1064 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1066 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1065 } | 1067 } |
| 1066 | 1068 |
| 1067 // foo should no longer be in the compilation cache | 1069 // foo should no longer be in the compilation cache |
| 1068 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); | 1070 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); |
| 1069 CHECK(!function->is_compiled() || function->IsOptimized()); | 1071 CHECK(!function->is_compiled() || function->IsOptimized()); |
| 1070 // Call foo to get it recompiled. | 1072 // Call foo to get it recompiled. |
| 1071 CompileRun("foo()"); | 1073 CompileRun("foo()"); |
| 1072 CHECK(function->shared()->is_compiled()); | 1074 CHECK(function->shared()->is_compiled()); |
| 1073 CHECK(function->is_compiled()); | 1075 CHECK(function->is_compiled()); |
| 1074 } | 1076 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1096 } | 1098 } |
| 1097 | 1099 |
| 1098 // Check function is compiled. | 1100 // Check function is compiled. |
| 1099 Object* func_value = CcTest::i_isolate()->context()->global_object()-> | 1101 Object* func_value = CcTest::i_isolate()->context()->global_object()-> |
| 1100 GetProperty(*foo_name)->ToObjectChecked(); | 1102 GetProperty(*foo_name)->ToObjectChecked(); |
| 1101 CHECK(func_value->IsJSFunction()); | 1103 CHECK(func_value->IsJSFunction()); |
| 1102 Handle<JSFunction> function(JSFunction::cast(func_value)); | 1104 Handle<JSFunction> function(JSFunction::cast(func_value)); |
| 1103 CHECK(function->shared()->is_compiled()); | 1105 CHECK(function->shared()->is_compiled()); |
| 1104 | 1106 |
| 1105 // The code will survive at least two GCs. | 1107 // The code will survive at least two GCs. |
| 1106 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1108 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1107 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1109 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1108 CHECK(function->shared()->is_compiled()); | 1110 CHECK(function->shared()->is_compiled()); |
| 1109 | 1111 |
| 1110 // Simulate several GCs that use incremental marking. | 1112 // Simulate several GCs that use incremental marking. |
| 1111 const int kAgingThreshold = 6; | 1113 const int kAgingThreshold = 6; |
| 1112 for (int i = 0; i < kAgingThreshold; i++) { | 1114 for (int i = 0; i < kAgingThreshold; i++) { |
| 1113 SimulateIncrementalMarking(); | 1115 SimulateIncrementalMarking(); |
| 1114 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1116 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1115 } | 1117 } |
| 1116 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); | 1118 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); |
| 1117 CHECK(!function->is_compiled() || function->IsOptimized()); | 1119 CHECK(!function->is_compiled() || function->IsOptimized()); |
| 1118 | 1120 |
| 1119 // This compile will compile the function again. | 1121 // This compile will compile the function again. |
| 1120 { v8::HandleScope scope(CcTest::isolate()); | 1122 { v8::HandleScope scope(CcTest::isolate()); |
| 1121 CompileRun("foo();"); | 1123 CompileRun("foo();"); |
| 1122 } | 1124 } |
| 1123 | 1125 |
| 1124 // Simulate several GCs that use incremental marking but make sure | 1126 // Simulate several GCs that use incremental marking but make sure |
| 1125 // the loop breaks once the function is enqueued as a candidate. | 1127 // the loop breaks once the function is enqueued as a candidate. |
| 1126 for (int i = 0; i < kAgingThreshold; i++) { | 1128 for (int i = 0; i < kAgingThreshold; i++) { |
| 1127 SimulateIncrementalMarking(); | 1129 SimulateIncrementalMarking(); |
| 1128 if (!function->next_function_link()->IsUndefined()) break; | 1130 if (!function->next_function_link()->IsUndefined()) break; |
| 1129 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1131 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1130 } | 1132 } |
| 1131 | 1133 |
| 1132 // Force optimization while incremental marking is active and while | 1134 // Force optimization while incremental marking is active and while |
| 1133 // the function is enqueued as a candidate. | 1135 // the function is enqueued as a candidate. |
| 1134 { v8::HandleScope scope(CcTest::isolate()); | 1136 { v8::HandleScope scope(CcTest::isolate()); |
| 1135 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();"); | 1137 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();"); |
| 1136 } | 1138 } |
| 1137 | 1139 |
| 1138 // Simulate one final GC to make sure the candidate queue is sane. | 1140 // Simulate one final GC to make sure the candidate queue is sane. |
| 1139 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1141 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1140 CHECK(function->shared()->is_compiled() || !function->IsOptimized()); | 1142 CHECK(function->shared()->is_compiled() || !function->IsOptimized()); |
| 1141 CHECK(function->is_compiled() || !function->IsOptimized()); | 1143 CHECK(function->is_compiled() || !function->IsOptimized()); |
| 1142 } | 1144 } |
| 1143 | 1145 |
| 1144 | 1146 |
| 1145 TEST(TestCodeFlushingIncrementalScavenge) { | 1147 TEST(TestCodeFlushingIncrementalScavenge) { |
| 1146 // If we do not flush code this test is invalid. | 1148 // If we do not flush code this test is invalid. |
| 1147 if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; | 1149 if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; |
| 1148 i::FLAG_allow_natives_syntax = true; | 1150 i::FLAG_allow_natives_syntax = true; |
| 1149 CcTest::InitializeVM(); | 1151 CcTest::InitializeVM(); |
| 1150 Isolate* isolate = CcTest::i_isolate(); | 1152 Isolate* isolate = CcTest::i_isolate(); |
| 1151 Factory* factory = isolate->factory(); | 1153 Factory* factory = isolate->factory(); |
| 1152 v8::HandleScope scope(CcTest::isolate()); | 1154 v8::HandleScope scope(CcTest::isolate()); |
| 1153 const char* source = "var foo = function() {" | 1155 const char* source = "var foo = function() {" |
| 1154 " var x = 42;" | 1156 " var x = 42;" |
| 1155 " var y = 42;" | 1157 " var y = 42;" |
| 1156 " var z = x + y;" | 1158 " var z = x + y;" |
| 1157 "};" | 1159 "};" |
| 1158 "foo();" | 1160 "foo();" |
| 1159 "var bar = function() {" | 1161 "var bar = function() {" |
| 1160 " var x = 23;" | 1162 " var x = 23;" |
| 1161 "};" | 1163 "};" |
| 1162 "bar();"; | 1164 "bar();"; |
| 1163 Handle<String> foo_name = factory->InternalizeUtf8String("foo"); | 1165 Handle<String> foo_name = factory->InternalizeUtf8String("foo"); |
| 1164 Handle<String> bar_name = factory->InternalizeUtf8String("bar"); | 1166 Handle<String> bar_name = factory->InternalizeUtf8String("bar"); |
| 1165 | 1167 |
| 1166 // Perfrom one initial GC to enable code flushing. | 1168 // Perfrom one initial GC to enable code flushing. |
| 1167 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1169 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1168 | 1170 |
| 1169 // This compile will add the code to the compilation cache. | 1171 // This compile will add the code to the compilation cache. |
| 1170 { v8::HandleScope scope(CcTest::isolate()); | 1172 { v8::HandleScope scope(CcTest::isolate()); |
| 1171 CompileRun(source); | 1173 CompileRun(source); |
| 1172 } | 1174 } |
| 1173 | 1175 |
| 1174 // Check functions are compiled. | 1176 // Check functions are compiled. |
| 1175 Object* func_value = CcTest::i_isolate()->context()->global_object()-> | 1177 Object* func_value = CcTest::i_isolate()->context()->global_object()-> |
| 1176 GetProperty(*foo_name)->ToObjectChecked(); | 1178 GetProperty(*foo_name)->ToObjectChecked(); |
| 1177 CHECK(func_value->IsJSFunction()); | 1179 CHECK(func_value->IsJSFunction()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1194 for (int i = 0; i < kAgingThreshold; i++) { | 1196 for (int i = 0; i < kAgingThreshold; i++) { |
| 1195 function->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 1197 function->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); |
| 1196 function2->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 1198 function2->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); |
| 1197 } | 1199 } |
| 1198 | 1200 |
| 1199 // Simulate incremental marking so that the functions are enqueued as | 1201 // Simulate incremental marking so that the functions are enqueued as |
| 1200 // code flushing candidates. Then kill one of the functions. Finally | 1202 // code flushing candidates. Then kill one of the functions. Finally |
| 1201 // perform a scavenge while incremental marking is still running. | 1203 // perform a scavenge while incremental marking is still running. |
| 1202 SimulateIncrementalMarking(); | 1204 SimulateIncrementalMarking(); |
| 1203 *function2.location() = NULL; | 1205 *function2.location() = NULL; |
| 1204 HEAP->CollectGarbage(NEW_SPACE, "test scavenge while marking"); | 1206 CcTest::heap()->CollectGarbage(NEW_SPACE, "test scavenge while marking"); |
| 1205 | 1207 |
| 1206 // Simulate one final GC to make sure the candidate queue is sane. | 1208 // Simulate one final GC to make sure the candidate queue is sane. |
| 1207 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1209 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1208 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); | 1210 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); |
| 1209 CHECK(!function->is_compiled() || function->IsOptimized()); | 1211 CHECK(!function->is_compiled() || function->IsOptimized()); |
| 1210 } | 1212 } |
| 1211 | 1213 |
| 1212 | 1214 |
| 1213 TEST(TestCodeFlushingIncrementalAbort) { | 1215 TEST(TestCodeFlushingIncrementalAbort) { |
| 1214 // If we do not flush code this test is invalid. | 1216 // If we do not flush code this test is invalid. |
| 1215 if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; | 1217 if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; |
| 1216 i::FLAG_allow_natives_syntax = true; | 1218 i::FLAG_allow_natives_syntax = true; |
| 1217 CcTest::InitializeVM(); | 1219 CcTest::InitializeVM(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1272 // Simulate one final GC to make sure the candidate queue is sane. | 1274 // Simulate one final GC to make sure the candidate queue is sane. |
| 1273 heap->CollectAllGarbage(Heap::kNoGCFlags); | 1275 heap->CollectAllGarbage(Heap::kNoGCFlags); |
| 1274 CHECK(function->shared()->is_compiled() || !function->IsOptimized()); | 1276 CHECK(function->shared()->is_compiled() || !function->IsOptimized()); |
| 1275 CHECK(function->is_compiled() || !function->IsOptimized()); | 1277 CHECK(function->is_compiled() || !function->IsOptimized()); |
| 1276 } | 1278 } |
| 1277 | 1279 |
| 1278 | 1280 |
| 1279 // Count the number of native contexts in the weak list of native contexts. | 1281 // Count the number of native contexts in the weak list of native contexts. |
| 1280 int CountNativeContexts() { | 1282 int CountNativeContexts() { |
| 1281 int count = 0; | 1283 int count = 0; |
| 1282 Object* object = HEAP->native_contexts_list(); | 1284 Object* object = CcTest::heap()->native_contexts_list(); |
| 1283 while (!object->IsUndefined()) { | 1285 while (!object->IsUndefined()) { |
| 1284 count++; | 1286 count++; |
| 1285 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); | 1287 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); |
| 1286 } | 1288 } |
| 1287 return count; | 1289 return count; |
| 1288 } | 1290 } |
| 1289 | 1291 |
| 1290 | 1292 |
| 1291 // Count the number of user functions in the weak list of optimized | 1293 // Count the number of user functions in the weak list of optimized |
| 1292 // functions attached to a native context. | 1294 // functions attached to a native context. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1352 CompileRun("f4()"); | 1354 CompileRun("f4()"); |
| 1353 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); | 1355 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1354 CompileRun("f5()"); | 1356 CompileRun("f5()"); |
| 1355 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); | 1357 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1356 | 1358 |
| 1357 // Remove function f1, and | 1359 // Remove function f1, and |
| 1358 CompileRun("f1=null"); | 1360 CompileRun("f1=null"); |
| 1359 | 1361 |
| 1360 // Scavenge treats these references as strong. | 1362 // Scavenge treats these references as strong. |
| 1361 for (int j = 0; j < 10; j++) { | 1363 for (int j = 0; j < 10; j++) { |
| 1362 HEAP->PerformScavenge(); | 1364 CcTest::heap()->PerformScavenge(); |
| 1363 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); | 1365 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1364 } | 1366 } |
| 1365 | 1367 |
| 1366 // Mark compact handles the weak references. | 1368 // Mark compact handles the weak references. |
| 1367 isolate->compilation_cache()->Clear(); | 1369 isolate->compilation_cache()->Clear(); |
| 1368 heap->CollectAllGarbage(Heap::kNoGCFlags); | 1370 heap->CollectAllGarbage(Heap::kNoGCFlags); |
| 1369 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); | 1371 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1370 | 1372 |
| 1371 // Get rid of f3 and f5 in the same way. | 1373 // Get rid of f3 and f5 in the same way. |
| 1372 CompileRun("f3=null"); | 1374 CompileRun("f3=null"); |
| 1373 for (int j = 0; j < 10; j++) { | 1375 for (int j = 0; j < 10; j++) { |
| 1374 HEAP->PerformScavenge(); | 1376 CcTest::heap()->PerformScavenge(); |
| 1375 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); | 1377 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1376 } | 1378 } |
| 1377 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1379 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1378 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); | 1380 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1379 CompileRun("f5=null"); | 1381 CompileRun("f5=null"); |
| 1380 for (int j = 0; j < 10; j++) { | 1382 for (int j = 0; j < 10; j++) { |
| 1381 HEAP->PerformScavenge(); | 1383 CcTest::heap()->PerformScavenge(); |
| 1382 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); | 1384 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1383 } | 1385 } |
| 1384 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1386 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1385 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); | 1387 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1386 | 1388 |
| 1387 ctx[i]->Exit(); | 1389 ctx[i]->Exit(); |
| 1388 } | 1390 } |
| 1389 | 1391 |
| 1390 // Force compilation cache cleanup. | 1392 // Force compilation cache cleanup. |
| 1391 HEAP->NotifyContextDisposed(); | 1393 CcTest::heap()->NotifyContextDisposed(); |
| 1392 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1394 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1393 | 1395 |
| 1394 // Dispose the native contexts one by one. | 1396 // Dispose the native contexts one by one. |
| 1395 for (int i = 0; i < kNumTestContexts; i++) { | 1397 for (int i = 0; i < kNumTestContexts; i++) { |
| 1396 // TODO(dcarney): is there a better way to do this? | 1398 // TODO(dcarney): is there a better way to do this? |
| 1397 i::Object** unsafe = reinterpret_cast<i::Object**>(*ctx[i]); | 1399 i::Object** unsafe = reinterpret_cast<i::Object**>(*ctx[i]); |
| 1398 *unsafe = HEAP->undefined_value(); | 1400 *unsafe = CcTest::heap()->undefined_value(); |
| 1399 ctx[i].Clear(); | 1401 ctx[i].Clear(); |
| 1400 | 1402 |
| 1401 // Scavenge treats these references as strong. | 1403 // Scavenge treats these references as strong. |
| 1402 for (int j = 0; j < 10; j++) { | 1404 for (int j = 0; j < 10; j++) { |
| 1403 HEAP->PerformScavenge(); | 1405 CcTest::heap()->PerformScavenge(); |
| 1404 CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); | 1406 CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); |
| 1405 } | 1407 } |
| 1406 | 1408 |
| 1407 // Mark compact handles the weak references. | 1409 // Mark compact handles the weak references. |
| 1408 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1410 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1409 CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts()); | 1411 CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts()); |
| 1410 } | 1412 } |
| 1411 | 1413 |
| 1412 CHECK_EQ(0, CountNativeContexts()); | 1414 CHECK_EQ(0, CountNativeContexts()); |
| 1413 } | 1415 } |
| 1414 | 1416 |
| 1415 | 1417 |
| 1416 // Count the number of native contexts in the weak list of native contexts | 1418 // Count the number of native contexts in the weak list of native contexts |
| 1417 // causing a GC after the specified number of elements. | 1419 // causing a GC after the specified number of elements. |
| 1418 static int CountNativeContextsWithGC(Isolate* isolate, int n) { | 1420 static int CountNativeContextsWithGC(Isolate* isolate, int n) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1501 | 1503 |
| 1502 ctx[0]->Exit(); | 1504 ctx[0]->Exit(); |
| 1503 } | 1505 } |
| 1504 | 1506 |
| 1505 | 1507 |
| 1506 TEST(TestSizeOfObjects) { | 1508 TEST(TestSizeOfObjects) { |
| 1507 v8::V8::Initialize(); | 1509 v8::V8::Initialize(); |
| 1508 | 1510 |
| 1509 // Get initial heap size after several full GCs, which will stabilize | 1511 // Get initial heap size after several full GCs, which will stabilize |
| 1510 // the heap size and return with sweeping finished completely. | 1512 // the heap size and return with sweeping finished completely. |
| 1511 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1513 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1512 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1514 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1513 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1515 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1514 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1516 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1515 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1517 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1516 CHECK(HEAP->old_pointer_space()->IsLazySweepingComplete()); | 1518 CHECK(CcTest::heap()->old_pointer_space()->IsLazySweepingComplete()); |
| 1517 int initial_size = static_cast<int>(HEAP->SizeOfObjects()); | 1519 int initial_size = static_cast<int>(CcTest::heap()->SizeOfObjects()); |
| 1518 | 1520 |
| 1519 { | 1521 { |
| 1520 // Allocate objects on several different old-space pages so that | 1522 // Allocate objects on several different old-space pages so that |
| 1521 // lazy sweeping kicks in for subsequent GC runs. | 1523 // lazy sweeping kicks in for subsequent GC runs. |
| 1522 AlwaysAllocateScope always_allocate; | 1524 AlwaysAllocateScope always_allocate; |
| 1523 int filler_size = static_cast<int>(FixedArray::SizeFor(8192)); | 1525 int filler_size = static_cast<int>(FixedArray::SizeFor(8192)); |
| 1524 for (int i = 1; i <= 100; i++) { | 1526 for (int i = 1; i <= 100; i++) { |
| 1525 HEAP->AllocateFixedArray(8192, TENURED)->ToObjectChecked(); | 1527 CcTest::heap()->AllocateFixedArray(8192, TENURED)->ToObjectChecked(); |
| 1526 CHECK_EQ(initial_size + i * filler_size, | 1528 CHECK_EQ(initial_size + i * filler_size, |
| 1527 static_cast<int>(HEAP->SizeOfObjects())); | 1529 static_cast<int>(CcTest::heap()->SizeOfObjects())); |
| 1528 } | 1530 } |
| 1529 } | 1531 } |
| 1530 | 1532 |
| 1531 // The heap size should go back to initial size after a full GC, even | 1533 // The heap size should go back to initial size after a full GC, even |
| 1532 // though sweeping didn't finish yet. | 1534 // though sweeping didn't finish yet. |
| 1533 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1535 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1534 | 1536 |
| 1535 // Normally sweeping would not be complete here, but no guarantees. | 1537 // Normally sweeping would not be complete here, but no guarantees. |
| 1536 | 1538 |
| 1537 CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects())); | 1539 CHECK_EQ(initial_size, static_cast<int>(CcTest::heap()->SizeOfObjects())); |
| 1538 | 1540 |
| 1539 // Advancing the sweeper step-wise should not change the heap size. | 1541 // Advancing the sweeper step-wise should not change the heap size. |
| 1540 while (!HEAP->old_pointer_space()->IsLazySweepingComplete()) { | 1542 while (!CcTest::heap()->old_pointer_space()->IsLazySweepingComplete()) { |
| 1541 HEAP->old_pointer_space()->AdvanceSweeper(KB); | 1543 CcTest::heap()->old_pointer_space()->AdvanceSweeper(KB); |
| 1542 CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects())); | 1544 CHECK_EQ(initial_size, static_cast<int>(CcTest::heap()->SizeOfObjects())); |
| 1543 } | 1545 } |
| 1544 } | 1546 } |
| 1545 | 1547 |
| 1546 | 1548 |
| 1547 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) { | 1549 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) { |
| 1548 CcTest::InitializeVM(); | 1550 CcTest::InitializeVM(); |
| 1549 HEAP->EnsureHeapIsIterable(); | 1551 CcTest::heap()->EnsureHeapIsIterable(); |
| 1550 intptr_t size_of_objects_1 = HEAP->SizeOfObjects(); | 1552 intptr_t size_of_objects_1 = CcTest::heap()->SizeOfObjects(); |
| 1551 HeapIterator iterator(HEAP); | 1553 HeapIterator iterator(CcTest::heap()); |
| 1552 intptr_t size_of_objects_2 = 0; | 1554 intptr_t size_of_objects_2 = 0; |
| 1553 for (HeapObject* obj = iterator.next(); | 1555 for (HeapObject* obj = iterator.next(); |
| 1554 obj != NULL; | 1556 obj != NULL; |
| 1555 obj = iterator.next()) { | 1557 obj = iterator.next()) { |
| 1556 if (!obj->IsFreeSpace()) { | 1558 if (!obj->IsFreeSpace()) { |
| 1557 size_of_objects_2 += obj->Size(); | 1559 size_of_objects_2 += obj->Size(); |
| 1558 } | 1560 } |
| 1559 } | 1561 } |
| 1560 // Delta must be within 5% of the larger result. | 1562 // Delta must be within 5% of the larger result. |
| 1561 // TODO(gc): Tighten this up by distinguishing between byte | 1563 // TODO(gc): Tighten this up by distinguishing between byte |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1590 intptr_t available = new_space->EffectiveCapacity() - new_space->Size(); | 1592 intptr_t available = new_space->EffectiveCapacity() - new_space->Size(); |
| 1591 intptr_t number_of_fillers = (available / FixedArray::SizeFor(32)) - 1; | 1593 intptr_t number_of_fillers = (available / FixedArray::SizeFor(32)) - 1; |
| 1592 for (intptr_t i = 0; i < number_of_fillers; i++) { | 1594 for (intptr_t i = 0; i < number_of_fillers; i++) { |
| 1593 CHECK(heap->InNewSpace(*factory->NewFixedArray(32, NOT_TENURED))); | 1595 CHECK(heap->InNewSpace(*factory->NewFixedArray(32, NOT_TENURED))); |
| 1594 } | 1596 } |
| 1595 } | 1597 } |
| 1596 | 1598 |
| 1597 | 1599 |
| 1598 TEST(GrowAndShrinkNewSpace) { | 1600 TEST(GrowAndShrinkNewSpace) { |
| 1599 CcTest::InitializeVM(); | 1601 CcTest::InitializeVM(); |
| 1600 NewSpace* new_space = HEAP->new_space(); | 1602 Heap* heap = CcTest::heap(); |
| 1603 NewSpace* new_space = heap->new_space(); |
| 1601 | 1604 |
| 1602 if (HEAP->ReservedSemiSpaceSize() == HEAP->InitialSemiSpaceSize() || | 1605 if (heap->ReservedSemiSpaceSize() == heap->InitialSemiSpaceSize() || |
| 1603 HEAP->MaxSemiSpaceSize() == HEAP->InitialSemiSpaceSize()) { | 1606 heap->MaxSemiSpaceSize() == heap->InitialSemiSpaceSize()) { |
| 1604 // The max size cannot exceed the reserved size, since semispaces must be | 1607 // The max size cannot exceed the reserved size, since semispaces must be |
| 1605 // always within the reserved space. We can't test new space growing and | 1608 // always within the reserved space. We can't test new space growing and |
| 1606 // shrinking if the reserved size is the same as the minimum (initial) size. | 1609 // shrinking if the reserved size is the same as the minimum (initial) size. |
| 1607 return; | 1610 return; |
| 1608 } | 1611 } |
| 1609 | 1612 |
| 1610 // Explicitly growing should double the space capacity. | 1613 // Explicitly growing should double the space capacity. |
| 1611 intptr_t old_capacity, new_capacity; | 1614 intptr_t old_capacity, new_capacity; |
| 1612 old_capacity = new_space->Capacity(); | 1615 old_capacity = new_space->Capacity(); |
| 1613 new_space->Grow(); | 1616 new_space->Grow(); |
| 1614 new_capacity = new_space->Capacity(); | 1617 new_capacity = new_space->Capacity(); |
| 1615 CHECK(2 * old_capacity == new_capacity); | 1618 CHECK(2 * old_capacity == new_capacity); |
| 1616 | 1619 |
| 1617 old_capacity = new_space->Capacity(); | 1620 old_capacity = new_space->Capacity(); |
| 1618 FillUpNewSpace(new_space); | 1621 FillUpNewSpace(new_space); |
| 1619 new_capacity = new_space->Capacity(); | 1622 new_capacity = new_space->Capacity(); |
| 1620 CHECK(old_capacity == new_capacity); | 1623 CHECK(old_capacity == new_capacity); |
| 1621 | 1624 |
| 1622 // Explicitly shrinking should not affect space capacity. | 1625 // Explicitly shrinking should not affect space capacity. |
| 1623 old_capacity = new_space->Capacity(); | 1626 old_capacity = new_space->Capacity(); |
| 1624 new_space->Shrink(); | 1627 new_space->Shrink(); |
| 1625 new_capacity = new_space->Capacity(); | 1628 new_capacity = new_space->Capacity(); |
| 1626 CHECK(old_capacity == new_capacity); | 1629 CHECK(old_capacity == new_capacity); |
| 1627 | 1630 |
| 1628 // Let the scavenger empty the new space. | 1631 // Let the scavenger empty the new space. |
| 1629 HEAP->CollectGarbage(NEW_SPACE); | 1632 heap->CollectGarbage(NEW_SPACE); |
| 1630 CHECK_LE(new_space->Size(), old_capacity); | 1633 CHECK_LE(new_space->Size(), old_capacity); |
| 1631 | 1634 |
| 1632 // Explicitly shrinking should halve the space capacity. | 1635 // Explicitly shrinking should halve the space capacity. |
| 1633 old_capacity = new_space->Capacity(); | 1636 old_capacity = new_space->Capacity(); |
| 1634 new_space->Shrink(); | 1637 new_space->Shrink(); |
| 1635 new_capacity = new_space->Capacity(); | 1638 new_capacity = new_space->Capacity(); |
| 1636 CHECK(old_capacity == 2 * new_capacity); | 1639 CHECK(old_capacity == 2 * new_capacity); |
| 1637 | 1640 |
| 1638 // Consecutive shrinking should not affect space capacity. | 1641 // Consecutive shrinking should not affect space capacity. |
| 1639 old_capacity = new_space->Capacity(); | 1642 old_capacity = new_space->Capacity(); |
| 1640 new_space->Shrink(); | 1643 new_space->Shrink(); |
| 1641 new_space->Shrink(); | 1644 new_space->Shrink(); |
| 1642 new_space->Shrink(); | 1645 new_space->Shrink(); |
| 1643 new_capacity = new_space->Capacity(); | 1646 new_capacity = new_space->Capacity(); |
| 1644 CHECK(old_capacity == new_capacity); | 1647 CHECK(old_capacity == new_capacity); |
| 1645 } | 1648 } |
| 1646 | 1649 |
| 1647 | 1650 |
| 1648 TEST(CollectingAllAvailableGarbageShrinksNewSpace) { | 1651 TEST(CollectingAllAvailableGarbageShrinksNewSpace) { |
| 1649 CcTest::InitializeVM(); | 1652 CcTest::InitializeVM(); |
| 1650 | 1653 Heap* heap = CcTest::heap(); |
| 1651 if (HEAP->ReservedSemiSpaceSize() == HEAP->InitialSemiSpaceSize() || | 1654 if (heap->ReservedSemiSpaceSize() == heap->InitialSemiSpaceSize() || |
| 1652 HEAP->MaxSemiSpaceSize() == HEAP->InitialSemiSpaceSize()) { | 1655 heap->MaxSemiSpaceSize() == heap->InitialSemiSpaceSize()) { |
| 1653 // The max size cannot exceed the reserved size, since semispaces must be | 1656 // The max size cannot exceed the reserved size, since semispaces must be |
| 1654 // always within the reserved space. We can't test new space growing and | 1657 // always within the reserved space. We can't test new space growing and |
| 1655 // shrinking if the reserved size is the same as the minimum (initial) size. | 1658 // shrinking if the reserved size is the same as the minimum (initial) size. |
| 1656 return; | 1659 return; |
| 1657 } | 1660 } |
| 1658 | 1661 |
| 1659 v8::HandleScope scope(CcTest::isolate()); | 1662 v8::HandleScope scope(CcTest::isolate()); |
| 1660 NewSpace* new_space = HEAP->new_space(); | 1663 NewSpace* new_space = heap->new_space(); |
| 1661 intptr_t old_capacity, new_capacity; | 1664 intptr_t old_capacity, new_capacity; |
| 1662 old_capacity = new_space->Capacity(); | 1665 old_capacity = new_space->Capacity(); |
| 1663 new_space->Grow(); | 1666 new_space->Grow(); |
| 1664 new_capacity = new_space->Capacity(); | 1667 new_capacity = new_space->Capacity(); |
| 1665 CHECK(2 * old_capacity == new_capacity); | 1668 CHECK(2 * old_capacity == new_capacity); |
| 1666 FillUpNewSpace(new_space); | 1669 FillUpNewSpace(new_space); |
| 1667 HEAP->CollectAllAvailableGarbage(); | 1670 heap->CollectAllAvailableGarbage(); |
| 1668 new_capacity = new_space->Capacity(); | 1671 new_capacity = new_space->Capacity(); |
| 1669 CHECK(old_capacity == new_capacity); | 1672 CHECK(old_capacity == new_capacity); |
| 1670 } | 1673 } |
| 1671 | 1674 |
| 1672 | 1675 |
| 1673 static int NumberOfGlobalObjects() { | 1676 static int NumberOfGlobalObjects() { |
| 1674 int count = 0; | 1677 int count = 0; |
| 1675 HeapIterator iterator(HEAP); | 1678 HeapIterator iterator(CcTest::heap()); |
| 1676 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 1679 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 1677 if (obj->IsGlobalObject()) count++; | 1680 if (obj->IsGlobalObject()) count++; |
| 1678 } | 1681 } |
| 1679 return count; | 1682 return count; |
| 1680 } | 1683 } |
| 1681 | 1684 |
| 1682 | 1685 |
| 1683 // Test that we don't embed maps from foreign contexts into | 1686 // Test that we don't embed maps from foreign contexts into |
| 1684 // optimized code. | 1687 // optimized code. |
| 1685 TEST(LeakNativeContextViaMap) { | 1688 TEST(LeakNativeContextViaMap) { |
| 1686 i::FLAG_allow_natives_syntax = true; | 1689 i::FLAG_allow_natives_syntax = true; |
| 1687 v8::Isolate* isolate = CcTest::isolate(); | 1690 v8::Isolate* isolate = CcTest::isolate(); |
| 1688 v8::HandleScope outer_scope(isolate); | 1691 v8::HandleScope outer_scope(isolate); |
| 1689 v8::Persistent<v8::Context> ctx1p; | 1692 v8::Persistent<v8::Context> ctx1p; |
| 1690 v8::Persistent<v8::Context> ctx2p; | 1693 v8::Persistent<v8::Context> ctx2p; |
| 1691 { | 1694 { |
| 1692 v8::HandleScope scope(isolate); | 1695 v8::HandleScope scope(isolate); |
| 1693 ctx1p.Reset(isolate, v8::Context::New(isolate)); | 1696 ctx1p.Reset(isolate, v8::Context::New(isolate)); |
| 1694 ctx2p.Reset(isolate, v8::Context::New(isolate)); | 1697 ctx2p.Reset(isolate, v8::Context::New(isolate)); |
| 1695 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); | 1698 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); |
| 1696 } | 1699 } |
| 1697 | 1700 |
| 1698 HEAP->CollectAllAvailableGarbage(); | 1701 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1699 CHECK_EQ(4, NumberOfGlobalObjects()); | 1702 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 1700 | 1703 |
| 1701 { | 1704 { |
| 1702 v8::HandleScope inner_scope(isolate); | 1705 v8::HandleScope inner_scope(isolate); |
| 1703 CompileRun("var v = {x: 42}"); | 1706 CompileRun("var v = {x: 42}"); |
| 1704 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); | 1707 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); |
| 1705 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); | 1708 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); |
| 1706 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 1709 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 1707 ctx2->Enter(); | 1710 ctx2->Enter(); |
| 1708 ctx2->Global()->Set(v8_str("o"), v); | 1711 ctx2->Global()->Set(v8_str("o"), v); |
| 1709 v8::Local<v8::Value> res = CompileRun( | 1712 v8::Local<v8::Value> res = CompileRun( |
| 1710 "function f() { return o.x; }" | 1713 "function f() { return o.x; }" |
| 1711 "for (var i = 0; i < 10; ++i) f();" | 1714 "for (var i = 0; i < 10; ++i) f();" |
| 1712 "%OptimizeFunctionOnNextCall(f);" | 1715 "%OptimizeFunctionOnNextCall(f);" |
| 1713 "f();"); | 1716 "f();"); |
| 1714 CHECK_EQ(42, res->Int32Value()); | 1717 CHECK_EQ(42, res->Int32Value()); |
| 1715 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); | 1718 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
| 1716 ctx2->Exit(); | 1719 ctx2->Exit(); |
| 1717 v8::Local<v8::Context>::New(isolate, ctx1)->Exit(); | 1720 v8::Local<v8::Context>::New(isolate, ctx1)->Exit(); |
| 1718 ctx1p.Dispose(); | 1721 ctx1p.Dispose(); |
| 1719 v8::V8::ContextDisposedNotification(); | 1722 v8::V8::ContextDisposedNotification(); |
| 1720 } | 1723 } |
| 1721 HEAP->CollectAllAvailableGarbage(); | 1724 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1722 CHECK_EQ(2, NumberOfGlobalObjects()); | 1725 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 1723 ctx2p.Dispose(); | 1726 ctx2p.Dispose(); |
| 1724 HEAP->CollectAllAvailableGarbage(); | 1727 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1725 CHECK_EQ(0, NumberOfGlobalObjects()); | 1728 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 1726 } | 1729 } |
| 1727 | 1730 |
| 1728 | 1731 |
| 1729 // Test that we don't embed functions from foreign contexts into | 1732 // Test that we don't embed functions from foreign contexts into |
| 1730 // optimized code. | 1733 // optimized code. |
| 1731 TEST(LeakNativeContextViaFunction) { | 1734 TEST(LeakNativeContextViaFunction) { |
| 1732 i::FLAG_allow_natives_syntax = true; | 1735 i::FLAG_allow_natives_syntax = true; |
| 1733 v8::Isolate* isolate = CcTest::isolate(); | 1736 v8::Isolate* isolate = CcTest::isolate(); |
| 1734 v8::HandleScope outer_scope(isolate); | 1737 v8::HandleScope outer_scope(isolate); |
| 1735 v8::Persistent<v8::Context> ctx1p; | 1738 v8::Persistent<v8::Context> ctx1p; |
| 1736 v8::Persistent<v8::Context> ctx2p; | 1739 v8::Persistent<v8::Context> ctx2p; |
| 1737 { | 1740 { |
| 1738 v8::HandleScope scope(isolate); | 1741 v8::HandleScope scope(isolate); |
| 1739 ctx1p.Reset(isolate, v8::Context::New(isolate)); | 1742 ctx1p.Reset(isolate, v8::Context::New(isolate)); |
| 1740 ctx2p.Reset(isolate, v8::Context::New(isolate)); | 1743 ctx2p.Reset(isolate, v8::Context::New(isolate)); |
| 1741 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); | 1744 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); |
| 1742 } | 1745 } |
| 1743 | 1746 |
| 1744 HEAP->CollectAllAvailableGarbage(); | 1747 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1745 CHECK_EQ(4, NumberOfGlobalObjects()); | 1748 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 1746 | 1749 |
| 1747 { | 1750 { |
| 1748 v8::HandleScope inner_scope(isolate); | 1751 v8::HandleScope inner_scope(isolate); |
| 1749 CompileRun("var v = function() { return 42; }"); | 1752 CompileRun("var v = function() { return 42; }"); |
| 1750 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); | 1753 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); |
| 1751 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); | 1754 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); |
| 1752 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 1755 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 1753 ctx2->Enter(); | 1756 ctx2->Enter(); |
| 1754 ctx2->Global()->Set(v8_str("o"), v); | 1757 ctx2->Global()->Set(v8_str("o"), v); |
| 1755 v8::Local<v8::Value> res = CompileRun( | 1758 v8::Local<v8::Value> res = CompileRun( |
| 1756 "function f(x) { return x(); }" | 1759 "function f(x) { return x(); }" |
| 1757 "for (var i = 0; i < 10; ++i) f(o);" | 1760 "for (var i = 0; i < 10; ++i) f(o);" |
| 1758 "%OptimizeFunctionOnNextCall(f);" | 1761 "%OptimizeFunctionOnNextCall(f);" |
| 1759 "f(o);"); | 1762 "f(o);"); |
| 1760 CHECK_EQ(42, res->Int32Value()); | 1763 CHECK_EQ(42, res->Int32Value()); |
| 1761 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); | 1764 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
| 1762 ctx2->Exit(); | 1765 ctx2->Exit(); |
| 1763 ctx1->Exit(); | 1766 ctx1->Exit(); |
| 1764 ctx1p.Dispose(); | 1767 ctx1p.Dispose(); |
| 1765 v8::V8::ContextDisposedNotification(); | 1768 v8::V8::ContextDisposedNotification(); |
| 1766 } | 1769 } |
| 1767 HEAP->CollectAllAvailableGarbage(); | 1770 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1768 CHECK_EQ(2, NumberOfGlobalObjects()); | 1771 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 1769 ctx2p.Dispose(); | 1772 ctx2p.Dispose(); |
| 1770 HEAP->CollectAllAvailableGarbage(); | 1773 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1771 CHECK_EQ(0, NumberOfGlobalObjects()); | 1774 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 1772 } | 1775 } |
| 1773 | 1776 |
| 1774 | 1777 |
| 1775 TEST(LeakNativeContextViaMapKeyed) { | 1778 TEST(LeakNativeContextViaMapKeyed) { |
| 1776 i::FLAG_allow_natives_syntax = true; | 1779 i::FLAG_allow_natives_syntax = true; |
| 1777 v8::Isolate* isolate = CcTest::isolate(); | 1780 v8::Isolate* isolate = CcTest::isolate(); |
| 1778 v8::HandleScope outer_scope(isolate); | 1781 v8::HandleScope outer_scope(isolate); |
| 1779 v8::Persistent<v8::Context> ctx1p; | 1782 v8::Persistent<v8::Context> ctx1p; |
| 1780 v8::Persistent<v8::Context> ctx2p; | 1783 v8::Persistent<v8::Context> ctx2p; |
| 1781 { | 1784 { |
| 1782 v8::HandleScope scope(isolate); | 1785 v8::HandleScope scope(isolate); |
| 1783 ctx1p.Reset(isolate, v8::Context::New(isolate)); | 1786 ctx1p.Reset(isolate, v8::Context::New(isolate)); |
| 1784 ctx2p.Reset(isolate, v8::Context::New(isolate)); | 1787 ctx2p.Reset(isolate, v8::Context::New(isolate)); |
| 1785 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); | 1788 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); |
| 1786 } | 1789 } |
| 1787 | 1790 |
| 1788 HEAP->CollectAllAvailableGarbage(); | 1791 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1789 CHECK_EQ(4, NumberOfGlobalObjects()); | 1792 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 1790 | 1793 |
| 1791 { | 1794 { |
| 1792 v8::HandleScope inner_scope(isolate); | 1795 v8::HandleScope inner_scope(isolate); |
| 1793 CompileRun("var v = [42, 43]"); | 1796 CompileRun("var v = [42, 43]"); |
| 1794 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); | 1797 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); |
| 1795 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); | 1798 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); |
| 1796 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 1799 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 1797 ctx2->Enter(); | 1800 ctx2->Enter(); |
| 1798 ctx2->Global()->Set(v8_str("o"), v); | 1801 ctx2->Global()->Set(v8_str("o"), v); |
| 1799 v8::Local<v8::Value> res = CompileRun( | 1802 v8::Local<v8::Value> res = CompileRun( |
| 1800 "function f() { return o[0]; }" | 1803 "function f() { return o[0]; }" |
| 1801 "for (var i = 0; i < 10; ++i) f();" | 1804 "for (var i = 0; i < 10; ++i) f();" |
| 1802 "%OptimizeFunctionOnNextCall(f);" | 1805 "%OptimizeFunctionOnNextCall(f);" |
| 1803 "f();"); | 1806 "f();"); |
| 1804 CHECK_EQ(42, res->Int32Value()); | 1807 CHECK_EQ(42, res->Int32Value()); |
| 1805 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); | 1808 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
| 1806 ctx2->Exit(); | 1809 ctx2->Exit(); |
| 1807 ctx1->Exit(); | 1810 ctx1->Exit(); |
| 1808 ctx1p.Dispose(); | 1811 ctx1p.Dispose(); |
| 1809 v8::V8::ContextDisposedNotification(); | 1812 v8::V8::ContextDisposedNotification(); |
| 1810 } | 1813 } |
| 1811 HEAP->CollectAllAvailableGarbage(); | 1814 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1812 CHECK_EQ(2, NumberOfGlobalObjects()); | 1815 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 1813 ctx2p.Dispose(); | 1816 ctx2p.Dispose(); |
| 1814 HEAP->CollectAllAvailableGarbage(); | 1817 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1815 CHECK_EQ(0, NumberOfGlobalObjects()); | 1818 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 1816 } | 1819 } |
| 1817 | 1820 |
| 1818 | 1821 |
| 1819 TEST(LeakNativeContextViaMapProto) { | 1822 TEST(LeakNativeContextViaMapProto) { |
| 1820 i::FLAG_allow_natives_syntax = true; | 1823 i::FLAG_allow_natives_syntax = true; |
| 1821 v8::Isolate* isolate = CcTest::isolate(); | 1824 v8::Isolate* isolate = CcTest::isolate(); |
| 1822 v8::HandleScope outer_scope(isolate); | 1825 v8::HandleScope outer_scope(isolate); |
| 1823 v8::Persistent<v8::Context> ctx1p; | 1826 v8::Persistent<v8::Context> ctx1p; |
| 1824 v8::Persistent<v8::Context> ctx2p; | 1827 v8::Persistent<v8::Context> ctx2p; |
| 1825 { | 1828 { |
| 1826 v8::HandleScope scope(isolate); | 1829 v8::HandleScope scope(isolate); |
| 1827 ctx1p.Reset(isolate, v8::Context::New(isolate)); | 1830 ctx1p.Reset(isolate, v8::Context::New(isolate)); |
| 1828 ctx2p.Reset(isolate, v8::Context::New(isolate)); | 1831 ctx2p.Reset(isolate, v8::Context::New(isolate)); |
| 1829 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); | 1832 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); |
| 1830 } | 1833 } |
| 1831 | 1834 |
| 1832 HEAP->CollectAllAvailableGarbage(); | 1835 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1833 CHECK_EQ(4, NumberOfGlobalObjects()); | 1836 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 1834 | 1837 |
| 1835 { | 1838 { |
| 1836 v8::HandleScope inner_scope(isolate); | 1839 v8::HandleScope inner_scope(isolate); |
| 1837 CompileRun("var v = { y: 42}"); | 1840 CompileRun("var v = { y: 42}"); |
| 1838 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); | 1841 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); |
| 1839 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); | 1842 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); |
| 1840 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 1843 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 1841 ctx2->Enter(); | 1844 ctx2->Enter(); |
| 1842 ctx2->Global()->Set(v8_str("o"), v); | 1845 ctx2->Global()->Set(v8_str("o"), v); |
| 1843 v8::Local<v8::Value> res = CompileRun( | 1846 v8::Local<v8::Value> res = CompileRun( |
| 1844 "function f() {" | 1847 "function f() {" |
| 1845 " var p = {x: 42};" | 1848 " var p = {x: 42};" |
| 1846 " p.__proto__ = o;" | 1849 " p.__proto__ = o;" |
| 1847 " return p.x;" | 1850 " return p.x;" |
| 1848 "}" | 1851 "}" |
| 1849 "for (var i = 0; i < 10; ++i) f();" | 1852 "for (var i = 0; i < 10; ++i) f();" |
| 1850 "%OptimizeFunctionOnNextCall(f);" | 1853 "%OptimizeFunctionOnNextCall(f);" |
| 1851 "f();"); | 1854 "f();"); |
| 1852 CHECK_EQ(42, res->Int32Value()); | 1855 CHECK_EQ(42, res->Int32Value()); |
| 1853 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); | 1856 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
| 1854 ctx2->Exit(); | 1857 ctx2->Exit(); |
| 1855 ctx1->Exit(); | 1858 ctx1->Exit(); |
| 1856 ctx1p.Dispose(); | 1859 ctx1p.Dispose(); |
| 1857 v8::V8::ContextDisposedNotification(); | 1860 v8::V8::ContextDisposedNotification(); |
| 1858 } | 1861 } |
| 1859 HEAP->CollectAllAvailableGarbage(); | 1862 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1860 CHECK_EQ(2, NumberOfGlobalObjects()); | 1863 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 1861 ctx2p.Dispose(); | 1864 ctx2p.Dispose(); |
| 1862 HEAP->CollectAllAvailableGarbage(); | 1865 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1863 CHECK_EQ(0, NumberOfGlobalObjects()); | 1866 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 1864 } | 1867 } |
| 1865 | 1868 |
| 1866 | 1869 |
| 1867 TEST(InstanceOfStubWriteBarrier) { | 1870 TEST(InstanceOfStubWriteBarrier) { |
| 1868 i::FLAG_allow_natives_syntax = true; | 1871 i::FLAG_allow_natives_syntax = true; |
| 1869 #ifdef VERIFY_HEAP | 1872 #ifdef VERIFY_HEAP |
| 1870 i::FLAG_verify_heap = true; | 1873 i::FLAG_verify_heap = true; |
| 1871 #endif | 1874 #endif |
| 1872 | 1875 |
| 1873 CcTest::InitializeVM(); | 1876 CcTest::InitializeVM(); |
| 1874 if (!CcTest::i_isolate()->use_crankshaft()) return; | 1877 if (!CcTest::i_isolate()->use_crankshaft()) return; |
| 1875 if (i::FLAG_force_marking_deque_overflows) return; | 1878 if (i::FLAG_force_marking_deque_overflows) return; |
| 1876 v8::HandleScope outer_scope(CcTest::isolate()); | 1879 v8::HandleScope outer_scope(CcTest::isolate()); |
| 1877 | 1880 |
| 1878 { | 1881 { |
| 1879 v8::HandleScope scope(CcTest::isolate()); | 1882 v8::HandleScope scope(CcTest::isolate()); |
| 1880 CompileRun( | 1883 CompileRun( |
| 1881 "function foo () { }" | 1884 "function foo () { }" |
| 1882 "function mkbar () { return new (new Function(\"\")) (); }" | 1885 "function mkbar () { return new (new Function(\"\")) (); }" |
| 1883 "function f (x) { return (x instanceof foo); }" | 1886 "function f (x) { return (x instanceof foo); }" |
| 1884 "function g () { f(mkbar()); }" | 1887 "function g () { f(mkbar()); }" |
| 1885 "f(new foo()); f(new foo());" | 1888 "f(new foo()); f(new foo());" |
| 1886 "%OptimizeFunctionOnNextCall(f);" | 1889 "%OptimizeFunctionOnNextCall(f);" |
| 1887 "f(new foo()); g();"); | 1890 "f(new foo()); g();"); |
| 1888 } | 1891 } |
| 1889 | 1892 |
| 1890 IncrementalMarking* marking = HEAP->incremental_marking(); | 1893 IncrementalMarking* marking = CcTest::heap()->incremental_marking(); |
| 1891 marking->Abort(); | 1894 marking->Abort(); |
| 1892 marking->Start(); | 1895 marking->Start(); |
| 1893 | 1896 |
| 1894 Handle<JSFunction> f = | 1897 Handle<JSFunction> f = |
| 1895 v8::Utils::OpenHandle( | 1898 v8::Utils::OpenHandle( |
| 1896 *v8::Handle<v8::Function>::Cast( | 1899 *v8::Handle<v8::Function>::Cast( |
| 1897 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 1900 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 1898 | 1901 |
| 1899 CHECK(f->IsOptimized()); | 1902 CHECK(f->IsOptimized()); |
| 1900 | 1903 |
| 1901 while (!Marking::IsBlack(Marking::MarkBitFrom(f->code())) && | 1904 while (!Marking::IsBlack(Marking::MarkBitFrom(f->code())) && |
| 1902 !marking->IsStopped()) { | 1905 !marking->IsStopped()) { |
| 1903 // Discard any pending GC requests otherwise we will get GC when we enter | 1906 // Discard any pending GC requests otherwise we will get GC when we enter |
| 1904 // code below. | 1907 // code below. |
| 1905 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | 1908 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 1906 } | 1909 } |
| 1907 | 1910 |
| 1908 CHECK(marking->IsMarking()); | 1911 CHECK(marking->IsMarking()); |
| 1909 | 1912 |
| 1910 { | 1913 { |
| 1911 v8::HandleScope scope(CcTest::isolate()); | 1914 v8::HandleScope scope(CcTest::isolate()); |
| 1912 v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global(); | 1915 v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global(); |
| 1913 v8::Handle<v8::Function> g = | 1916 v8::Handle<v8::Function> g = |
| 1914 v8::Handle<v8::Function>::Cast(global->Get(v8_str("g"))); | 1917 v8::Handle<v8::Function>::Cast(global->Get(v8_str("g"))); |
| 1915 g->Call(global, 0, NULL); | 1918 g->Call(global, 0, NULL); |
| 1916 } | 1919 } |
| 1917 | 1920 |
| 1918 HEAP->incremental_marking()->set_should_hurry(true); | 1921 CcTest::heap()->incremental_marking()->set_should_hurry(true); |
| 1919 HEAP->CollectGarbage(OLD_POINTER_SPACE); | 1922 CcTest::heap()->CollectGarbage(OLD_POINTER_SPACE); |
| 1920 } | 1923 } |
| 1921 | 1924 |
| 1922 | 1925 |
| 1923 TEST(PrototypeTransitionClearing) { | 1926 TEST(PrototypeTransitionClearing) { |
| 1924 CcTest::InitializeVM(); | 1927 CcTest::InitializeVM(); |
| 1925 Isolate* isolate = CcTest::i_isolate(); | 1928 Isolate* isolate = CcTest::i_isolate(); |
| 1926 Factory* factory = isolate->factory(); | 1929 Factory* factory = isolate->factory(); |
| 1927 v8::HandleScope scope(CcTest::isolate()); | 1930 v8::HandleScope scope(CcTest::isolate()); |
| 1928 | 1931 |
| 1929 CompileRun( | 1932 CompileRun( |
| 1930 "var base = {};" | 1933 "var base = {};" |
| 1931 "var live = [];" | 1934 "var live = [];" |
| 1932 "for (var i = 0; i < 10; i++) {" | 1935 "for (var i = 0; i < 10; i++) {" |
| 1933 " var object = {};" | 1936 " var object = {};" |
| 1934 " var prototype = {};" | 1937 " var prototype = {};" |
| 1935 " object.__proto__ = prototype;" | 1938 " object.__proto__ = prototype;" |
| 1936 " if (i >= 3) live.push(object, prototype);" | 1939 " if (i >= 3) live.push(object, prototype);" |
| 1937 "}"); | 1940 "}"); |
| 1938 | 1941 |
| 1939 Handle<JSObject> baseObject = | 1942 Handle<JSObject> baseObject = |
| 1940 v8::Utils::OpenHandle( | 1943 v8::Utils::OpenHandle( |
| 1941 *v8::Handle<v8::Object>::Cast( | 1944 *v8::Handle<v8::Object>::Cast( |
| 1942 v8::Context::GetCurrent()->Global()->Get(v8_str("base")))); | 1945 v8::Context::GetCurrent()->Global()->Get(v8_str("base")))); |
| 1943 | 1946 |
| 1944 // Verify that only dead prototype transitions are cleared. | 1947 // Verify that only dead prototype transitions are cleared. |
| 1945 CHECK_EQ(10, baseObject->map()->NumberOfProtoTransitions()); | 1948 CHECK_EQ(10, baseObject->map()->NumberOfProtoTransitions()); |
| 1946 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1949 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1947 const int transitions = 10 - 3; | 1950 const int transitions = 10 - 3; |
| 1948 CHECK_EQ(transitions, baseObject->map()->NumberOfProtoTransitions()); | 1951 CHECK_EQ(transitions, baseObject->map()->NumberOfProtoTransitions()); |
| 1949 | 1952 |
| 1950 // Verify that prototype transitions array was compacted. | 1953 // Verify that prototype transitions array was compacted. |
| 1951 FixedArray* trans = baseObject->map()->GetPrototypeTransitions(); | 1954 FixedArray* trans = baseObject->map()->GetPrototypeTransitions(); |
| 1952 for (int i = 0; i < transitions; i++) { | 1955 for (int i = 0; i < transitions; i++) { |
| 1953 int j = Map::kProtoTransitionHeaderSize + | 1956 int j = Map::kProtoTransitionHeaderSize + |
| 1954 i * Map::kProtoTransitionElementsPerEntry; | 1957 i * Map::kProtoTransitionElementsPerEntry; |
| 1955 CHECK(trans->get(j + Map::kProtoTransitionMapOffset)->IsMap()); | 1958 CHECK(trans->get(j + Map::kProtoTransitionMapOffset)->IsMap()); |
| 1956 Object* proto = trans->get(j + Map::kProtoTransitionPrototypeOffset); | 1959 Object* proto = trans->get(j + Map::kProtoTransitionPrototypeOffset); |
| 1957 CHECK(proto->IsTheHole() || proto->IsJSObject()); | 1960 CHECK(proto->IsTheHole() || proto->IsJSObject()); |
| 1958 } | 1961 } |
| 1959 | 1962 |
| 1960 // Make sure next prototype is placed on an old-space evacuation candidate. | 1963 // Make sure next prototype is placed on an old-space evacuation candidate. |
| 1961 Handle<JSObject> prototype; | 1964 Handle<JSObject> prototype; |
| 1962 PagedSpace* space = HEAP->old_pointer_space(); | 1965 PagedSpace* space = CcTest::heap()->old_pointer_space(); |
| 1963 { | 1966 { |
| 1964 AlwaysAllocateScope always_allocate; | 1967 AlwaysAllocateScope always_allocate; |
| 1965 SimulateFullSpace(space); | 1968 SimulateFullSpace(space); |
| 1966 prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED); | 1969 prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED); |
| 1967 } | 1970 } |
| 1968 | 1971 |
| 1969 // Add a prototype on an evacuation candidate and verify that transition | 1972 // Add a prototype on an evacuation candidate and verify that transition |
| 1970 // clearing correctly records slots in prototype transition array. | 1973 // clearing correctly records slots in prototype transition array. |
| 1971 i::FLAG_always_compact = true; | 1974 i::FLAG_always_compact = true; |
| 1972 Handle<Map> map(baseObject->map()); | 1975 Handle<Map> map(baseObject->map()); |
| 1973 CHECK(!space->LastPage()->Contains( | 1976 CHECK(!space->LastPage()->Contains( |
| 1974 map->GetPrototypeTransitions()->address())); | 1977 map->GetPrototypeTransitions()->address())); |
| 1975 CHECK(space->LastPage()->Contains(prototype->address())); | 1978 CHECK(space->LastPage()->Contains(prototype->address())); |
| 1976 JSObject::SetPrototype(baseObject, prototype, false); | 1979 JSObject::SetPrototype(baseObject, prototype, false); |
| 1977 CHECK(Map::GetPrototypeTransition(map, prototype)->IsMap()); | 1980 CHECK(Map::GetPrototypeTransition(map, prototype)->IsMap()); |
| 1978 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1981 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1979 CHECK(Map::GetPrototypeTransition(map, prototype)->IsMap()); | 1982 CHECK(Map::GetPrototypeTransition(map, prototype)->IsMap()); |
| 1980 } | 1983 } |
| 1981 | 1984 |
| 1982 | 1985 |
| 1983 TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { | 1986 TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { |
| 1984 i::FLAG_stress_compaction = false; | 1987 i::FLAG_stress_compaction = false; |
| 1985 i::FLAG_allow_natives_syntax = true; | 1988 i::FLAG_allow_natives_syntax = true; |
| 1986 #ifdef VERIFY_HEAP | 1989 #ifdef VERIFY_HEAP |
| 1987 i::FLAG_verify_heap = true; | 1990 i::FLAG_verify_heap = true; |
| 1988 #endif | 1991 #endif |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2002 "f(); f();" | 2005 "f(); f();" |
| 2003 "%OptimizeFunctionOnNextCall(f);" | 2006 "%OptimizeFunctionOnNextCall(f);" |
| 2004 "f();"); | 2007 "f();"); |
| 2005 } | 2008 } |
| 2006 Handle<JSFunction> f = | 2009 Handle<JSFunction> f = |
| 2007 v8::Utils::OpenHandle( | 2010 v8::Utils::OpenHandle( |
| 2008 *v8::Handle<v8::Function>::Cast( | 2011 *v8::Handle<v8::Function>::Cast( |
| 2009 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2012 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2010 CHECK(f->IsOptimized()); | 2013 CHECK(f->IsOptimized()); |
| 2011 | 2014 |
| 2012 IncrementalMarking* marking = HEAP->incremental_marking(); | 2015 IncrementalMarking* marking = CcTest::heap()->incremental_marking(); |
| 2013 marking->Abort(); | 2016 marking->Abort(); |
| 2014 marking->Start(); | 2017 marking->Start(); |
| 2015 | 2018 |
| 2016 // The following two calls will increment HEAP->global_ic_age(). | 2019 // The following two calls will increment CcTest::heap()->global_ic_age(). |
| 2017 const int kLongIdlePauseInMs = 1000; | 2020 const int kLongIdlePauseInMs = 1000; |
| 2018 v8::V8::ContextDisposedNotification(); | 2021 v8::V8::ContextDisposedNotification(); |
| 2019 v8::V8::IdleNotification(kLongIdlePauseInMs); | 2022 v8::V8::IdleNotification(kLongIdlePauseInMs); |
| 2020 | 2023 |
| 2021 while (!marking->IsStopped() && !marking->IsComplete()) { | 2024 while (!marking->IsStopped() && !marking->IsComplete()) { |
| 2022 marking->Step(1 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | 2025 marking->Step(1 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 2023 } | 2026 } |
| 2024 if (!marking->IsStopped() || marking->should_hurry()) { | 2027 if (!marking->IsStopped() || marking->should_hurry()) { |
| 2025 // We don't normally finish a GC via Step(), we normally finish by | 2028 // We don't normally finish a GC via Step(), we normally finish by |
| 2026 // setting the stack guard and then do the final steps in the stack | 2029 // setting the stack guard and then do the final steps in the stack |
| 2027 // guard interrupt. But here we didn't ask for that, and there is no | 2030 // guard interrupt. But here we didn't ask for that, and there is no |
| 2028 // JS code running to trigger the interrupt, so we explicitly finalize | 2031 // JS code running to trigger the interrupt, so we explicitly finalize |
| 2029 // here. | 2032 // here. |
| 2030 HEAP->CollectAllGarbage(Heap::kNoGCFlags, | 2033 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 2031 "Test finalizing incremental mark-sweep"); | 2034 "Test finalizing incremental mark-sweep"); |
| 2032 } | 2035 } |
| 2033 | 2036 |
| 2034 CHECK_EQ(HEAP->global_ic_age(), f->shared()->ic_age()); | 2037 CHECK_EQ(CcTest::heap()->global_ic_age(), f->shared()->ic_age()); |
| 2035 CHECK_EQ(0, f->shared()->opt_count()); | 2038 CHECK_EQ(0, f->shared()->opt_count()); |
| 2036 CHECK_EQ(0, f->shared()->code()->profiler_ticks()); | 2039 CHECK_EQ(0, f->shared()->code()->profiler_ticks()); |
| 2037 } | 2040 } |
| 2038 | 2041 |
| 2039 | 2042 |
| 2040 TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) { | 2043 TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) { |
| 2041 i::FLAG_stress_compaction = false; | 2044 i::FLAG_stress_compaction = false; |
| 2042 i::FLAG_allow_natives_syntax = true; | 2045 i::FLAG_allow_natives_syntax = true; |
| 2043 #ifdef VERIFY_HEAP | 2046 #ifdef VERIFY_HEAP |
| 2044 i::FLAG_verify_heap = true; | 2047 i::FLAG_verify_heap = true; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2059 "f(); f();" | 2062 "f(); f();" |
| 2060 "%OptimizeFunctionOnNextCall(f);" | 2063 "%OptimizeFunctionOnNextCall(f);" |
| 2061 "f();"); | 2064 "f();"); |
| 2062 } | 2065 } |
| 2063 Handle<JSFunction> f = | 2066 Handle<JSFunction> f = |
| 2064 v8::Utils::OpenHandle( | 2067 v8::Utils::OpenHandle( |
| 2065 *v8::Handle<v8::Function>::Cast( | 2068 *v8::Handle<v8::Function>::Cast( |
| 2066 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2069 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2067 CHECK(f->IsOptimized()); | 2070 CHECK(f->IsOptimized()); |
| 2068 | 2071 |
| 2069 HEAP->incremental_marking()->Abort(); | 2072 CcTest::heap()->incremental_marking()->Abort(); |
| 2070 | 2073 |
| 2071 // The following two calls will increment HEAP->global_ic_age(). | 2074 // The following two calls will increment CcTest::heap()->global_ic_age(). |
| 2072 // Since incremental marking is off, IdleNotification will do full GC. | 2075 // Since incremental marking is off, IdleNotification will do full GC. |
| 2073 const int kLongIdlePauseInMs = 1000; | 2076 const int kLongIdlePauseInMs = 1000; |
| 2074 v8::V8::ContextDisposedNotification(); | 2077 v8::V8::ContextDisposedNotification(); |
| 2075 v8::V8::IdleNotification(kLongIdlePauseInMs); | 2078 v8::V8::IdleNotification(kLongIdlePauseInMs); |
| 2076 | 2079 |
| 2077 CHECK_EQ(HEAP->global_ic_age(), f->shared()->ic_age()); | 2080 CHECK_EQ(CcTest::heap()->global_ic_age(), f->shared()->ic_age()); |
| 2078 CHECK_EQ(0, f->shared()->opt_count()); | 2081 CHECK_EQ(0, f->shared()->opt_count()); |
| 2079 CHECK_EQ(0, f->shared()->code()->profiler_ticks()); | 2082 CHECK_EQ(0, f->shared()->code()->profiler_ticks()); |
| 2080 } | 2083 } |
| 2081 | 2084 |
| 2082 | 2085 |
| 2083 // Test that HAllocateObject will always return an object in new-space. | 2086 // Test that HAllocateObject will always return an object in new-space. |
| 2084 TEST(OptimizedAllocationAlwaysInNewSpace) { | 2087 TEST(OptimizedAllocationAlwaysInNewSpace) { |
| 2085 i::FLAG_allow_natives_syntax = true; | 2088 i::FLAG_allow_natives_syntax = true; |
| 2086 CcTest::InitializeVM(); | 2089 CcTest::InitializeVM(); |
| 2087 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2090 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2088 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2091 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2089 v8::HandleScope scope(CcTest::isolate()); | 2092 v8::HandleScope scope(CcTest::isolate()); |
| 2090 | 2093 |
| 2091 SimulateFullSpace(HEAP->new_space()); | 2094 SimulateFullSpace(CcTest::heap()->new_space()); |
| 2092 AlwaysAllocateScope always_allocate; | 2095 AlwaysAllocateScope always_allocate; |
| 2093 v8::Local<v8::Value> res = CompileRun( | 2096 v8::Local<v8::Value> res = CompileRun( |
| 2094 "function c(x) {" | 2097 "function c(x) {" |
| 2095 " this.x = x;" | 2098 " this.x = x;" |
| 2096 " for (var i = 0; i < 32; i++) {" | 2099 " for (var i = 0; i < 32; i++) {" |
| 2097 " this['x' + i] = x;" | 2100 " this['x' + i] = x;" |
| 2098 " }" | 2101 " }" |
| 2099 "}" | 2102 "}" |
| 2100 "function f(x) { return new c(x); };" | 2103 "function f(x) { return new c(x); };" |
| 2101 "f(1); f(2); f(3);" | 2104 "f(1); f(2); f(3);" |
| 2102 "%OptimizeFunctionOnNextCall(f);" | 2105 "%OptimizeFunctionOnNextCall(f);" |
| 2103 "f(4);"); | 2106 "f(4);"); |
| 2104 CHECK_EQ(4, res->ToObject()->GetRealNamedProperty(v8_str("x"))->Int32Value()); | 2107 CHECK_EQ(4, res->ToObject()->GetRealNamedProperty(v8_str("x"))->Int32Value()); |
| 2105 | 2108 |
| 2106 Handle<JSObject> o = | 2109 Handle<JSObject> o = |
| 2107 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2110 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2108 | 2111 |
| 2109 CHECK(HEAP->InNewSpace(*o)); | 2112 CHECK(CcTest::heap()->InNewSpace(*o)); |
| 2110 } | 2113 } |
| 2111 | 2114 |
| 2112 | 2115 |
| 2113 TEST(OptimizedPretenuringAllocationFolding) { | 2116 TEST(OptimizedPretenuringAllocationFolding) { |
| 2114 i::FLAG_allow_natives_syntax = true; | 2117 i::FLAG_allow_natives_syntax = true; |
| 2115 CcTest::InitializeVM(); | 2118 CcTest::InitializeVM(); |
| 2116 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2119 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2117 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2120 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2118 v8::HandleScope scope(CcTest::isolate()); | 2121 v8::HandleScope scope(CcTest::isolate()); |
| 2119 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2122 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2120 | 2123 |
| 2121 v8::Local<v8::Value> res = CompileRun( | 2124 v8::Local<v8::Value> res = CompileRun( |
| 2122 "function DataObject() {" | 2125 "function DataObject() {" |
| 2123 " this.a = 1.1;" | 2126 " this.a = 1.1;" |
| 2124 " this.b = [{}];" | 2127 " this.b = [{}];" |
| 2125 " this.c = 1.2;" | 2128 " this.c = 1.2;" |
| 2126 " this.d = [{}];" | 2129 " this.d = [{}];" |
| 2127 " this.e = 1.3;" | 2130 " this.e = 1.3;" |
| 2128 " this.f = [{}];" | 2131 " this.f = [{}];" |
| 2129 "}" | 2132 "}" |
| 2130 "function f() {" | 2133 "function f() {" |
| 2131 " return new DataObject();" | 2134 " return new DataObject();" |
| 2132 "};" | 2135 "};" |
| 2133 "f(); f(); f();" | 2136 "f(); f(); f();" |
| 2134 "%OptimizeFunctionOnNextCall(f);" | 2137 "%OptimizeFunctionOnNextCall(f);" |
| 2135 "f();"); | 2138 "f();"); |
| 2136 | 2139 |
| 2137 Handle<JSObject> o = | 2140 Handle<JSObject> o = |
| 2138 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2141 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2139 | 2142 |
| 2140 CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(0))); | 2143 CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(0))); |
| 2141 CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(1))); | 2144 CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(1))); |
| 2142 CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(2))); | 2145 CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(2))); |
| 2143 CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(3))); | 2146 CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(3))); |
| 2144 CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(4))); | 2147 CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(4))); |
| 2145 CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(5))); | 2148 CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(5))); |
| 2146 } | 2149 } |
| 2147 | 2150 |
| 2148 | 2151 |
| 2149 TEST(OptimizedPretenuringAllocationFoldingBlocks) { | 2152 TEST(OptimizedPretenuringAllocationFoldingBlocks) { |
| 2150 i::FLAG_allow_natives_syntax = true; | 2153 i::FLAG_allow_natives_syntax = true; |
| 2151 CcTest::InitializeVM(); | 2154 CcTest::InitializeVM(); |
| 2152 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2155 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2153 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2156 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2154 v8::HandleScope scope(CcTest::isolate()); | 2157 v8::HandleScope scope(CcTest::isolate()); |
| 2155 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2158 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2156 | 2159 |
| 2157 v8::Local<v8::Value> res = CompileRun( | 2160 v8::Local<v8::Value> res = CompileRun( |
| 2158 "function DataObject() {" | 2161 "function DataObject() {" |
| 2159 " this.a = [{}];" | 2162 " this.a = [{}];" |
| 2160 " this.b = [{}];" | 2163 " this.b = [{}];" |
| 2161 " this.c = 1.1;" | 2164 " this.c = 1.1;" |
| 2162 " this.d = 1.2;" | 2165 " this.d = 1.2;" |
| 2163 " this.e = [{}];" | 2166 " this.e = [{}];" |
| 2164 " this.f = 1.3;" | 2167 " this.f = 1.3;" |
| 2165 "}" | 2168 "}" |
| 2166 "function f() {" | 2169 "function f() {" |
| 2167 " return new DataObject();" | 2170 " return new DataObject();" |
| 2168 "};" | 2171 "};" |
| 2169 "f(); f(); f();" | 2172 "f(); f(); f();" |
| 2170 "%OptimizeFunctionOnNextCall(f);" | 2173 "%OptimizeFunctionOnNextCall(f);" |
| 2171 "f();"); | 2174 "f();"); |
| 2172 | 2175 |
| 2173 Handle<JSObject> o = | 2176 Handle<JSObject> o = |
| 2174 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2177 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2175 | 2178 |
| 2176 CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(0))); | 2179 CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(0))); |
| 2177 CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(1))); | 2180 CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(1))); |
| 2178 CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(2))); | 2181 CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(2))); |
| 2179 CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(3))); | 2182 CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(3))); |
| 2180 CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(4))); | 2183 CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(4))); |
| 2181 CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(5))); | 2184 CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(5))); |
| 2182 } | 2185 } |
| 2183 | 2186 |
| 2184 | 2187 |
| 2185 TEST(OptimizedPretenuringObjectArrayLiterals) { | 2188 TEST(OptimizedPretenuringObjectArrayLiterals) { |
| 2186 i::FLAG_allow_natives_syntax = true; | 2189 i::FLAG_allow_natives_syntax = true; |
| 2187 CcTest::InitializeVM(); | 2190 CcTest::InitializeVM(); |
| 2188 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2191 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2189 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2192 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2190 v8::HandleScope scope(CcTest::isolate()); | 2193 v8::HandleScope scope(CcTest::isolate()); |
| 2191 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2194 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2192 | 2195 |
| 2193 v8::Local<v8::Value> res = CompileRun( | 2196 v8::Local<v8::Value> res = CompileRun( |
| 2194 "function f() {" | 2197 "function f() {" |
| 2195 " var numbers = [{}, {}, {}];" | 2198 " var numbers = [{}, {}, {}];" |
| 2196 " return numbers;" | 2199 " return numbers;" |
| 2197 "};" | 2200 "};" |
| 2198 "f(); f(); f();" | 2201 "f(); f(); f();" |
| 2199 "%OptimizeFunctionOnNextCall(f);" | 2202 "%OptimizeFunctionOnNextCall(f);" |
| 2200 "f();"); | 2203 "f();"); |
| 2201 | 2204 |
| 2202 Handle<JSObject> o = | 2205 Handle<JSObject> o = |
| 2203 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2206 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2204 | 2207 |
| 2205 CHECK(HEAP->InOldPointerSpace(o->elements())); | 2208 CHECK(CcTest::heap()->InOldPointerSpace(o->elements())); |
| 2206 CHECK(HEAP->InOldPointerSpace(*o)); | 2209 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2207 } | 2210 } |
| 2208 | 2211 |
| 2209 | 2212 |
| 2210 TEST(OptimizedPretenuringMixedInObjectProperties) { | 2213 TEST(OptimizedPretenuringMixedInObjectProperties) { |
| 2211 i::FLAG_allow_natives_syntax = true; | 2214 i::FLAG_allow_natives_syntax = true; |
| 2212 CcTest::InitializeVM(); | 2215 CcTest::InitializeVM(); |
| 2213 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2216 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2214 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2217 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2215 v8::HandleScope scope(CcTest::isolate()); | 2218 v8::HandleScope scope(CcTest::isolate()); |
| 2216 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2219 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2217 | 2220 |
| 2218 v8::Local<v8::Value> res = CompileRun( | 2221 v8::Local<v8::Value> res = CompileRun( |
| 2219 "function f() {" | 2222 "function f() {" |
| 2220 " var numbers = {a: {c: 2.2, d: {}}, b: 1.1};" | 2223 " var numbers = {a: {c: 2.2, d: {}}, b: 1.1};" |
| 2221 " return numbers;" | 2224 " return numbers;" |
| 2222 "};" | 2225 "};" |
| 2223 "f(); f(); f();" | 2226 "f(); f(); f();" |
| 2224 "%OptimizeFunctionOnNextCall(f);" | 2227 "%OptimizeFunctionOnNextCall(f);" |
| 2225 "f();"); | 2228 "f();"); |
| 2226 | 2229 |
| 2227 Handle<JSObject> o = | 2230 Handle<JSObject> o = |
| 2228 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2231 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2229 | 2232 |
| 2230 CHECK(HEAP->InOldPointerSpace(*o)); | 2233 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2231 CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(0))); | 2234 CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(0))); |
| 2232 CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(1))); | 2235 CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(1))); |
| 2233 | 2236 |
| 2234 JSObject* inner_object = reinterpret_cast<JSObject*>(o->RawFastPropertyAt(0)); | 2237 JSObject* inner_object = reinterpret_cast<JSObject*>(o->RawFastPropertyAt(0)); |
| 2235 CHECK(HEAP->InOldPointerSpace(inner_object)); | 2238 CHECK(CcTest::heap()->InOldPointerSpace(inner_object)); |
| 2236 CHECK(HEAP->InOldDataSpace(inner_object->RawFastPropertyAt(0))); | 2239 CHECK(CcTest::heap()->InOldDataSpace(inner_object->RawFastPropertyAt(0))); |
| 2237 CHECK(HEAP->InOldPointerSpace(inner_object->RawFastPropertyAt(1))); | 2240 CHECK(CcTest::heap()->InOldPointerSpace(inner_object->RawFastPropertyAt(1))); |
| 2238 } | 2241 } |
| 2239 | 2242 |
| 2240 | 2243 |
| 2241 TEST(OptimizedPretenuringDoubleArrayProperties) { | 2244 TEST(OptimizedPretenuringDoubleArrayProperties) { |
| 2242 i::FLAG_allow_natives_syntax = true; | 2245 i::FLAG_allow_natives_syntax = true; |
| 2243 CcTest::InitializeVM(); | 2246 CcTest::InitializeVM(); |
| 2244 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2247 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2245 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2248 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2246 v8::HandleScope scope(CcTest::isolate()); | 2249 v8::HandleScope scope(CcTest::isolate()); |
| 2247 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2250 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2248 | 2251 |
| 2249 v8::Local<v8::Value> res = CompileRun( | 2252 v8::Local<v8::Value> res = CompileRun( |
| 2250 "function f() {" | 2253 "function f() {" |
| 2251 " var numbers = {a: 1.1, b: 2.2};" | 2254 " var numbers = {a: 1.1, b: 2.2};" |
| 2252 " return numbers;" | 2255 " return numbers;" |
| 2253 "};" | 2256 "};" |
| 2254 "f(); f(); f();" | 2257 "f(); f(); f();" |
| 2255 "%OptimizeFunctionOnNextCall(f);" | 2258 "%OptimizeFunctionOnNextCall(f);" |
| 2256 "f();"); | 2259 "f();"); |
| 2257 | 2260 |
| 2258 Handle<JSObject> o = | 2261 Handle<JSObject> o = |
| 2259 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2262 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2260 | 2263 |
| 2261 CHECK(HEAP->InOldPointerSpace(*o)); | 2264 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2262 CHECK(HEAP->InOldDataSpace(o->properties())); | 2265 CHECK(CcTest::heap()->InOldDataSpace(o->properties())); |
| 2263 } | 2266 } |
| 2264 | 2267 |
| 2265 | 2268 |
| 2266 TEST(OptimizedPretenuringdoubleArrayLiterals) { | 2269 TEST(OptimizedPretenuringdoubleArrayLiterals) { |
| 2267 i::FLAG_allow_natives_syntax = true; | 2270 i::FLAG_allow_natives_syntax = true; |
| 2268 CcTest::InitializeVM(); | 2271 CcTest::InitializeVM(); |
| 2269 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2272 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2270 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2273 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2271 v8::HandleScope scope(CcTest::isolate()); | 2274 v8::HandleScope scope(CcTest::isolate()); |
| 2272 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2275 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2273 | 2276 |
| 2274 v8::Local<v8::Value> res = CompileRun( | 2277 v8::Local<v8::Value> res = CompileRun( |
| 2275 "function f() {" | 2278 "function f() {" |
| 2276 " var numbers = [1.1, 2.2, 3.3];" | 2279 " var numbers = [1.1, 2.2, 3.3];" |
| 2277 " return numbers;" | 2280 " return numbers;" |
| 2278 "};" | 2281 "};" |
| 2279 "f(); f(); f();" | 2282 "f(); f(); f();" |
| 2280 "%OptimizeFunctionOnNextCall(f);" | 2283 "%OptimizeFunctionOnNextCall(f);" |
| 2281 "f();"); | 2284 "f();"); |
| 2282 | 2285 |
| 2283 Handle<JSObject> o = | 2286 Handle<JSObject> o = |
| 2284 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2287 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2285 | 2288 |
| 2286 CHECK(HEAP->InOldDataSpace(o->elements())); | 2289 CHECK(CcTest::heap()->InOldDataSpace(o->elements())); |
| 2287 CHECK(HEAP->InOldPointerSpace(*o)); | 2290 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2288 } | 2291 } |
| 2289 | 2292 |
| 2290 | 2293 |
| 2291 TEST(OptimizedPretenuringNestedMixedArrayLiterals) { | 2294 TEST(OptimizedPretenuringNestedMixedArrayLiterals) { |
| 2292 i::FLAG_allow_natives_syntax = true; | 2295 i::FLAG_allow_natives_syntax = true; |
| 2293 CcTest::InitializeVM(); | 2296 CcTest::InitializeVM(); |
| 2294 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2297 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2295 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2298 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2296 v8::HandleScope scope(CcTest::isolate()); | 2299 v8::HandleScope scope(CcTest::isolate()); |
| 2297 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2300 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2298 | 2301 |
| 2299 v8::Local<v8::Value> res = CompileRun( | 2302 v8::Local<v8::Value> res = CompileRun( |
| 2300 "function f() {" | 2303 "function f() {" |
| 2301 " var numbers = [[{}, {}, {}],[1.1, 2.2, 3.3]];" | 2304 " var numbers = [[{}, {}, {}],[1.1, 2.2, 3.3]];" |
| 2302 " return numbers;" | 2305 " return numbers;" |
| 2303 "};" | 2306 "};" |
| 2304 "f(); f(); f();" | 2307 "f(); f(); f();" |
| 2305 "%OptimizeFunctionOnNextCall(f);" | 2308 "%OptimizeFunctionOnNextCall(f);" |
| 2306 "f();"); | 2309 "f();"); |
| 2307 | 2310 |
| 2308 v8::Local<v8::Value> int_array = v8::Object::Cast(*res)->Get(v8_str("0")); | 2311 v8::Local<v8::Value> int_array = v8::Object::Cast(*res)->Get(v8_str("0")); |
| 2309 Handle<JSObject> int_array_handle = | 2312 Handle<JSObject> int_array_handle = |
| 2310 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array)); | 2313 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array)); |
| 2311 v8::Local<v8::Value> double_array = v8::Object::Cast(*res)->Get(v8_str("1")); | 2314 v8::Local<v8::Value> double_array = v8::Object::Cast(*res)->Get(v8_str("1")); |
| 2312 Handle<JSObject> double_array_handle = | 2315 Handle<JSObject> double_array_handle = |
| 2313 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array)); | 2316 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array)); |
| 2314 | 2317 |
| 2315 Handle<JSObject> o = | 2318 Handle<JSObject> o = |
| 2316 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2319 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2317 CHECK(HEAP->InOldPointerSpace(*o)); | 2320 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2318 CHECK(HEAP->InOldPointerSpace(*int_array_handle)); | 2321 CHECK(CcTest::heap()->InOldPointerSpace(*int_array_handle)); |
| 2319 CHECK(HEAP->InOldPointerSpace(int_array_handle->elements())); | 2322 CHECK(CcTest::heap()->InOldPointerSpace(int_array_handle->elements())); |
| 2320 CHECK(HEAP->InOldPointerSpace(*double_array_handle)); | 2323 CHECK(CcTest::heap()->InOldPointerSpace(*double_array_handle)); |
| 2321 CHECK(HEAP->InOldDataSpace(double_array_handle->elements())); | 2324 CHECK(CcTest::heap()->InOldDataSpace(double_array_handle->elements())); |
| 2322 } | 2325 } |
| 2323 | 2326 |
| 2324 | 2327 |
| 2325 TEST(OptimizedPretenuringNestedObjectLiterals) { | 2328 TEST(OptimizedPretenuringNestedObjectLiterals) { |
| 2326 i::FLAG_allow_natives_syntax = true; | 2329 i::FLAG_allow_natives_syntax = true; |
| 2327 CcTest::InitializeVM(); | 2330 CcTest::InitializeVM(); |
| 2328 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2331 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2329 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2332 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2330 v8::HandleScope scope(CcTest::isolate()); | 2333 v8::HandleScope scope(CcTest::isolate()); |
| 2331 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2334 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2332 | 2335 |
| 2333 v8::Local<v8::Value> res = CompileRun( | 2336 v8::Local<v8::Value> res = CompileRun( |
| 2334 "function f() {" | 2337 "function f() {" |
| 2335 " var numbers = [[{}, {}, {}],[{}, {}, {}]];" | 2338 " var numbers = [[{}, {}, {}],[{}, {}, {}]];" |
| 2336 " return numbers;" | 2339 " return numbers;" |
| 2337 "};" | 2340 "};" |
| 2338 "f(); f(); f();" | 2341 "f(); f(); f();" |
| 2339 "%OptimizeFunctionOnNextCall(f);" | 2342 "%OptimizeFunctionOnNextCall(f);" |
| 2340 "f();"); | 2343 "f();"); |
| 2341 | 2344 |
| 2342 v8::Local<v8::Value> int_array_1 = v8::Object::Cast(*res)->Get(v8_str("0")); | 2345 v8::Local<v8::Value> int_array_1 = v8::Object::Cast(*res)->Get(v8_str("0")); |
| 2343 Handle<JSObject> int_array_handle_1 = | 2346 Handle<JSObject> int_array_handle_1 = |
| 2344 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array_1)); | 2347 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array_1)); |
| 2345 v8::Local<v8::Value> int_array_2 = v8::Object::Cast(*res)->Get(v8_str("1")); | 2348 v8::Local<v8::Value> int_array_2 = v8::Object::Cast(*res)->Get(v8_str("1")); |
| 2346 Handle<JSObject> int_array_handle_2 = | 2349 Handle<JSObject> int_array_handle_2 = |
| 2347 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array_2)); | 2350 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array_2)); |
| 2348 | 2351 |
| 2349 Handle<JSObject> o = | 2352 Handle<JSObject> o = |
| 2350 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2353 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2351 CHECK(HEAP->InOldPointerSpace(*o)); | 2354 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2352 CHECK(HEAP->InOldPointerSpace(*int_array_handle_1)); | 2355 CHECK(CcTest::heap()->InOldPointerSpace(*int_array_handle_1)); |
| 2353 CHECK(HEAP->InOldPointerSpace(int_array_handle_1->elements())); | 2356 CHECK(CcTest::heap()->InOldPointerSpace(int_array_handle_1->elements())); |
| 2354 CHECK(HEAP->InOldPointerSpace(*int_array_handle_2)); | 2357 CHECK(CcTest::heap()->InOldPointerSpace(*int_array_handle_2)); |
| 2355 CHECK(HEAP->InOldPointerSpace(int_array_handle_2->elements())); | 2358 CHECK(CcTest::heap()->InOldPointerSpace(int_array_handle_2->elements())); |
| 2356 } | 2359 } |
| 2357 | 2360 |
| 2358 | 2361 |
| 2359 TEST(OptimizedPretenuringNestedDoubleLiterals) { | 2362 TEST(OptimizedPretenuringNestedDoubleLiterals) { |
| 2360 i::FLAG_allow_natives_syntax = true; | 2363 i::FLAG_allow_natives_syntax = true; |
| 2361 CcTest::InitializeVM(); | 2364 CcTest::InitializeVM(); |
| 2362 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2365 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2363 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2366 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2364 v8::HandleScope scope(CcTest::isolate()); | 2367 v8::HandleScope scope(CcTest::isolate()); |
| 2365 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2368 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2366 | 2369 |
| 2367 v8::Local<v8::Value> res = CompileRun( | 2370 v8::Local<v8::Value> res = CompileRun( |
| 2368 "function f() {" | 2371 "function f() {" |
| 2369 " var numbers = [[1.1, 1.2, 1.3],[2.1, 2.2, 2.3]];" | 2372 " var numbers = [[1.1, 1.2, 1.3],[2.1, 2.2, 2.3]];" |
| 2370 " return numbers;" | 2373 " return numbers;" |
| 2371 "};" | 2374 "};" |
| 2372 "f(); f(); f();" | 2375 "f(); f(); f();" |
| 2373 "%OptimizeFunctionOnNextCall(f);" | 2376 "%OptimizeFunctionOnNextCall(f);" |
| 2374 "f();"); | 2377 "f();"); |
| 2375 | 2378 |
| 2376 v8::Local<v8::Value> double_array_1 = | 2379 v8::Local<v8::Value> double_array_1 = |
| 2377 v8::Object::Cast(*res)->Get(v8_str("0")); | 2380 v8::Object::Cast(*res)->Get(v8_str("0")); |
| 2378 Handle<JSObject> double_array_handle_1 = | 2381 Handle<JSObject> double_array_handle_1 = |
| 2379 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array_1)); | 2382 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array_1)); |
| 2380 v8::Local<v8::Value> double_array_2 = | 2383 v8::Local<v8::Value> double_array_2 = |
| 2381 v8::Object::Cast(*res)->Get(v8_str("1")); | 2384 v8::Object::Cast(*res)->Get(v8_str("1")); |
| 2382 Handle<JSObject> double_array_handle_2 = | 2385 Handle<JSObject> double_array_handle_2 = |
| 2383 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array_2)); | 2386 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array_2)); |
| 2384 | 2387 |
| 2385 Handle<JSObject> o = | 2388 Handle<JSObject> o = |
| 2386 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2389 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2387 CHECK(HEAP->InOldPointerSpace(*o)); | 2390 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2388 CHECK(HEAP->InOldPointerSpace(*double_array_handle_1)); | 2391 CHECK(CcTest::heap()->InOldPointerSpace(*double_array_handle_1)); |
| 2389 CHECK(HEAP->InOldDataSpace(double_array_handle_1->elements())); | 2392 CHECK(CcTest::heap()->InOldDataSpace(double_array_handle_1->elements())); |
| 2390 CHECK(HEAP->InOldPointerSpace(*double_array_handle_2)); | 2393 CHECK(CcTest::heap()->InOldPointerSpace(*double_array_handle_2)); |
| 2391 CHECK(HEAP->InOldDataSpace(double_array_handle_2->elements())); | 2394 CHECK(CcTest::heap()->InOldDataSpace(double_array_handle_2->elements())); |
| 2392 } | 2395 } |
| 2393 | 2396 |
| 2394 | 2397 |
| 2395 // Test regular array literals allocation. | 2398 // Test regular array literals allocation. |
| 2396 TEST(OptimizedAllocationArrayLiterals) { | 2399 TEST(OptimizedAllocationArrayLiterals) { |
| 2397 i::FLAG_allow_natives_syntax = true; | 2400 i::FLAG_allow_natives_syntax = true; |
| 2398 CcTest::InitializeVM(); | 2401 CcTest::InitializeVM(); |
| 2399 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2402 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2400 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2403 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2401 v8::HandleScope scope(CcTest::isolate()); | 2404 v8::HandleScope scope(CcTest::isolate()); |
| 2402 | 2405 |
| 2403 v8::Local<v8::Value> res = CompileRun( | 2406 v8::Local<v8::Value> res = CompileRun( |
| 2404 "function f() {" | 2407 "function f() {" |
| 2405 " var numbers = new Array(1, 2, 3);" | 2408 " var numbers = new Array(1, 2, 3);" |
| 2406 " numbers[0] = 3.14;" | 2409 " numbers[0] = 3.14;" |
| 2407 " return numbers;" | 2410 " return numbers;" |
| 2408 "};" | 2411 "};" |
| 2409 "f(); f(); f();" | 2412 "f(); f(); f();" |
| 2410 "%OptimizeFunctionOnNextCall(f);" | 2413 "%OptimizeFunctionOnNextCall(f);" |
| 2411 "f();"); | 2414 "f();"); |
| 2412 CHECK_EQ(static_cast<int>(3.14), | 2415 CHECK_EQ(static_cast<int>(3.14), |
| 2413 v8::Object::Cast(*res)->Get(v8_str("0"))->Int32Value()); | 2416 v8::Object::Cast(*res)->Get(v8_str("0"))->Int32Value()); |
| 2414 | 2417 |
| 2415 Handle<JSObject> o = | 2418 Handle<JSObject> o = |
| 2416 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2419 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2417 | 2420 |
| 2418 CHECK(HEAP->InNewSpace(o->elements())); | 2421 CHECK(CcTest::heap()->InNewSpace(o->elements())); |
| 2419 } | 2422 } |
| 2420 | 2423 |
| 2421 | 2424 |
| 2422 TEST(OptimizedPretenuringCallNew) { | 2425 TEST(OptimizedPretenuringCallNew) { |
| 2423 i::FLAG_allow_natives_syntax = true; | 2426 i::FLAG_allow_natives_syntax = true; |
| 2424 i::FLAG_pretenuring_call_new = true; | 2427 i::FLAG_pretenuring_call_new = true; |
| 2425 CcTest::InitializeVM(); | 2428 CcTest::InitializeVM(); |
| 2426 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2429 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2427 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2430 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2428 v8::HandleScope scope(CcTest::isolate()); | 2431 v8::HandleScope scope(CcTest::isolate()); |
| 2429 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2432 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2430 | 2433 |
| 2431 AlwaysAllocateScope always_allocate; | 2434 AlwaysAllocateScope always_allocate; |
| 2432 v8::Local<v8::Value> res = CompileRun( | 2435 v8::Local<v8::Value> res = CompileRun( |
| 2433 "function g() { this.a = 0; }" | 2436 "function g() { this.a = 0; }" |
| 2434 "function f() {" | 2437 "function f() {" |
| 2435 " return new g();" | 2438 " return new g();" |
| 2436 "};" | 2439 "};" |
| 2437 "f(); f(); f();" | 2440 "f(); f(); f();" |
| 2438 "%OptimizeFunctionOnNextCall(f);" | 2441 "%OptimizeFunctionOnNextCall(f);" |
| 2439 "f();"); | 2442 "f();"); |
| 2440 | 2443 |
| 2441 Handle<JSObject> o = | 2444 Handle<JSObject> o = |
| 2442 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2445 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2443 CHECK(HEAP->InOldPointerSpace(*o)); | 2446 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2444 } | 2447 } |
| 2445 | 2448 |
| 2446 | 2449 |
| 2447 static int CountMapTransitions(Map* map) { | 2450 static int CountMapTransitions(Map* map) { |
| 2448 return map->transitions()->number_of_transitions(); | 2451 return map->transitions()->number_of_transitions(); |
| 2449 } | 2452 } |
| 2450 | 2453 |
| 2451 | 2454 |
| 2452 // Test that map transitions are cleared and maps are collected with | 2455 // Test that map transitions are cleared and maps are collected with |
| 2453 // incremental marking as well. | 2456 // incremental marking as well. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2473 v8::Utils::OpenHandle( | 2476 v8::Utils::OpenHandle( |
| 2474 *v8::Handle<v8::Object>::Cast( | 2477 *v8::Handle<v8::Object>::Cast( |
| 2475 v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); | 2478 v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); |
| 2476 | 2479 |
| 2477 // Count number of live transitions before marking. | 2480 // Count number of live transitions before marking. |
| 2478 int transitions_before = CountMapTransitions(root->map()); | 2481 int transitions_before = CountMapTransitions(root->map()); |
| 2479 CompileRun("%DebugPrint(root);"); | 2482 CompileRun("%DebugPrint(root);"); |
| 2480 CHECK_EQ(transitions_count, transitions_before); | 2483 CHECK_EQ(transitions_count, transitions_before); |
| 2481 | 2484 |
| 2482 SimulateIncrementalMarking(); | 2485 SimulateIncrementalMarking(); |
| 2483 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2486 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2484 | 2487 |
| 2485 // Count number of live transitions after marking. Note that one transition | 2488 // Count number of live transitions after marking. Note that one transition |
| 2486 // is left, because 'o' still holds an instance of one transition target. | 2489 // is left, because 'o' still holds an instance of one transition target. |
| 2487 int transitions_after = CountMapTransitions(root->map()); | 2490 int transitions_after = CountMapTransitions(root->map()); |
| 2488 CompileRun("%DebugPrint(root);"); | 2491 CompileRun("%DebugPrint(root);"); |
| 2489 CHECK_EQ(1, transitions_after); | 2492 CHECK_EQ(1, transitions_after); |
| 2490 } | 2493 } |
| 2491 | 2494 |
| 2492 | 2495 |
| 2493 TEST(Regress2143a) { | 2496 TEST(Regress2143a) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2507 // Compile a StoreIC that performs the prepared map transition. This | 2510 // Compile a StoreIC that performs the prepared map transition. This |
| 2508 // will restart incremental marking and should make sure the root is | 2511 // will restart incremental marking and should make sure the root is |
| 2509 // marked grey again. | 2512 // marked grey again. |
| 2510 CompileRun("function f(o) {" | 2513 CompileRun("function f(o) {" |
| 2511 " o.foo = 0;" | 2514 " o.foo = 0;" |
| 2512 "}" | 2515 "}" |
| 2513 "f(new Object);" | 2516 "f(new Object);" |
| 2514 "f(root);"); | 2517 "f(root);"); |
| 2515 | 2518 |
| 2516 // This bug only triggers with aggressive IC clearing. | 2519 // This bug only triggers with aggressive IC clearing. |
| 2517 HEAP->AgeInlineCaches(); | 2520 CcTest::heap()->AgeInlineCaches(); |
| 2518 | 2521 |
| 2519 // Explicitly request GC to perform final marking step and sweeping. | 2522 // Explicitly request GC to perform final marking step and sweeping. |
| 2520 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2523 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2521 | 2524 |
| 2522 Handle<JSObject> root = | 2525 Handle<JSObject> root = |
| 2523 v8::Utils::OpenHandle( | 2526 v8::Utils::OpenHandle( |
| 2524 *v8::Handle<v8::Object>::Cast( | 2527 *v8::Handle<v8::Object>::Cast( |
| 2525 v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); | 2528 v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); |
| 2526 | 2529 |
| 2527 // The root object should be in a sane state. | 2530 // The root object should be in a sane state. |
| 2528 CHECK(root->IsJSObject()); | 2531 CHECK(root->IsJSObject()); |
| 2529 CHECK(root->map()->IsMap()); | 2532 CHECK(root->map()->IsMap()); |
| 2530 } | 2533 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2551 CompileRun("function f(o) {" | 2554 CompileRun("function f(o) {" |
| 2552 " o.foo = 0;" | 2555 " o.foo = 0;" |
| 2553 "}" | 2556 "}" |
| 2554 "f(new Object);" | 2557 "f(new Object);" |
| 2555 "f(new Object);" | 2558 "f(new Object);" |
| 2556 "%OptimizeFunctionOnNextCall(f);" | 2559 "%OptimizeFunctionOnNextCall(f);" |
| 2557 "f(root);" | 2560 "f(root);" |
| 2558 "%DeoptimizeFunction(f);"); | 2561 "%DeoptimizeFunction(f);"); |
| 2559 | 2562 |
| 2560 // This bug only triggers with aggressive IC clearing. | 2563 // This bug only triggers with aggressive IC clearing. |
| 2561 HEAP->AgeInlineCaches(); | 2564 CcTest::heap()->AgeInlineCaches(); |
| 2562 | 2565 |
| 2563 // Explicitly request GC to perform final marking step and sweeping. | 2566 // Explicitly request GC to perform final marking step and sweeping. |
| 2564 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2567 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2565 | 2568 |
| 2566 Handle<JSObject> root = | 2569 Handle<JSObject> root = |
| 2567 v8::Utils::OpenHandle( | 2570 v8::Utils::OpenHandle( |
| 2568 *v8::Handle<v8::Object>::Cast( | 2571 *v8::Handle<v8::Object>::Cast( |
| 2569 v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); | 2572 v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); |
| 2570 | 2573 |
| 2571 // The root object should be in a sane state. | 2574 // The root object should be in a sane state. |
| 2572 CHECK(root->IsJSObject()); | 2575 CHECK(root->IsJSObject()); |
| 2573 CHECK(root->map()->IsMap()); | 2576 CHECK(root->map()->IsMap()); |
| 2574 } | 2577 } |
| 2575 | 2578 |
| 2576 | 2579 |
| 2577 TEST(ReleaseOverReservedPages) { | 2580 TEST(ReleaseOverReservedPages) { |
| 2578 i::FLAG_trace_gc = true; | 2581 i::FLAG_trace_gc = true; |
| 2579 // The optimizer can allocate stuff, messing up the test. | 2582 // The optimizer can allocate stuff, messing up the test. |
| 2580 i::FLAG_crankshaft = false; | 2583 i::FLAG_crankshaft = false; |
| 2581 i::FLAG_always_opt = false; | 2584 i::FLAG_always_opt = false; |
| 2582 CcTest::InitializeVM(); | 2585 CcTest::InitializeVM(); |
| 2583 Isolate* isolate = CcTest::i_isolate(); | 2586 Isolate* isolate = CcTest::i_isolate(); |
| 2584 Factory* factory = isolate->factory(); | 2587 Factory* factory = isolate->factory(); |
| 2588 Heap* heap = isolate->heap(); |
| 2585 v8::HandleScope scope(CcTest::isolate()); | 2589 v8::HandleScope scope(CcTest::isolate()); |
| 2586 static const int number_of_test_pages = 20; | 2590 static const int number_of_test_pages = 20; |
| 2587 | 2591 |
| 2588 // Prepare many pages with low live-bytes count. | 2592 // Prepare many pages with low live-bytes count. |
| 2589 PagedSpace* old_pointer_space = HEAP->old_pointer_space(); | 2593 PagedSpace* old_pointer_space = heap->old_pointer_space(); |
| 2590 CHECK_EQ(1, old_pointer_space->CountTotalPages()); | 2594 CHECK_EQ(1, old_pointer_space->CountTotalPages()); |
| 2591 for (int i = 0; i < number_of_test_pages; i++) { | 2595 for (int i = 0; i < number_of_test_pages; i++) { |
| 2592 AlwaysAllocateScope always_allocate; | 2596 AlwaysAllocateScope always_allocate; |
| 2593 SimulateFullSpace(old_pointer_space); | 2597 SimulateFullSpace(old_pointer_space); |
| 2594 factory->NewFixedArray(1, TENURED); | 2598 factory->NewFixedArray(1, TENURED); |
| 2595 } | 2599 } |
| 2596 CHECK_EQ(number_of_test_pages + 1, old_pointer_space->CountTotalPages()); | 2600 CHECK_EQ(number_of_test_pages + 1, old_pointer_space->CountTotalPages()); |
| 2597 | 2601 |
| 2598 // Triggering one GC will cause a lot of garbage to be discovered but | 2602 // Triggering one GC will cause a lot of garbage to be discovered but |
| 2599 // even spread across all allocated pages. | 2603 // even spread across all allocated pages. |
| 2600 HEAP->CollectAllGarbage(Heap::kNoGCFlags, "triggered for preparation"); | 2604 heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered for preparation"); |
| 2601 CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages()); | 2605 CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages()); |
| 2602 | 2606 |
| 2603 // Triggering subsequent GCs should cause at least half of the pages | 2607 // Triggering subsequent GCs should cause at least half of the pages |
| 2604 // to be released to the OS after at most two cycles. | 2608 // to be released to the OS after at most two cycles. |
| 2605 HEAP->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 1"); | 2609 heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 1"); |
| 2606 CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages()); | 2610 CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages()); |
| 2607 HEAP->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 2"); | 2611 heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 2"); |
| 2608 CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages() * 2); | 2612 CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages() * 2); |
| 2609 | 2613 |
| 2610 // Triggering a last-resort GC should cause all pages to be released to the | 2614 // Triggering a last-resort GC should cause all pages to be released to the |
| 2611 // OS so that other processes can seize the memory. If we get a failure here | 2615 // OS so that other processes can seize the memory. If we get a failure here |
| 2612 // where there are 2 pages left instead of 1, then we should increase the | 2616 // where there are 2 pages left instead of 1, then we should increase the |
| 2613 // size of the first page a little in SizeOfFirstPage in spaces.cc. The | 2617 // size of the first page a little in SizeOfFirstPage in spaces.cc. The |
| 2614 // first page should be small in order to reduce memory used when the VM | 2618 // first page should be small in order to reduce memory used when the VM |
| 2615 // boots, but if the 20 small arrays don't fit on the first page then that's | 2619 // boots, but if the 20 small arrays don't fit on the first page then that's |
| 2616 // an indication that it is too small. | 2620 // an indication that it is too small. |
| 2617 HEAP->CollectAllAvailableGarbage("triggered really hard"); | 2621 heap->CollectAllAvailableGarbage("triggered really hard"); |
| 2618 CHECK_EQ(1, old_pointer_space->CountTotalPages()); | 2622 CHECK_EQ(1, old_pointer_space->CountTotalPages()); |
| 2619 } | 2623 } |
| 2620 | 2624 |
| 2621 | 2625 |
| 2622 TEST(Regress2237) { | 2626 TEST(Regress2237) { |
| 2623 i::FLAG_stress_compaction = false; | 2627 i::FLAG_stress_compaction = false; |
| 2624 CcTest::InitializeVM(); | 2628 CcTest::InitializeVM(); |
| 2625 Isolate* isolate = CcTest::i_isolate(); | 2629 Isolate* isolate = CcTest::i_isolate(); |
| 2626 Factory* factory = isolate->factory(); | 2630 Factory* factory = isolate->factory(); |
| 2627 v8::HandleScope scope(CcTest::isolate()); | 2631 v8::HandleScope scope(CcTest::isolate()); |
| 2628 Handle<String> slice(HEAP->empty_string()); | 2632 Handle<String> slice(CcTest::heap()->empty_string()); |
| 2629 | 2633 |
| 2630 { | 2634 { |
| 2631 // Generate a parent that lives in new-space. | 2635 // Generate a parent that lives in new-space. |
| 2632 v8::HandleScope inner_scope(CcTest::isolate()); | 2636 v8::HandleScope inner_scope(CcTest::isolate()); |
| 2633 const char* c = "This text is long enough to trigger sliced strings."; | 2637 const char* c = "This text is long enough to trigger sliced strings."; |
| 2634 Handle<String> s = factory->NewStringFromAscii(CStrVector(c)); | 2638 Handle<String> s = factory->NewStringFromAscii(CStrVector(c)); |
| 2635 CHECK(s->IsSeqOneByteString()); | 2639 CHECK(s->IsSeqOneByteString()); |
| 2636 CHECK(HEAP->InNewSpace(*s)); | 2640 CHECK(CcTest::heap()->InNewSpace(*s)); |
| 2637 | 2641 |
| 2638 // Generate a sliced string that is based on the above parent and | 2642 // Generate a sliced string that is based on the above parent and |
| 2639 // lives in old-space. | 2643 // lives in old-space. |
| 2640 SimulateFullSpace(HEAP->new_space()); | 2644 SimulateFullSpace(CcTest::heap()->new_space()); |
| 2641 AlwaysAllocateScope always_allocate; | 2645 AlwaysAllocateScope always_allocate; |
| 2642 Handle<String> t = factory->NewProperSubString(s, 5, 35); | 2646 Handle<String> t = factory->NewProperSubString(s, 5, 35); |
| 2643 CHECK(t->IsSlicedString()); | 2647 CHECK(t->IsSlicedString()); |
| 2644 CHECK(!HEAP->InNewSpace(*t)); | 2648 CHECK(!CcTest::heap()->InNewSpace(*t)); |
| 2645 *slice.location() = *t.location(); | 2649 *slice.location() = *t.location(); |
| 2646 } | 2650 } |
| 2647 | 2651 |
| 2648 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString()); | 2652 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString()); |
| 2649 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2653 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2650 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString()); | 2654 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString()); |
| 2651 } | 2655 } |
| 2652 | 2656 |
| 2653 | 2657 |
| 2654 #ifdef OBJECT_PRINT | 2658 #ifdef OBJECT_PRINT |
| 2655 TEST(PrintSharedFunctionInfo) { | 2659 TEST(PrintSharedFunctionInfo) { |
| 2656 CcTest::InitializeVM(); | 2660 CcTest::InitializeVM(); |
| 2657 v8::HandleScope scope(CcTest::isolate()); | 2661 v8::HandleScope scope(CcTest::isolate()); |
| 2658 const char* source = "f = function() { return 987654321; }\n" | 2662 const char* source = "f = function() { return 987654321; }\n" |
| 2659 "g = function() { return 123456789; }\n"; | 2663 "g = function() { return 123456789; }\n"; |
| 2660 CompileRun(source); | 2664 CompileRun(source); |
| 2661 Handle<JSFunction> g = | 2665 Handle<JSFunction> g = |
| 2662 v8::Utils::OpenHandle( | 2666 v8::Utils::OpenHandle( |
| 2663 *v8::Handle<v8::Function>::Cast( | 2667 *v8::Handle<v8::Function>::Cast( |
| 2664 v8::Context::GetCurrent()->Global()->Get(v8_str("g")))); | 2668 v8::Context::GetCurrent()->Global()->Get(v8_str("g")))); |
| 2665 | 2669 |
| 2666 DisallowHeapAllocation no_allocation; | 2670 DisallowHeapAllocation no_allocation; |
| 2667 g->shared()->PrintLn(); | 2671 g->shared()->PrintLn(); |
| 2668 } | 2672 } |
| 2669 #endif // OBJECT_PRINT | 2673 #endif // OBJECT_PRINT |
| 2670 | 2674 |
| 2671 | 2675 |
| 2672 TEST(Regress2211) { | 2676 TEST(Regress2211) { |
| 2673 CcTest::InitializeVM(); | 2677 CcTest::InitializeVM(); |
| 2674 v8::HandleScope scope(CcTest::isolate()); | 2678 v8::HandleScope scope(CcTest::isolate()); |
| 2675 | 2679 |
| 2676 v8::Handle<v8::String> value = v8_str("val string"); | 2680 v8::Handle<v8::String> value = v8_str("val string"); |
| 2677 Smi* hash = Smi::FromInt(321); | 2681 Smi* hash = Smi::FromInt(321); |
| 2678 Heap* heap = CcTest::i_isolate()->heap(); | 2682 Heap* heap = CcTest::heap(); |
| 2679 | 2683 |
| 2680 for (int i = 0; i < 2; i++) { | 2684 for (int i = 0; i < 2; i++) { |
| 2681 // Store identity hash first and common hidden property second. | 2685 // Store identity hash first and common hidden property second. |
| 2682 v8::Handle<v8::Object> obj = v8::Object::New(); | 2686 v8::Handle<v8::Object> obj = v8::Object::New(); |
| 2683 Handle<JSObject> internal_obj = v8::Utils::OpenHandle(*obj); | 2687 Handle<JSObject> internal_obj = v8::Utils::OpenHandle(*obj); |
| 2684 CHECK(internal_obj->HasFastProperties()); | 2688 CHECK(internal_obj->HasFastProperties()); |
| 2685 | 2689 |
| 2686 // In the first iteration, set hidden value first and identity hash second. | 2690 // In the first iteration, set hidden value first and identity hash second. |
| 2687 // In the second iteration, reverse the order. | 2691 // In the second iteration, reverse the order. |
| 2688 if (i == 0) obj->SetHiddenValue(v8_str("key string"), value); | 2692 if (i == 0) obj->SetHiddenValue(v8_str("key string"), value); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2732 *v8::Handle<v8::Function>::Cast( | 2736 *v8::Handle<v8::Function>::Cast( |
| 2733 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2737 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2734 Handle<TypeFeedbackCells> cells(TypeFeedbackInfo::cast( | 2738 Handle<TypeFeedbackCells> cells(TypeFeedbackInfo::cast( |
| 2735 f->shared()->code()->type_feedback_info())->type_feedback_cells()); | 2739 f->shared()->code()->type_feedback_info())->type_feedback_cells()); |
| 2736 | 2740 |
| 2737 CHECK_EQ(2, cells->CellCount()); | 2741 CHECK_EQ(2, cells->CellCount()); |
| 2738 CHECK(cells->GetCell(0)->value()->IsJSFunction()); | 2742 CHECK(cells->GetCell(0)->value()->IsJSFunction()); |
| 2739 CHECK(cells->GetCell(1)->value()->IsJSFunction()); | 2743 CHECK(cells->GetCell(1)->value()->IsJSFunction()); |
| 2740 | 2744 |
| 2741 SimulateIncrementalMarking(); | 2745 SimulateIncrementalMarking(); |
| 2742 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2746 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2743 | 2747 |
| 2744 CHECK_EQ(2, cells->CellCount()); | 2748 CHECK_EQ(2, cells->CellCount()); |
| 2745 CHECK(cells->GetCell(0)->value()->IsTheHole()); | 2749 CHECK(cells->GetCell(0)->value()->IsTheHole()); |
| 2746 CHECK(cells->GetCell(1)->value()->IsTheHole()); | 2750 CHECK(cells->GetCell(1)->value()->IsTheHole()); |
| 2747 } | 2751 } |
| 2748 | 2752 |
| 2749 | 2753 |
| 2750 static Code* FindFirstIC(Code* code, Code::Kind kind) { | 2754 static Code* FindFirstIC(Code* code, Code::Kind kind) { |
| 2751 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | | 2755 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
| 2752 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | | 2756 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2774 "function f(o) { return o.x; } f(obj); f(obj);"); | 2778 "function f(o) { return o.x; } f(obj); f(obj);"); |
| 2775 Handle<JSFunction> f = | 2779 Handle<JSFunction> f = |
| 2776 v8::Utils::OpenHandle( | 2780 v8::Utils::OpenHandle( |
| 2777 *v8::Handle<v8::Function>::Cast( | 2781 *v8::Handle<v8::Function>::Cast( |
| 2778 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2782 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2779 | 2783 |
| 2780 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2784 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2781 CHECK(ic_before->ic_state() == MONOMORPHIC); | 2785 CHECK(ic_before->ic_state() == MONOMORPHIC); |
| 2782 | 2786 |
| 2783 SimulateIncrementalMarking(); | 2787 SimulateIncrementalMarking(); |
| 2784 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2788 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2785 | 2789 |
| 2786 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2790 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2787 CHECK(ic_after->ic_state() == MONOMORPHIC); | 2791 CHECK(ic_after->ic_state() == MONOMORPHIC); |
| 2788 } | 2792 } |
| 2789 | 2793 |
| 2790 | 2794 |
| 2791 TEST(IncrementalMarkingClearsMonomorhpicIC) { | 2795 TEST(IncrementalMarkingClearsMonomorhpicIC) { |
| 2792 if (i::FLAG_always_opt) return; | 2796 if (i::FLAG_always_opt) return; |
| 2793 CcTest::InitializeVM(); | 2797 CcTest::InitializeVM(); |
| 2794 v8::HandleScope scope(CcTest::isolate()); | 2798 v8::HandleScope scope(CcTest::isolate()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2808 v8::Utils::OpenHandle( | 2812 v8::Utils::OpenHandle( |
| 2809 *v8::Handle<v8::Function>::Cast( | 2813 *v8::Handle<v8::Function>::Cast( |
| 2810 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2814 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2811 | 2815 |
| 2812 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2816 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2813 CHECK(ic_before->ic_state() == MONOMORPHIC); | 2817 CHECK(ic_before->ic_state() == MONOMORPHIC); |
| 2814 | 2818 |
| 2815 // Fire context dispose notification. | 2819 // Fire context dispose notification. |
| 2816 v8::V8::ContextDisposedNotification(); | 2820 v8::V8::ContextDisposedNotification(); |
| 2817 SimulateIncrementalMarking(); | 2821 SimulateIncrementalMarking(); |
| 2818 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2822 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2819 | 2823 |
| 2820 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2824 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2821 CHECK(ic_after->ic_state() == UNINITIALIZED); | 2825 CHECK(ic_after->ic_state() == UNINITIALIZED); |
| 2822 } | 2826 } |
| 2823 | 2827 |
| 2824 | 2828 |
| 2825 TEST(IncrementalMarkingClearsPolymorhpicIC) { | 2829 TEST(IncrementalMarkingClearsPolymorhpicIC) { |
| 2826 if (i::FLAG_always_opt) return; | 2830 if (i::FLAG_always_opt) return; |
| 2827 CcTest::InitializeVM(); | 2831 CcTest::InitializeVM(); |
| 2828 v8::HandleScope scope(CcTest::isolate()); | 2832 v8::HandleScope scope(CcTest::isolate()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2849 v8::Utils::OpenHandle( | 2853 v8::Utils::OpenHandle( |
| 2850 *v8::Handle<v8::Function>::Cast( | 2854 *v8::Handle<v8::Function>::Cast( |
| 2851 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2855 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2852 | 2856 |
| 2853 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2857 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2854 CHECK(ic_before->ic_state() == POLYMORPHIC); | 2858 CHECK(ic_before->ic_state() == POLYMORPHIC); |
| 2855 | 2859 |
| 2856 // Fire context dispose notification. | 2860 // Fire context dispose notification. |
| 2857 v8::V8::ContextDisposedNotification(); | 2861 v8::V8::ContextDisposedNotification(); |
| 2858 SimulateIncrementalMarking(); | 2862 SimulateIncrementalMarking(); |
| 2859 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2863 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2860 | 2864 |
| 2861 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2865 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2862 CHECK(ic_after->ic_state() == UNINITIALIZED); | 2866 CHECK(ic_after->ic_state() == UNINITIALIZED); |
| 2863 } | 2867 } |
| 2864 | 2868 |
| 2865 | 2869 |
| 2866 class SourceResource: public v8::String::ExternalAsciiStringResource { | 2870 class SourceResource: public v8::String::ExternalAsciiStringResource { |
| 2867 public: | 2871 public: |
| 2868 explicit SourceResource(const char* data) | 2872 explicit SourceResource(const char* data) |
| 2869 : data_(data), length_(strlen(data)) { } | 2873 : data_(data), length_(strlen(data)) { } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2891 // to check whether the data is being released since the external string | 2895 // to check whether the data is being released since the external string |
| 2892 // resource's callback is fired when the external string is GC'ed. | 2896 // resource's callback is fired when the external string is GC'ed. |
| 2893 FLAG_use_ic = false; // ICs retain objects. | 2897 FLAG_use_ic = false; // ICs retain objects. |
| 2894 FLAG_concurrent_recompilation = false; | 2898 FLAG_concurrent_recompilation = false; |
| 2895 CcTest::InitializeVM(); | 2899 CcTest::InitializeVM(); |
| 2896 v8::HandleScope scope(CcTest::isolate()); | 2900 v8::HandleScope scope(CcTest::isolate()); |
| 2897 SourceResource* resource = new SourceResource(i::StrDup(source)); | 2901 SourceResource* resource = new SourceResource(i::StrDup(source)); |
| 2898 { | 2902 { |
| 2899 v8::HandleScope scope(CcTest::isolate()); | 2903 v8::HandleScope scope(CcTest::isolate()); |
| 2900 v8::Handle<v8::String> source_string = v8::String::NewExternal(resource); | 2904 v8::Handle<v8::String> source_string = v8::String::NewExternal(resource); |
| 2901 HEAP->CollectAllAvailableGarbage(); | 2905 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2902 v8::Script::Compile(source_string)->Run(); | 2906 v8::Script::Compile(source_string)->Run(); |
| 2903 CHECK(!resource->IsDisposed()); | 2907 CHECK(!resource->IsDisposed()); |
| 2904 } | 2908 } |
| 2905 // HEAP->CollectAllAvailableGarbage(); | 2909 // CcTest::heap()->CollectAllAvailableGarbage(); |
| 2906 CHECK(!resource->IsDisposed()); | 2910 CHECK(!resource->IsDisposed()); |
| 2907 | 2911 |
| 2908 CompileRun(accessor); | 2912 CompileRun(accessor); |
| 2909 HEAP->CollectAllAvailableGarbage(); | 2913 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2910 | 2914 |
| 2911 // External source has been released. | 2915 // External source has been released. |
| 2912 CHECK(resource->IsDisposed()); | 2916 CHECK(resource->IsDisposed()); |
| 2913 delete resource; | 2917 delete resource; |
| 2914 } | 2918 } |
| 2915 | 2919 |
| 2916 | 2920 |
| 2917 TEST(ReleaseStackTraceData) { | 2921 TEST(ReleaseStackTraceData) { |
| 2918 static const char* source1 = "var error = null; " | 2922 static const char* source1 = "var error = null; " |
| 2919 /* Normal Error */ "try { " | 2923 /* Normal Error */ "try { " |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3243 "obj = fastliteralcase(get_standard_literal(), 2);"); | 3247 "obj = fastliteralcase(get_standard_literal(), 2);"); |
| 3244 | 3248 |
| 3245 // prepare the heap | 3249 // prepare the heap |
| 3246 v8::Local<v8::String> mote_code_string = | 3250 v8::Local<v8::String> mote_code_string = |
| 3247 v8_str("fastliteralcase(mote, 2.5);"); | 3251 v8_str("fastliteralcase(mote, 2.5);"); |
| 3248 | 3252 |
| 3249 v8::Local<v8::String> array_name = v8_str("mote"); | 3253 v8::Local<v8::String> array_name = v8_str("mote"); |
| 3250 v8::Context::GetCurrent()->Global()->Set(array_name, v8::Int32::New(0)); | 3254 v8::Context::GetCurrent()->Global()->Set(array_name, v8::Int32::New(0)); |
| 3251 | 3255 |
| 3252 // First make sure we flip spaces | 3256 // First make sure we flip spaces |
| 3253 HEAP->CollectGarbage(NEW_SPACE); | 3257 CcTest::heap()->CollectGarbage(NEW_SPACE); |
| 3254 | 3258 |
| 3255 // Allocate the object. | 3259 // Allocate the object. |
| 3256 Handle<FixedArray> array_data = factory->NewFixedArray(2, NOT_TENURED); | 3260 Handle<FixedArray> array_data = factory->NewFixedArray(2, NOT_TENURED); |
| 3257 array_data->set(0, Smi::FromInt(1)); | 3261 array_data->set(0, Smi::FromInt(1)); |
| 3258 array_data->set(1, Smi::FromInt(2)); | 3262 array_data->set(1, Smi::FromInt(2)); |
| 3259 | 3263 |
| 3260 AllocateAllButNBytes(HEAP->new_space(), | 3264 AllocateAllButNBytes(CcTest::heap()->new_space(), |
| 3261 JSArray::kSize + AllocationMemento::kSize + | 3265 JSArray::kSize + AllocationMemento::kSize + |
| 3262 kPointerSize); | 3266 kPointerSize); |
| 3263 | 3267 |
| 3264 Handle<JSArray> array = factory->NewJSArrayWithElements(array_data, | 3268 Handle<JSArray> array = factory->NewJSArrayWithElements(array_data, |
| 3265 FAST_SMI_ELEMENTS, | 3269 FAST_SMI_ELEMENTS, |
| 3266 NOT_TENURED); | 3270 NOT_TENURED); |
| 3267 | 3271 |
| 3268 CHECK_EQ(Smi::FromInt(2), array->length()); | 3272 CHECK_EQ(Smi::FromInt(2), array->length()); |
| 3269 CHECK(array->HasFastSmiOrObjectElements()); | 3273 CHECK(array->HasFastSmiOrObjectElements()); |
| 3270 | 3274 |
| 3271 // We need filler the size of AllocationMemento object, plus an extra | 3275 // We need filler the size of AllocationMemento object, plus an extra |
| 3272 // fill pointer value. | 3276 // fill pointer value. |
| 3273 MaybeObject* maybe_object = HEAP->AllocateRaw( | 3277 MaybeObject* maybe_object = CcTest::heap()->AllocateRaw( |
| 3274 AllocationMemento::kSize + kPointerSize, NEW_SPACE, OLD_POINTER_SPACE); | 3278 AllocationMemento::kSize + kPointerSize, NEW_SPACE, OLD_POINTER_SPACE); |
| 3275 Object* obj = NULL; | 3279 Object* obj = NULL; |
| 3276 CHECK(maybe_object->ToObject(&obj)); | 3280 CHECK(maybe_object->ToObject(&obj)); |
| 3277 Address addr_obj = reinterpret_cast<Address>( | 3281 Address addr_obj = reinterpret_cast<Address>( |
| 3278 reinterpret_cast<byte*>(obj - kHeapObjectTag)); | 3282 reinterpret_cast<byte*>(obj - kHeapObjectTag)); |
| 3279 HEAP->CreateFillerObjectAt(addr_obj, | 3283 CcTest::heap()->CreateFillerObjectAt(addr_obj, |
| 3280 AllocationMemento::kSize + kPointerSize); | 3284 AllocationMemento::kSize + kPointerSize); |
| 3281 | 3285 |
| 3282 // Give the array a name, making sure not to allocate strings. | 3286 // Give the array a name, making sure not to allocate strings. |
| 3283 v8::Handle<v8::Object> array_obj = v8::Utils::ToLocal(array); | 3287 v8::Handle<v8::Object> array_obj = v8::Utils::ToLocal(array); |
| 3284 v8::Context::GetCurrent()->Global()->Set(array_name, array_obj); | 3288 v8::Context::GetCurrent()->Global()->Set(array_name, array_obj); |
| 3285 | 3289 |
| 3286 // This should crash with a protection violation if we are running a build | 3290 // This should crash with a protection violation if we are running a build |
| 3287 // with the bug. | 3291 // with the bug. |
| 3288 AlwaysAllocateScope aa_scope; | 3292 AlwaysAllocateScope aa_scope; |
| 3289 v8::Script::Compile(mote_code_string)->Run(); | 3293 v8::Script::Compile(mote_code_string)->Run(); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3430 | 3434 |
| 3431 | 3435 |
| 3432 TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) { | 3436 TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) { |
| 3433 CcTest::InitializeVM(); | 3437 CcTest::InitializeVM(); |
| 3434 v8::HandleScope scope(CcTest::isolate()); | 3438 v8::HandleScope scope(CcTest::isolate()); |
| 3435 CompileRun("function f(n) {" | 3439 CompileRun("function f(n) {" |
| 3436 " var a = new Array(n);" | 3440 " var a = new Array(n);" |
| 3437 " for (var i = 0; i < n; i += 100) a[i] = i;" | 3441 " for (var i = 0; i < n; i += 100) a[i] = i;" |
| 3438 "};" | 3442 "};" |
| 3439 "f(10 * 1024 * 1024);"); | 3443 "f(10 * 1024 * 1024);"); |
| 3440 IncrementalMarking* marking = HEAP->incremental_marking(); | 3444 IncrementalMarking* marking = CcTest::heap()->incremental_marking(); |
| 3441 if (marking->IsStopped()) marking->Start(); | 3445 if (marking->IsStopped()) marking->Start(); |
| 3442 // This big step should be sufficient to mark the whole array. | 3446 // This big step should be sufficient to mark the whole array. |
| 3443 marking->Step(100 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | 3447 marking->Step(100 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 3444 ASSERT(marking->IsComplete()); | 3448 ASSERT(marking->IsComplete()); |
| 3445 } | 3449 } |
| OLD | NEW |