| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 | 2 |
| 3 #include <stdlib.h> | 3 #include <stdlib.h> |
| 4 | 4 |
| 5 #include "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "compilation-cache.h" | 7 #include "compilation-cache.h" |
| 8 #include "execution.h" | 8 #include "execution.h" |
| 9 #include "factory.h" | 9 #include "factory.h" |
| 10 #include "macro-assembler.h" | 10 #include "macro-assembler.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 | 51 |
| 52 TEST(HeapMaps) { | 52 TEST(HeapMaps) { |
| 53 InitializeVM(); | 53 InitializeVM(); |
| 54 CheckMap(HEAP->meta_map(), MAP_TYPE, Map::kSize); | 54 CheckMap(HEAP->meta_map(), MAP_TYPE, Map::kSize); |
| 55 CheckMap(HEAP->heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize); | 55 CheckMap(HEAP->heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize); |
| 56 CheckMap(HEAP->fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel); | 56 CheckMap(HEAP->fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel); |
| 57 CheckMap(HEAP->string_map(), STRING_TYPE, kVariableSizeSentinel); | 57 CheckMap(HEAP->string_map(), STRING_TYPE, kVariableSizeSentinel); |
| 58 } | 58 } |
| 59 | 59 |
| 60 | 60 |
| 61 static void CheckOddball(Object* obj, const char* string) { | 61 static void CheckOddball(Isolate* isolate, Object* obj, const char* string) { |
| 62 CHECK(obj->IsOddball()); | 62 CHECK(obj->IsOddball()); |
| 63 bool exc; | 63 bool exc; |
| 64 Object* print_string = *Execution::ToString(Handle<Object>(obj), &exc); | 64 Object* print_string = |
| 65 *Execution::ToString(Handle<Object>(obj, isolate), &exc); |
| 65 CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string))); | 66 CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string))); |
| 66 } | 67 } |
| 67 | 68 |
| 68 | 69 |
| 69 static void CheckSmi(int value, const char* string) { | 70 static void CheckSmi(Isolate* isolate, int value, const char* string) { |
| 70 bool exc; | 71 bool exc; |
| 71 Object* print_string = | 72 Object* print_string = |
| 72 *Execution::ToString(Handle<Object>(Smi::FromInt(value)), &exc); | 73 *Execution::ToString(Handle<Object>(Smi::FromInt(value), isolate), &exc); |
| 73 CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string))); | 74 CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string))); |
| 74 } | 75 } |
| 75 | 76 |
| 76 | 77 |
| 77 static void CheckNumber(double value, const char* string) { | 78 static void CheckNumber(Isolate* isolate, double value, const char* string) { |
| 78 Object* obj = HEAP->NumberFromDouble(value)->ToObjectChecked(); | 79 Object* obj = HEAP->NumberFromDouble(value)->ToObjectChecked(); |
| 79 CHECK(obj->IsNumber()); | 80 CHECK(obj->IsNumber()); |
| 80 bool exc; | 81 bool exc; |
| 81 Object* print_string = *Execution::ToString(Handle<Object>(obj), &exc); | 82 Object* print_string = |
| 83 *Execution::ToString(Handle<Object>(obj, isolate), &exc); |
| 82 CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string))); | 84 CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string))); |
| 83 } | 85 } |
| 84 | 86 |
| 85 | 87 |
| 86 static void CheckFindCodeObject() { | 88 static void CheckFindCodeObject(Isolate* isolate) { |
| 87 // Test FindCodeObject | 89 // Test FindCodeObject |
| 88 #define __ assm. | 90 #define __ assm. |
| 89 | 91 |
| 90 Assembler assm(Isolate::Current(), NULL, 0); | 92 Assembler assm(isolate, NULL, 0); |
| 91 | 93 |
| 92 __ nop(); // supported on all architectures | 94 __ nop(); // supported on all architectures |
| 93 | 95 |
| 94 CodeDesc desc; | 96 CodeDesc desc; |
| 95 assm.GetCode(&desc); | 97 assm.GetCode(&desc); |
| 96 Object* code = HEAP->CreateCode( | 98 Heap* heap = isolate->heap(); |
| 99 Object* code = heap->CreateCode( |
| 97 desc, | 100 desc, |
| 98 Code::ComputeFlags(Code::STUB), | 101 Code::ComputeFlags(Code::STUB), |
| 99 Handle<Object>(HEAP->undefined_value()))->ToObjectChecked(); | 102 Handle<Code>())->ToObjectChecked(); |
| 100 CHECK(code->IsCode()); | 103 CHECK(code->IsCode()); |
| 101 | 104 |
| 102 HeapObject* obj = HeapObject::cast(code); | 105 HeapObject* obj = HeapObject::cast(code); |
| 103 Address obj_addr = obj->address(); | 106 Address obj_addr = obj->address(); |
| 104 | 107 |
| 105 for (int i = 0; i < obj->Size(); i += kPointerSize) { | 108 for (int i = 0; i < obj->Size(); i += kPointerSize) { |
| 106 Object* found = HEAP->FindCodeObject(obj_addr + i); | 109 Object* found = heap->FindCodeObject(obj_addr + i); |
| 107 CHECK_EQ(code, found); | 110 CHECK_EQ(code, found); |
| 108 } | 111 } |
| 109 | 112 |
| 110 Object* copy = HEAP->CreateCode( | 113 Object* copy = heap->CreateCode( |
| 111 desc, | 114 desc, |
| 112 Code::ComputeFlags(Code::STUB), | 115 Code::ComputeFlags(Code::STUB), |
| 113 Handle<Object>(HEAP->undefined_value()))->ToObjectChecked(); | 116 Handle<Code>())->ToObjectChecked(); |
| 114 CHECK(copy->IsCode()); | 117 CHECK(copy->IsCode()); |
| 115 HeapObject* obj_copy = HeapObject::cast(copy); | 118 HeapObject* obj_copy = HeapObject::cast(copy); |
| 116 Object* not_right = HEAP->FindCodeObject(obj_copy->address() + | 119 Object* not_right = heap->FindCodeObject(obj_copy->address() + |
| 117 obj_copy->Size() / 2); | 120 obj_copy->Size() / 2); |
| 118 CHECK(not_right != code); | 121 CHECK(not_right != code); |
| 119 } | 122 } |
| 120 | 123 |
| 121 | 124 |
| 122 TEST(HeapObjects) { | 125 TEST(HeapObjects) { |
| 123 InitializeVM(); | 126 InitializeVM(); |
| 127 Isolate* isolate = Isolate::Current(); |
| 128 Heap* heap = isolate->heap(); |
| 124 | 129 |
| 125 v8::HandleScope sc; | 130 v8::HandleScope sc; |
| 126 Object* value = HEAP->NumberFromDouble(1.000123)->ToObjectChecked(); | 131 Object* value = heap->NumberFromDouble(1.000123)->ToObjectChecked(); |
| 127 CHECK(value->IsHeapNumber()); | 132 CHECK(value->IsHeapNumber()); |
| 128 CHECK(value->IsNumber()); | 133 CHECK(value->IsNumber()); |
| 129 CHECK_EQ(1.000123, value->Number()); | 134 CHECK_EQ(1.000123, value->Number()); |
| 130 | 135 |
| 131 value = HEAP->NumberFromDouble(1.0)->ToObjectChecked(); | 136 value = heap->NumberFromDouble(1.0)->ToObjectChecked(); |
| 132 CHECK(value->IsSmi()); | 137 CHECK(value->IsSmi()); |
| 133 CHECK(value->IsNumber()); | 138 CHECK(value->IsNumber()); |
| 134 CHECK_EQ(1.0, value->Number()); | 139 CHECK_EQ(1.0, value->Number()); |
| 135 | 140 |
| 136 value = HEAP->NumberFromInt32(1024)->ToObjectChecked(); | 141 value = heap->NumberFromInt32(1024)->ToObjectChecked(); |
| 137 CHECK(value->IsSmi()); | 142 CHECK(value->IsSmi()); |
| 138 CHECK(value->IsNumber()); | 143 CHECK(value->IsNumber()); |
| 139 CHECK_EQ(1024.0, value->Number()); | 144 CHECK_EQ(1024.0, value->Number()); |
| 140 | 145 |
| 141 value = HEAP->NumberFromInt32(Smi::kMinValue)->ToObjectChecked(); | 146 value = heap->NumberFromInt32(Smi::kMinValue)->ToObjectChecked(); |
| 142 CHECK(value->IsSmi()); | 147 CHECK(value->IsSmi()); |
| 143 CHECK(value->IsNumber()); | 148 CHECK(value->IsNumber()); |
| 144 CHECK_EQ(Smi::kMinValue, Smi::cast(value)->value()); | 149 CHECK_EQ(Smi::kMinValue, Smi::cast(value)->value()); |
| 145 | 150 |
| 146 value = HEAP->NumberFromInt32(Smi::kMaxValue)->ToObjectChecked(); | 151 value = heap->NumberFromInt32(Smi::kMaxValue)->ToObjectChecked(); |
| 147 CHECK(value->IsSmi()); | 152 CHECK(value->IsSmi()); |
| 148 CHECK(value->IsNumber()); | 153 CHECK(value->IsNumber()); |
| 149 CHECK_EQ(Smi::kMaxValue, Smi::cast(value)->value()); | 154 CHECK_EQ(Smi::kMaxValue, Smi::cast(value)->value()); |
| 150 | 155 |
| 151 #ifndef V8_TARGET_ARCH_X64 | 156 #ifndef V8_TARGET_ARCH_X64 |
| 152 // TODO(lrn): We need a NumberFromIntptr function in order to test this. | 157 // TODO(lrn): We need a NumberFromIntptr function in order to test this. |
| 153 value = HEAP->NumberFromInt32(Smi::kMinValue - 1)->ToObjectChecked(); | 158 value = heap->NumberFromInt32(Smi::kMinValue - 1)->ToObjectChecked(); |
| 154 CHECK(value->IsHeapNumber()); | 159 CHECK(value->IsHeapNumber()); |
| 155 CHECK(value->IsNumber()); | 160 CHECK(value->IsNumber()); |
| 156 CHECK_EQ(static_cast<double>(Smi::kMinValue - 1), value->Number()); | 161 CHECK_EQ(static_cast<double>(Smi::kMinValue - 1), value->Number()); |
| 157 #endif | 162 #endif |
| 158 | 163 |
| 159 MaybeObject* maybe_value = | 164 MaybeObject* maybe_value = |
| 160 HEAP->NumberFromUint32(static_cast<uint32_t>(Smi::kMaxValue) + 1); | 165 heap->NumberFromUint32(static_cast<uint32_t>(Smi::kMaxValue) + 1); |
| 161 value = maybe_value->ToObjectChecked(); | 166 value = maybe_value->ToObjectChecked(); |
| 162 CHECK(value->IsHeapNumber()); | 167 CHECK(value->IsHeapNumber()); |
| 163 CHECK(value->IsNumber()); | 168 CHECK(value->IsNumber()); |
| 164 CHECK_EQ(static_cast<double>(static_cast<uint32_t>(Smi::kMaxValue) + 1), | 169 CHECK_EQ(static_cast<double>(static_cast<uint32_t>(Smi::kMaxValue) + 1), |
| 165 value->Number()); | 170 value->Number()); |
| 166 | 171 |
| 167 maybe_value = HEAP->NumberFromUint32(static_cast<uint32_t>(1) << 31); | 172 maybe_value = heap->NumberFromUint32(static_cast<uint32_t>(1) << 31); |
| 168 value = maybe_value->ToObjectChecked(); | 173 value = maybe_value->ToObjectChecked(); |
| 169 CHECK(value->IsHeapNumber()); | 174 CHECK(value->IsHeapNumber()); |
| 170 CHECK(value->IsNumber()); | 175 CHECK(value->IsNumber()); |
| 171 CHECK_EQ(static_cast<double>(static_cast<uint32_t>(1) << 31), | 176 CHECK_EQ(static_cast<double>(static_cast<uint32_t>(1) << 31), |
| 172 value->Number()); | 177 value->Number()); |
| 173 | 178 |
| 174 // nan oddball checks | 179 // nan oddball checks |
| 175 CHECK(HEAP->nan_value()->IsNumber()); | 180 CHECK(heap->nan_value()->IsNumber()); |
| 176 CHECK(isnan(HEAP->nan_value()->Number())); | 181 CHECK(isnan(heap->nan_value()->Number())); |
| 177 | 182 |
| 178 Handle<String> s = FACTORY->NewStringFromAscii(CStrVector("fisk hest ")); | 183 Handle<String> s = FACTORY->NewStringFromAscii(CStrVector("fisk hest ")); |
| 179 CHECK(s->IsString()); | 184 CHECK(s->IsString()); |
| 180 CHECK_EQ(10, s->length()); | 185 CHECK_EQ(10, s->length()); |
| 181 | 186 |
| 182 String* object_symbol = String::cast(HEAP->Object_symbol()); | 187 String* object_symbol = String::cast(heap->Object_symbol()); |
| 183 CHECK( | 188 CHECK( |
| 184 Isolate::Current()->context()->global_object()->HasLocalProperty( | 189 Isolate::Current()->context()->global_object()->HasLocalProperty( |
| 185 object_symbol)); | 190 object_symbol)); |
| 186 | 191 |
| 187 // Check ToString for oddballs | 192 // Check ToString for oddballs |
| 188 CheckOddball(HEAP->true_value(), "true"); | 193 CheckOddball(isolate, heap->true_value(), "true"); |
| 189 CheckOddball(HEAP->false_value(), "false"); | 194 CheckOddball(isolate, heap->false_value(), "false"); |
| 190 CheckOddball(HEAP->null_value(), "null"); | 195 CheckOddball(isolate, heap->null_value(), "null"); |
| 191 CheckOddball(HEAP->undefined_value(), "undefined"); | 196 CheckOddball(isolate, heap->undefined_value(), "undefined"); |
| 192 | 197 |
| 193 // Check ToString for Smis | 198 // Check ToString for Smis |
| 194 CheckSmi(0, "0"); | 199 CheckSmi(isolate, 0, "0"); |
| 195 CheckSmi(42, "42"); | 200 CheckSmi(isolate, 42, "42"); |
| 196 CheckSmi(-42, "-42"); | 201 CheckSmi(isolate, -42, "-42"); |
| 197 | 202 |
| 198 // Check ToString for Numbers | 203 // Check ToString for Numbers |
| 199 CheckNumber(1.1, "1.1"); | 204 CheckNumber(isolate, 1.1, "1.1"); |
| 200 | 205 |
| 201 CheckFindCodeObject(); | 206 CheckFindCodeObject(isolate); |
| 202 } | 207 } |
| 203 | 208 |
| 204 | 209 |
| 205 TEST(Tagging) { | 210 TEST(Tagging) { |
| 206 InitializeVM(); | 211 InitializeVM(); |
| 207 int request = 24; | 212 int request = 24; |
| 208 CHECK_EQ(request, static_cast<int>(OBJECT_POINTER_ALIGN(request))); | 213 CHECK_EQ(request, static_cast<int>(OBJECT_POINTER_ALIGN(request))); |
| 209 CHECK(Smi::FromInt(42)->IsSmi()); | 214 CHECK(Smi::FromInt(42)->IsSmi()); |
| 210 CHECK(Failure::RetryAfterGC(NEW_SPACE)->IsFailure()); | 215 CHECK(Failure::RetryAfterGC(NEW_SPACE)->IsFailure()); |
| 211 CHECK_EQ(NEW_SPACE, | 216 CHECK_EQ(NEW_SPACE, |
| (...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 } | 1208 } |
| 1204 | 1209 |
| 1205 // Simulate incremental marking so that the function is enqueued as | 1210 // Simulate incremental marking so that the function is enqueued as |
| 1206 // code flushing candidate. | 1211 // code flushing candidate. |
| 1207 SimulateIncrementalMarking(); | 1212 SimulateIncrementalMarking(); |
| 1208 | 1213 |
| 1209 // Enable the debugger and add a breakpoint while incremental marking | 1214 // Enable the debugger and add a breakpoint while incremental marking |
| 1210 // is running so that incremental marking aborts and code flushing is | 1215 // is running so that incremental marking aborts and code flushing is |
| 1211 // disabled. | 1216 // disabled. |
| 1212 int position = 0; | 1217 int position = 0; |
| 1213 Handle<Object> breakpoint_object(Smi::FromInt(0)); | 1218 Handle<Object> breakpoint_object(Smi::FromInt(0), isolate); |
| 1214 isolate->debug()->SetBreakPoint(function, breakpoint_object, &position); | 1219 isolate->debug()->SetBreakPoint(function, breakpoint_object, &position); |
| 1215 isolate->debug()->ClearAllBreakPoints(); | 1220 isolate->debug()->ClearAllBreakPoints(); |
| 1216 | 1221 |
| 1217 // Force optimization now that code flushing is disabled. | 1222 // Force optimization now that code flushing is disabled. |
| 1218 { v8::HandleScope scope; | 1223 { v8::HandleScope scope; |
| 1219 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();"); | 1224 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();"); |
| 1220 } | 1225 } |
| 1221 | 1226 |
| 1222 // Simulate one final GC to make sure the candidate queue is sane. | 1227 // Simulate one final GC to make sure the candidate queue is sane. |
| 1223 heap->CollectAllGarbage(Heap::kNoGCFlags); | 1228 heap->CollectAllGarbage(Heap::kNoGCFlags); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1350 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1355 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 1351 CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts()); | 1356 CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts()); |
| 1352 } | 1357 } |
| 1353 | 1358 |
| 1354 CHECK_EQ(0, CountNativeContexts()); | 1359 CHECK_EQ(0, CountNativeContexts()); |
| 1355 } | 1360 } |
| 1356 | 1361 |
| 1357 | 1362 |
| 1358 // Count the number of native contexts in the weak list of native contexts | 1363 // Count the number of native contexts in the weak list of native contexts |
| 1359 // causing a GC after the specified number of elements. | 1364 // causing a GC after the specified number of elements. |
| 1360 static int CountNativeContextsWithGC(int n) { | 1365 static int CountNativeContextsWithGC(Isolate* isolate, int n) { |
| 1366 Heap* heap = isolate->heap(); |
| 1361 int count = 0; | 1367 int count = 0; |
| 1362 Handle<Object> object(HEAP->native_contexts_list()); | 1368 Handle<Object> object(heap->native_contexts_list(), isolate); |
| 1363 while (!object->IsUndefined()) { | 1369 while (!object->IsUndefined()) { |
| 1364 count++; | 1370 count++; |
| 1365 if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1371 if (count == n) heap->CollectAllGarbage(Heap::kNoGCFlags); |
| 1366 object = | 1372 object = |
| 1367 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK)); | 1373 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK), |
| 1374 isolate); |
| 1368 } | 1375 } |
| 1369 return count; | 1376 return count; |
| 1370 } | 1377 } |
| 1371 | 1378 |
| 1372 | 1379 |
| 1373 // Count the number of user functions in the weak list of optimized | 1380 // Count the number of user functions in the weak list of optimized |
| 1374 // functions attached to a native context causing a GC after the | 1381 // functions attached to a native context causing a GC after the |
| 1375 // specified number of elements. | 1382 // specified number of elements. |
| 1376 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context, | 1383 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context, |
| 1377 int n) { | 1384 int n) { |
| 1378 int count = 0; | 1385 int count = 0; |
| 1379 Handle<Context> icontext = v8::Utils::OpenHandle(*context); | 1386 Handle<Context> icontext = v8::Utils::OpenHandle(*context); |
| 1380 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST)); | 1387 Isolate* isolate = icontext->GetIsolate(); |
| 1388 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST), |
| 1389 isolate); |
| 1381 while (object->IsJSFunction() && | 1390 while (object->IsJSFunction() && |
| 1382 !Handle<JSFunction>::cast(object)->IsBuiltin()) { | 1391 !Handle<JSFunction>::cast(object)->IsBuiltin()) { |
| 1383 count++; | 1392 count++; |
| 1384 if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1393 if (count == n) isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1385 object = Handle<Object>( | 1394 object = Handle<Object>( |
| 1386 Object::cast(JSFunction::cast(*object)->next_function_link())); | 1395 Object::cast(JSFunction::cast(*object)->next_function_link()), |
| 1396 isolate); |
| 1387 } | 1397 } |
| 1388 return count; | 1398 return count; |
| 1389 } | 1399 } |
| 1390 | 1400 |
| 1391 | 1401 |
| 1392 TEST(TestInternalWeakListsTraverseWithGC) { | 1402 TEST(TestInternalWeakListsTraverseWithGC) { |
| 1393 v8::V8::Initialize(); | 1403 v8::V8::Initialize(); |
| 1404 Isolate* isolate = Isolate::Current(); |
| 1394 | 1405 |
| 1395 static const int kNumTestContexts = 10; | 1406 static const int kNumTestContexts = 10; |
| 1396 | 1407 |
| 1397 v8::HandleScope scope; | 1408 v8::HandleScope scope; |
| 1398 v8::Persistent<v8::Context> ctx[kNumTestContexts]; | 1409 v8::Persistent<v8::Context> ctx[kNumTestContexts]; |
| 1399 | 1410 |
| 1400 CHECK_EQ(0, CountNativeContexts()); | 1411 CHECK_EQ(0, CountNativeContexts()); |
| 1401 | 1412 |
| 1402 // Create an number of contexts and check the length of the weak list both | 1413 // Create an number of contexts and check the length of the weak list both |
| 1403 // with and without GCs while iterating the list. | 1414 // with and without GCs while iterating the list. |
| 1404 for (int i = 0; i < kNumTestContexts; i++) { | 1415 for (int i = 0; i < kNumTestContexts; i++) { |
| 1405 ctx[i] = v8::Context::New(); | 1416 ctx[i] = v8::Context::New(); |
| 1406 CHECK_EQ(i + 1, CountNativeContexts()); | 1417 CHECK_EQ(i + 1, CountNativeContexts()); |
| 1407 CHECK_EQ(i + 1, CountNativeContextsWithGC(i / 2 + 1)); | 1418 CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1)); |
| 1408 } | 1419 } |
| 1409 | 1420 |
| 1410 bool opt = (FLAG_always_opt && i::V8::UseCrankshaft()); | 1421 bool opt = (FLAG_always_opt && i::V8::UseCrankshaft()); |
| 1411 | 1422 |
| 1412 // Compile a number of functions the length of the weak list of optimized | 1423 // Compile a number of functions the length of the weak list of optimized |
| 1413 // functions both with and without GCs while iterating the list. | 1424 // functions both with and without GCs while iterating the list. |
| 1414 ctx[0]->Enter(); | 1425 ctx[0]->Enter(); |
| 1415 const char* source = "function f1() { };" | 1426 const char* source = "function f1() { };" |
| 1416 "function f2() { };" | 1427 "function f2() { };" |
| 1417 "function f3() { };" | 1428 "function f3() { };" |
| (...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2480 " error = e; " | 2491 " error = e; " |
| 2481 "} "; | 2492 "} "; |
| 2482 ReleaseStackTraceDataTest(source1); | 2493 ReleaseStackTraceDataTest(source1); |
| 2483 ReleaseStackTraceDataTest(source2); | 2494 ReleaseStackTraceDataTest(source2); |
| 2484 } | 2495 } |
| 2485 | 2496 |
| 2486 | 2497 |
| 2487 TEST(Regression144230) { | 2498 TEST(Regression144230) { |
| 2488 InitializeVM(); | 2499 InitializeVM(); |
| 2489 Isolate* isolate = Isolate::Current(); | 2500 Isolate* isolate = Isolate::Current(); |
| 2501 Heap* heap = isolate->heap(); |
| 2490 v8::HandleScope scope; | 2502 v8::HandleScope scope; |
| 2491 | 2503 |
| 2492 // First make sure that the uninitialized CallIC stub is on a single page | 2504 // First make sure that the uninitialized CallIC stub is on a single page |
| 2493 // that will later be selected as an evacuation candidate. | 2505 // that will later be selected as an evacuation candidate. |
| 2494 { | 2506 { |
| 2495 v8::HandleScope inner_scope; | 2507 v8::HandleScope inner_scope; |
| 2496 AlwaysAllocateScope always_allocate; | 2508 AlwaysAllocateScope always_allocate; |
| 2497 SimulateFullSpace(HEAP->code_space()); | 2509 SimulateFullSpace(heap->code_space()); |
| 2498 isolate->stub_cache()->ComputeCallInitialize(9, RelocInfo::CODE_TARGET); | 2510 isolate->stub_cache()->ComputeCallInitialize(9, RelocInfo::CODE_TARGET); |
| 2499 } | 2511 } |
| 2500 | 2512 |
| 2501 // Second compile a CallIC and execute it once so that it gets patched to | 2513 // Second compile a CallIC and execute it once so that it gets patched to |
| 2502 // the pre-monomorphic stub. These code objects are on yet another page. | 2514 // the pre-monomorphic stub. These code objects are on yet another page. |
| 2503 { | 2515 { |
| 2504 v8::HandleScope inner_scope; | 2516 v8::HandleScope inner_scope; |
| 2505 AlwaysAllocateScope always_allocate; | 2517 AlwaysAllocateScope always_allocate; |
| 2506 SimulateFullSpace(HEAP->code_space()); | 2518 SimulateFullSpace(heap->code_space()); |
| 2507 CompileRun("var o = { f:function(a,b,c,d,e,f,g,h,i) {}};" | 2519 CompileRun("var o = { f:function(a,b,c,d,e,f,g,h,i) {}};" |
| 2508 "function call() { o.f(1,2,3,4,5,6,7,8,9); };" | 2520 "function call() { o.f(1,2,3,4,5,6,7,8,9); };" |
| 2509 "call();"); | 2521 "call();"); |
| 2510 } | 2522 } |
| 2511 | 2523 |
| 2512 // Third we fill up the last page of the code space so that it does not get | 2524 // Third we fill up the last page of the code space so that it does not get |
| 2513 // chosen as an evacuation candidate. | 2525 // chosen as an evacuation candidate. |
| 2514 { | 2526 { |
| 2515 v8::HandleScope inner_scope; | 2527 v8::HandleScope inner_scope; |
| 2516 AlwaysAllocateScope always_allocate; | 2528 AlwaysAllocateScope always_allocate; |
| 2517 CompileRun("for (var i = 0; i < 2000; i++) {" | 2529 CompileRun("for (var i = 0; i < 2000; i++) {" |
| 2518 " eval('function f' + i + '() { return ' + i +'; };' +" | 2530 " eval('function f' + i + '() { return ' + i +'; };' +" |
| 2519 " 'f' + i + '();');" | 2531 " 'f' + i + '();');" |
| 2520 "}"); | 2532 "}"); |
| 2521 } | 2533 } |
| 2522 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2534 heap->CollectAllGarbage(Heap::kNoGCFlags); |
| 2523 | 2535 |
| 2524 // Fourth is the tricky part. Make sure the code containing the CallIC is | 2536 // Fourth is the tricky part. Make sure the code containing the CallIC is |
| 2525 // visited first without clearing the IC. The shared function info is then | 2537 // visited first without clearing the IC. The shared function info is then |
| 2526 // visited later, causing the CallIC to be cleared. | 2538 // visited later, causing the CallIC to be cleared. |
| 2527 Handle<String> name = FACTORY->LookupUtf8Symbol("call"); | 2539 Handle<String> name = FACTORY->LookupUtf8Symbol("call"); |
| 2528 Handle<GlobalObject> global(isolate->context()->global_object()); | 2540 Handle<GlobalObject> global(isolate->context()->global_object()); |
| 2529 MaybeObject* maybe_call = global->GetProperty(*name); | 2541 MaybeObject* maybe_call = global->GetProperty(*name); |
| 2530 JSFunction* call = JSFunction::cast(maybe_call->ToObjectChecked()); | 2542 JSFunction* call = JSFunction::cast(maybe_call->ToObjectChecked()); |
| 2531 USE(global->SetProperty(*name, Smi::FromInt(0), NONE, kNonStrictMode)); | 2543 USE(global->SetProperty(*name, Smi::FromInt(0), NONE, kNonStrictMode)); |
| 2532 isolate->compilation_cache()->Clear(); | 2544 isolate->compilation_cache()->Clear(); |
| 2533 call->shared()->set_ic_age(HEAP->global_ic_age() + 1); | 2545 call->shared()->set_ic_age(heap->global_ic_age() + 1); |
| 2534 Handle<Object> call_code(call->code()); | 2546 Handle<Object> call_code(call->code(), isolate); |
| 2535 Handle<Object> call_function(call); | 2547 Handle<Object> call_function(call, isolate); |
| 2536 | 2548 |
| 2537 // Now we are ready to mess up the heap. | 2549 // Now we are ready to mess up the heap. |
| 2538 HEAP->CollectAllGarbage(Heap::kReduceMemoryFootprintMask); | 2550 heap->CollectAllGarbage(Heap::kReduceMemoryFootprintMask); |
| 2539 | 2551 |
| 2540 // Either heap verification caught the problem already or we go kaboom once | 2552 // Either heap verification caught the problem already or we go kaboom once |
| 2541 // the CallIC is executed the next time. | 2553 // the CallIC is executed the next time. |
| 2542 USE(global->SetProperty(*name, *call_function, NONE, kNonStrictMode)); | 2554 USE(global->SetProperty(*name, *call_function, NONE, kNonStrictMode)); |
| 2543 CompileRun("call();"); | 2555 CompileRun("call();"); |
| 2544 } | 2556 } |
| 2545 | 2557 |
| 2546 | 2558 |
| 2547 TEST(Regress159140) { | 2559 TEST(Regress159140) { |
| 2548 i::FLAG_allow_natives_syntax = true; | 2560 i::FLAG_allow_natives_syntax = true; |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2911 // explicitly enqueued. | 2923 // explicitly enqueued. |
| 2912 SimulateIncrementalMarking(); | 2924 SimulateIncrementalMarking(); |
| 2913 | 2925 |
| 2914 // Now enable the debugger which in turn will disable code flushing. | 2926 // Now enable the debugger which in turn will disable code flushing. |
| 2915 CHECK(isolate->debug()->Load()); | 2927 CHECK(isolate->debug()->Load()); |
| 2916 | 2928 |
| 2917 // This cycle will bust the heap and subsequent cycles will go ballistic. | 2929 // This cycle will bust the heap and subsequent cycles will go ballistic. |
| 2918 heap->CollectAllGarbage(Heap::kNoGCFlags); | 2930 heap->CollectAllGarbage(Heap::kNoGCFlags); |
| 2919 heap->CollectAllGarbage(Heap::kNoGCFlags); | 2931 heap->CollectAllGarbage(Heap::kNoGCFlags); |
| 2920 } | 2932 } |
| OLD | NEW |