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