| 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 28 matching lines...) Expand all Loading... |
| 141 CHECK(copy->IsCode()); | 142 CHECK(copy->IsCode()); |
| 142 HeapObject* obj_copy = HeapObject::cast(copy); | 143 HeapObject* obj_copy = HeapObject::cast(copy); |
| 143 Object* not_right = isolate->FindCodeObject(obj_copy->address() + | 144 Object* not_right = isolate->FindCodeObject(obj_copy->address() + |
| 144 obj_copy->Size() / 2); | 145 obj_copy->Size() / 2); |
| 145 CHECK(not_right != code); | 146 CHECK(not_right != code); |
| 146 } | 147 } |
| 147 | 148 |
| 148 | 149 |
| 149 TEST(HeapObjects) { | 150 TEST(HeapObjects) { |
| 150 CcTest::InitializeVM(); | 151 CcTest::InitializeVM(); |
| 151 Isolate* isolate = Isolate::Current(); | 152 Isolate* isolate = CcTest::i_isolate(); |
| 152 Factory* factory = isolate->factory(); | 153 Factory* factory = isolate->factory(); |
| 153 Heap* heap = isolate->heap(); | 154 Heap* heap = isolate->heap(); |
| 154 | 155 |
| 155 HandleScope sc(isolate); | 156 HandleScope sc(isolate); |
| 156 Object* value = heap->NumberFromDouble(1.000123)->ToObjectChecked(); | 157 Object* value = heap->NumberFromDouble(1.000123)->ToObjectChecked(); |
| 157 CHECK(value->IsHeapNumber()); | 158 CHECK(value->IsHeapNumber()); |
| 158 CHECK(value->IsNumber()); | 159 CHECK(value->IsNumber()); |
| 159 CHECK_EQ(1.000123, value->Number()); | 160 CHECK_EQ(1.000123, value->Number()); |
| 160 | 161 |
| 161 value = heap->NumberFromDouble(1.0)->ToObjectChecked(); | 162 value = heap->NumberFromDouble(1.0)->ToObjectChecked(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 value->Number()); | 203 value->Number()); |
| 203 | 204 |
| 204 // nan oddball checks | 205 // nan oddball checks |
| 205 CHECK(heap->nan_value()->IsNumber()); | 206 CHECK(heap->nan_value()->IsNumber()); |
| 206 CHECK(std::isnan(heap->nan_value()->Number())); | 207 CHECK(std::isnan(heap->nan_value()->Number())); |
| 207 | 208 |
| 208 Handle<String> s = factory->NewStringFromAscii(CStrVector("fisk hest ")); | 209 Handle<String> s = factory->NewStringFromAscii(CStrVector("fisk hest ")); |
| 209 CHECK(s->IsString()); | 210 CHECK(s->IsString()); |
| 210 CHECK_EQ(10, s->length()); | 211 CHECK_EQ(10, s->length()); |
| 211 | 212 |
| 212 String* object_string = String::cast(heap->Object_string()); | 213 Handle<String> object_string = Handle<String>::cast(factory->Object_string()); |
| 213 CHECK( | 214 Handle<GlobalObject> global(CcTest::i_isolate()->context()->global_object()); |
| 214 Isolate::Current()->context()->global_object()->HasLocalProperty( | 215 CHECK(JSReceiver::HasLocalProperty(global, object_string)); |
| 215 object_string)); | |
| 216 | 216 |
| 217 // Check ToString for oddballs | 217 // Check ToString for oddballs |
| 218 CheckOddball(isolate, heap->true_value(), "true"); | 218 CheckOddball(isolate, heap->true_value(), "true"); |
| 219 CheckOddball(isolate, heap->false_value(), "false"); | 219 CheckOddball(isolate, heap->false_value(), "false"); |
| 220 CheckOddball(isolate, heap->null_value(), "null"); | 220 CheckOddball(isolate, heap->null_value(), "null"); |
| 221 CheckOddball(isolate, heap->undefined_value(), "undefined"); | 221 CheckOddball(isolate, heap->undefined_value(), "undefined"); |
| 222 | 222 |
| 223 // Check ToString for Smis | 223 // Check ToString for Smis |
| 224 CheckSmi(isolate, 0, "0"); | 224 CheckSmi(isolate, 0, "0"); |
| 225 CheckSmi(isolate, 42, "42"); | 225 CheckSmi(isolate, 42, "42"); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 243 CHECK_EQ(OLD_POINTER_SPACE, | 243 CHECK_EQ(OLD_POINTER_SPACE, |
| 244 Failure::RetryAfterGC(OLD_POINTER_SPACE)->allocation_space()); | 244 Failure::RetryAfterGC(OLD_POINTER_SPACE)->allocation_space()); |
| 245 CHECK(Failure::Exception()->IsFailure()); | 245 CHECK(Failure::Exception()->IsFailure()); |
| 246 CHECK(Smi::FromInt(Smi::kMinValue)->IsSmi()); | 246 CHECK(Smi::FromInt(Smi::kMinValue)->IsSmi()); |
| 247 CHECK(Smi::FromInt(Smi::kMaxValue)->IsSmi()); | 247 CHECK(Smi::FromInt(Smi::kMaxValue)->IsSmi()); |
| 248 } | 248 } |
| 249 | 249 |
| 250 | 250 |
| 251 TEST(GarbageCollection) { | 251 TEST(GarbageCollection) { |
| 252 CcTest::InitializeVM(); | 252 CcTest::InitializeVM(); |
| 253 Isolate* isolate = Isolate::Current(); | 253 Isolate* isolate = CcTest::i_isolate(); |
| 254 Heap* heap = isolate->heap(); | 254 Heap* heap = isolate->heap(); |
| 255 Factory* factory = isolate->factory(); | 255 Factory* factory = isolate->factory(); |
| 256 | 256 |
| 257 HandleScope sc(isolate); | 257 HandleScope sc(isolate); |
| 258 // Check GC. | 258 // Check GC. |
| 259 heap->CollectGarbage(NEW_SPACE); | 259 heap->CollectGarbage(NEW_SPACE); |
| 260 | 260 |
| 261 Handle<GlobalObject> global(CcTest::i_isolate()->context()->global_object()); |
| 261 Handle<String> name = factory->InternalizeUtf8String("theFunction"); | 262 Handle<String> name = factory->InternalizeUtf8String("theFunction"); |
| 262 Handle<String> prop_name = factory->InternalizeUtf8String("theSlot"); | 263 Handle<String> prop_name = factory->InternalizeUtf8String("theSlot"); |
| 263 Handle<String> prop_namex = factory->InternalizeUtf8String("theSlotx"); | 264 Handle<String> prop_namex = factory->InternalizeUtf8String("theSlotx"); |
| 264 Handle<String> obj_name = factory->InternalizeUtf8String("theObject"); | 265 Handle<String> obj_name = factory->InternalizeUtf8String("theObject"); |
| 266 Handle<Smi> twenty_three(Smi::FromInt(23), isolate); |
| 267 Handle<Smi> twenty_four(Smi::FromInt(24), isolate); |
| 265 | 268 |
| 266 { | 269 { |
| 267 HandleScope inner_scope(isolate); | 270 HandleScope inner_scope(isolate); |
| 268 // Allocate a function and keep it in global object's property. | 271 // Allocate a function and keep it in global object's property. |
| 269 Handle<JSFunction> function = | 272 Handle<JSFunction> function = |
| 270 factory->NewFunction(name, factory->undefined_value()); | 273 factory->NewFunction(name, factory->undefined_value()); |
| 271 Handle<Map> initial_map = | 274 Handle<Map> initial_map = |
| 272 factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 275 factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
| 273 function->set_initial_map(*initial_map); | 276 function->set_initial_map(*initial_map); |
| 274 Isolate::Current()->context()->global_object()->SetProperty( | 277 JSReceiver::SetProperty(global, name, function, NONE, kNonStrictMode); |
| 275 *name, *function, NONE, kNonStrictMode)->ToObjectChecked(); | |
| 276 // Allocate an object. Unrooted after leaving the scope. | 278 // Allocate an object. Unrooted after leaving the scope. |
| 277 Handle<JSObject> obj = factory->NewJSObject(function); | 279 Handle<JSObject> obj = factory->NewJSObject(function); |
| 278 obj->SetProperty( | 280 JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode); |
| 279 *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked(); | 281 JSReceiver::SetProperty(obj, prop_namex, twenty_four, NONE, kNonStrictMode); |
| 280 obj->SetProperty( | |
| 281 *prop_namex, Smi::FromInt(24), NONE, kNonStrictMode)->ToObjectChecked(); | |
| 282 | 282 |
| 283 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); | 283 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); |
| 284 CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex)); | 284 CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex)); |
| 285 } | 285 } |
| 286 | 286 |
| 287 heap->CollectGarbage(NEW_SPACE); | 287 heap->CollectGarbage(NEW_SPACE); |
| 288 | 288 |
| 289 // Function should be alive. | 289 // Function should be alive. |
| 290 CHECK(Isolate::Current()->context()->global_object()-> | 290 CHECK(JSReceiver::HasLocalProperty(global, name)); |
| 291 HasLocalProperty(*name)); | |
| 292 // Check function is retained. | 291 // Check function is retained. |
| 293 Object* func_value = Isolate::Current()->context()->global_object()-> | 292 Object* func_value = CcTest::i_isolate()->context()->global_object()-> |
| 294 GetProperty(*name)->ToObjectChecked(); | 293 GetProperty(*name)->ToObjectChecked(); |
| 295 CHECK(func_value->IsJSFunction()); | 294 CHECK(func_value->IsJSFunction()); |
| 296 Handle<JSFunction> function(JSFunction::cast(func_value)); | 295 Handle<JSFunction> function(JSFunction::cast(func_value)); |
| 297 | 296 |
| 298 { | 297 { |
| 299 HandleScope inner_scope(isolate); | 298 HandleScope inner_scope(isolate); |
| 300 // Allocate another object, make it reachable from global. | 299 // Allocate another object, make it reachable from global. |
| 301 Handle<JSObject> obj = factory->NewJSObject(function); | 300 Handle<JSObject> obj = factory->NewJSObject(function); |
| 302 Isolate::Current()->context()->global_object()->SetProperty( | 301 JSReceiver::SetProperty(global, obj_name, obj, NONE, kNonStrictMode); |
| 303 *obj_name, *obj, NONE, kNonStrictMode)->ToObjectChecked(); | 302 JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode); |
| 304 obj->SetProperty( | |
| 305 *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked(); | |
| 306 } | 303 } |
| 307 | 304 |
| 308 // After gc, it should survive. | 305 // After gc, it should survive. |
| 309 heap->CollectGarbage(NEW_SPACE); | 306 heap->CollectGarbage(NEW_SPACE); |
| 310 | 307 |
| 311 CHECK(Isolate::Current()->context()->global_object()-> | 308 CHECK(JSReceiver::HasLocalProperty(global, obj_name)); |
| 312 HasLocalProperty(*obj_name)); | 309 CHECK(CcTest::i_isolate()->context()->global_object()-> |
| 313 CHECK(Isolate::Current()->context()->global_object()-> | |
| 314 GetProperty(*obj_name)->ToObjectChecked()->IsJSObject()); | 310 GetProperty(*obj_name)->ToObjectChecked()->IsJSObject()); |
| 315 Object* obj = Isolate::Current()->context()->global_object()-> | 311 Object* obj = CcTest::i_isolate()->context()->global_object()-> |
| 316 GetProperty(*obj_name)->ToObjectChecked(); | 312 GetProperty(*obj_name)->ToObjectChecked(); |
| 317 JSObject* js_obj = JSObject::cast(obj); | 313 JSObject* js_obj = JSObject::cast(obj); |
| 318 CHECK_EQ(Smi::FromInt(23), js_obj->GetProperty(*prop_name)); | 314 CHECK_EQ(Smi::FromInt(23), js_obj->GetProperty(*prop_name)); |
| 319 } | 315 } |
| 320 | 316 |
| 321 | 317 |
| 322 static void VerifyStringAllocation(Isolate* isolate, const char* string) { | 318 static void VerifyStringAllocation(Isolate* isolate, const char* string) { |
| 323 HandleScope scope(isolate); | 319 HandleScope scope(isolate); |
| 324 Handle<String> s = isolate->factory()->NewStringFromUtf8(CStrVector(string)); | 320 Handle<String> s = isolate->factory()->NewStringFromUtf8(CStrVector(string)); |
| 325 CHECK_EQ(StrLength(string), s->length()); | 321 CHECK_EQ(StrLength(string), s->length()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 336 VerifyStringAllocation(isolate, "a"); | 332 VerifyStringAllocation(isolate, "a"); |
| 337 VerifyStringAllocation(isolate, "ab"); | 333 VerifyStringAllocation(isolate, "ab"); |
| 338 VerifyStringAllocation(isolate, "abc"); | 334 VerifyStringAllocation(isolate, "abc"); |
| 339 VerifyStringAllocation(isolate, "abcd"); | 335 VerifyStringAllocation(isolate, "abcd"); |
| 340 VerifyStringAllocation(isolate, "fiskerdrengen er paa havet"); | 336 VerifyStringAllocation(isolate, "fiskerdrengen er paa havet"); |
| 341 } | 337 } |
| 342 | 338 |
| 343 | 339 |
| 344 TEST(LocalHandles) { | 340 TEST(LocalHandles) { |
| 345 CcTest::InitializeVM(); | 341 CcTest::InitializeVM(); |
| 346 Isolate* isolate = Isolate::Current(); | 342 Isolate* isolate = CcTest::i_isolate(); |
| 347 Factory* factory = isolate->factory(); | 343 Factory* factory = isolate->factory(); |
| 348 | 344 |
| 349 v8::HandleScope scope(CcTest::isolate()); | 345 v8::HandleScope scope(CcTest::isolate()); |
| 350 const char* name = "Kasper the spunky"; | 346 const char* name = "Kasper the spunky"; |
| 351 Handle<String> string = factory->NewStringFromAscii(CStrVector(name)); | 347 Handle<String> string = factory->NewStringFromAscii(CStrVector(name)); |
| 352 CHECK_EQ(StrLength(name), string->length()); | 348 CHECK_EQ(StrLength(name), string->length()); |
| 353 } | 349 } |
| 354 | 350 |
| 355 | 351 |
| 356 TEST(GlobalHandles) { | 352 TEST(GlobalHandles) { |
| 357 CcTest::InitializeVM(); | 353 CcTest::InitializeVM(); |
| 358 Isolate* isolate = Isolate::Current(); | 354 Isolate* isolate = CcTest::i_isolate(); |
| 359 Heap* heap = isolate->heap(); | 355 Heap* heap = isolate->heap(); |
| 360 Factory* factory = isolate->factory(); | 356 Factory* factory = isolate->factory(); |
| 361 GlobalHandles* global_handles = isolate->global_handles(); | 357 GlobalHandles* global_handles = isolate->global_handles(); |
| 362 | 358 |
| 363 Handle<Object> h1; | 359 Handle<Object> h1; |
| 364 Handle<Object> h2; | 360 Handle<Object> h2; |
| 365 Handle<Object> h3; | 361 Handle<Object> h3; |
| 366 Handle<Object> h4; | 362 Handle<Object> h4; |
| 367 | 363 |
| 368 { | 364 { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 v8::Persistent<v8::Value>* handle, | 397 v8::Persistent<v8::Value>* handle, |
| 402 void* id) { | 398 void* id) { |
| 403 if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true; | 399 if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true; |
| 404 handle->Dispose(); | 400 handle->Dispose(); |
| 405 } | 401 } |
| 406 | 402 |
| 407 | 403 |
| 408 TEST(WeakGlobalHandlesScavenge) { | 404 TEST(WeakGlobalHandlesScavenge) { |
| 409 i::FLAG_stress_compaction = false; | 405 i::FLAG_stress_compaction = false; |
| 410 CcTest::InitializeVM(); | 406 CcTest::InitializeVM(); |
| 411 Isolate* isolate = Isolate::Current(); | 407 Isolate* isolate = CcTest::i_isolate(); |
| 412 Heap* heap = isolate->heap(); | 408 Heap* heap = isolate->heap(); |
| 413 Factory* factory = isolate->factory(); | 409 Factory* factory = isolate->factory(); |
| 414 GlobalHandles* global_handles = isolate->global_handles(); | 410 GlobalHandles* global_handles = isolate->global_handles(); |
| 415 | 411 |
| 416 WeakPointerCleared = false; | 412 WeakPointerCleared = false; |
| 417 | 413 |
| 418 Handle<Object> h1; | 414 Handle<Object> h1; |
| 419 Handle<Object> h2; | 415 Handle<Object> h2; |
| 420 | 416 |
| 421 { | 417 { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 442 CHECK(!global_handles->IsNearDeath(h2.location())); | 438 CHECK(!global_handles->IsNearDeath(h2.location())); |
| 443 CHECK(!global_handles->IsNearDeath(h1.location())); | 439 CHECK(!global_handles->IsNearDeath(h1.location())); |
| 444 | 440 |
| 445 global_handles->Destroy(h1.location()); | 441 global_handles->Destroy(h1.location()); |
| 446 global_handles->Destroy(h2.location()); | 442 global_handles->Destroy(h2.location()); |
| 447 } | 443 } |
| 448 | 444 |
| 449 | 445 |
| 450 TEST(WeakGlobalHandlesMark) { | 446 TEST(WeakGlobalHandlesMark) { |
| 451 CcTest::InitializeVM(); | 447 CcTest::InitializeVM(); |
| 452 Isolate* isolate = Isolate::Current(); | 448 Isolate* isolate = CcTest::i_isolate(); |
| 453 Heap* heap = isolate->heap(); | 449 Heap* heap = isolate->heap(); |
| 454 Factory* factory = isolate->factory(); | 450 Factory* factory = isolate->factory(); |
| 455 GlobalHandles* global_handles = isolate->global_handles(); | 451 GlobalHandles* global_handles = isolate->global_handles(); |
| 456 | 452 |
| 457 WeakPointerCleared = false; | 453 WeakPointerCleared = false; |
| 458 | 454 |
| 459 Handle<Object> h1; | 455 Handle<Object> h1; |
| 460 Handle<Object> h2; | 456 Handle<Object> h2; |
| 461 | 457 |
| 462 { | 458 { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 488 CHECK(WeakPointerCleared); | 484 CHECK(WeakPointerCleared); |
| 489 CHECK(!GlobalHandles::IsNearDeath(h1.location())); | 485 CHECK(!GlobalHandles::IsNearDeath(h1.location())); |
| 490 | 486 |
| 491 global_handles->Destroy(h1.location()); | 487 global_handles->Destroy(h1.location()); |
| 492 } | 488 } |
| 493 | 489 |
| 494 | 490 |
| 495 TEST(DeleteWeakGlobalHandle) { | 491 TEST(DeleteWeakGlobalHandle) { |
| 496 i::FLAG_stress_compaction = false; | 492 i::FLAG_stress_compaction = false; |
| 497 CcTest::InitializeVM(); | 493 CcTest::InitializeVM(); |
| 498 Isolate* isolate = Isolate::Current(); | 494 Isolate* isolate = CcTest::i_isolate(); |
| 499 Heap* heap = isolate->heap(); | 495 Heap* heap = isolate->heap(); |
| 500 Factory* factory = isolate->factory(); | 496 Factory* factory = isolate->factory(); |
| 501 GlobalHandles* global_handles = isolate->global_handles(); | 497 GlobalHandles* global_handles = isolate->global_handles(); |
| 502 | 498 |
| 503 WeakPointerCleared = false; | 499 WeakPointerCleared = false; |
| 504 | 500 |
| 505 Handle<Object> h; | 501 Handle<Object> h; |
| 506 | 502 |
| 507 { | 503 { |
| 508 HandleScope scope(isolate); | 504 HandleScope scope(isolate); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 "volatile", | 583 "volatile", |
| 588 "while", | 584 "while", |
| 589 "with", | 585 "with", |
| 590 0 | 586 0 |
| 591 }; | 587 }; |
| 592 | 588 |
| 593 | 589 |
| 594 static void CheckInternalizedStrings(const char** strings) { | 590 static void CheckInternalizedStrings(const char** strings) { |
| 595 for (const char* string = *strings; *strings != 0; string = *strings++) { | 591 for (const char* string = *strings; *strings != 0; string = *strings++) { |
| 596 Object* a; | 592 Object* a; |
| 597 MaybeObject* maybe_a = HEAP->InternalizeUtf8String(string); | 593 MaybeObject* maybe_a = CcTest::heap()->InternalizeUtf8String(string); |
| 598 // InternalizeUtf8String may return a failure if a GC is needed. | 594 // InternalizeUtf8String may return a failure if a GC is needed. |
| 599 if (!maybe_a->ToObject(&a)) continue; | 595 if (!maybe_a->ToObject(&a)) continue; |
| 600 CHECK(a->IsInternalizedString()); | 596 CHECK(a->IsInternalizedString()); |
| 601 Object* b; | 597 Object* b; |
| 602 MaybeObject* maybe_b = HEAP->InternalizeUtf8String(string); | 598 MaybeObject* maybe_b = CcTest::heap()->InternalizeUtf8String(string); |
| 603 if (!maybe_b->ToObject(&b)) continue; | 599 if (!maybe_b->ToObject(&b)) continue; |
| 604 CHECK_EQ(b, a); | 600 CHECK_EQ(b, a); |
| 605 CHECK(String::cast(b)->IsUtf8EqualTo(CStrVector(string))); | 601 CHECK(String::cast(b)->IsUtf8EqualTo(CStrVector(string))); |
| 606 } | 602 } |
| 607 } | 603 } |
| 608 | 604 |
| 609 | 605 |
| 610 TEST(StringTable) { | 606 TEST(StringTable) { |
| 611 CcTest::InitializeVM(); | 607 CcTest::InitializeVM(); |
| 612 | 608 |
| 613 CheckInternalizedStrings(not_so_random_string_table); | 609 CheckInternalizedStrings(not_so_random_string_table); |
| 614 CheckInternalizedStrings(not_so_random_string_table); | 610 CheckInternalizedStrings(not_so_random_string_table); |
| 615 } | 611 } |
| 616 | 612 |
| 617 | 613 |
| 618 TEST(FunctionAllocation) { | 614 TEST(FunctionAllocation) { |
| 619 CcTest::InitializeVM(); | 615 CcTest::InitializeVM(); |
| 620 Isolate* isolate = Isolate::Current(); | 616 Isolate* isolate = CcTest::i_isolate(); |
| 621 Factory* factory = isolate->factory(); | 617 Factory* factory = isolate->factory(); |
| 622 | 618 |
| 623 v8::HandleScope sc(CcTest::isolate()); | 619 v8::HandleScope sc(CcTest::isolate()); |
| 624 Handle<String> name = factory->InternalizeUtf8String("theFunction"); | 620 Handle<String> name = factory->InternalizeUtf8String("theFunction"); |
| 625 Handle<JSFunction> function = | 621 Handle<JSFunction> function = |
| 626 factory->NewFunction(name, factory->undefined_value()); | 622 factory->NewFunction(name, factory->undefined_value()); |
| 627 Handle<Map> initial_map = | 623 Handle<Map> initial_map = |
| 628 factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 624 factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
| 629 function->set_initial_map(*initial_map); | 625 function->set_initial_map(*initial_map); |
| 630 | 626 |
| 627 Handle<Smi> twenty_three(Smi::FromInt(23), isolate); |
| 628 Handle<Smi> twenty_four(Smi::FromInt(24), isolate); |
| 629 |
| 631 Handle<String> prop_name = factory->InternalizeUtf8String("theSlot"); | 630 Handle<String> prop_name = factory->InternalizeUtf8String("theSlot"); |
| 632 Handle<JSObject> obj = factory->NewJSObject(function); | 631 Handle<JSObject> obj = factory->NewJSObject(function); |
| 633 obj->SetProperty( | 632 JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode); |
| 634 *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked(); | |
| 635 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); | 633 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); |
| 636 // Check that we can add properties to function objects. | 634 // Check that we can add properties to function objects. |
| 637 function->SetProperty( | 635 JSReceiver::SetProperty(function, prop_name, twenty_four, NONE, |
| 638 *prop_name, Smi::FromInt(24), NONE, kNonStrictMode)->ToObjectChecked(); | 636 kNonStrictMode); |
| 639 CHECK_EQ(Smi::FromInt(24), function->GetProperty(*prop_name)); | 637 CHECK_EQ(Smi::FromInt(24), function->GetProperty(*prop_name)); |
| 640 } | 638 } |
| 641 | 639 |
| 642 | 640 |
| 643 TEST(ObjectProperties) { | 641 TEST(ObjectProperties) { |
| 644 CcTest::InitializeVM(); | 642 CcTest::InitializeVM(); |
| 645 Isolate* isolate = Isolate::Current(); | 643 Isolate* isolate = CcTest::i_isolate(); |
| 646 Factory* factory = isolate->factory(); | 644 Factory* factory = isolate->factory(); |
| 647 | 645 |
| 648 v8::HandleScope sc(CcTest::isolate()); | 646 v8::HandleScope sc(CcTest::isolate()); |
| 649 String* object_string = String::cast(HEAP->Object_string()); | 647 String* object_string = String::cast(CcTest::heap()->Object_string()); |
| 650 Object* raw_object = Isolate::Current()->context()->global_object()-> | 648 Object* raw_object = CcTest::i_isolate()->context()->global_object()-> |
| 651 GetProperty(object_string)->ToObjectChecked(); | 649 GetProperty(object_string)->ToObjectChecked(); |
| 652 JSFunction* object_function = JSFunction::cast(raw_object); | 650 JSFunction* object_function = JSFunction::cast(raw_object); |
| 653 Handle<JSFunction> constructor(object_function); | 651 Handle<JSFunction> constructor(object_function); |
| 654 Handle<JSObject> obj = factory->NewJSObject(constructor); | 652 Handle<JSObject> obj = factory->NewJSObject(constructor); |
| 655 Handle<String> first = factory->InternalizeUtf8String("first"); | 653 Handle<String> first = factory->InternalizeUtf8String("first"); |
| 656 Handle<String> second = factory->InternalizeUtf8String("second"); | 654 Handle<String> second = factory->InternalizeUtf8String("second"); |
| 657 | 655 |
| 656 Handle<Smi> one(Smi::FromInt(1), isolate); |
| 657 Handle<Smi> two(Smi::FromInt(2), isolate); |
| 658 |
| 658 // check for empty | 659 // check for empty |
| 659 CHECK(!obj->HasLocalProperty(*first)); | 660 CHECK(!JSReceiver::HasLocalProperty(obj, first)); |
| 660 | 661 |
| 661 // add first | 662 // add first |
| 662 obj->SetProperty( | 663 JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode); |
| 663 *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); | 664 CHECK(JSReceiver::HasLocalProperty(obj, first)); |
| 664 CHECK(obj->HasLocalProperty(*first)); | |
| 665 | 665 |
| 666 // delete first | 666 // delete first |
| 667 JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION); | 667 JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION); |
| 668 CHECK(!obj->HasLocalProperty(*first)); | 668 CHECK(!JSReceiver::HasLocalProperty(obj, first)); |
| 669 | 669 |
| 670 // add first and then second | 670 // add first and then second |
| 671 obj->SetProperty( | 671 JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode); |
| 672 *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); | 672 JSReceiver::SetProperty(obj, second, two, NONE, kNonStrictMode); |
| 673 obj->SetProperty( | 673 CHECK(JSReceiver::HasLocalProperty(obj, first)); |
| 674 *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked(); | 674 CHECK(JSReceiver::HasLocalProperty(obj, second)); |
| 675 CHECK(obj->HasLocalProperty(*first)); | |
| 676 CHECK(obj->HasLocalProperty(*second)); | |
| 677 | 675 |
| 678 // delete first and then second | 676 // delete first and then second |
| 679 JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION); | 677 JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION); |
| 680 CHECK(obj->HasLocalProperty(*second)); | 678 CHECK(JSReceiver::HasLocalProperty(obj, second)); |
| 681 JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION); | 679 JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION); |
| 682 CHECK(!obj->HasLocalProperty(*first)); | 680 CHECK(!JSReceiver::HasLocalProperty(obj, first)); |
| 683 CHECK(!obj->HasLocalProperty(*second)); | 681 CHECK(!JSReceiver::HasLocalProperty(obj, second)); |
| 684 | 682 |
| 685 // add first and then second | 683 // add first and then second |
| 686 obj->SetProperty( | 684 JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode); |
| 687 *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); | 685 JSReceiver::SetProperty(obj, second, two, NONE, kNonStrictMode); |
| 688 obj->SetProperty( | 686 CHECK(JSReceiver::HasLocalProperty(obj, first)); |
| 689 *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked(); | 687 CHECK(JSReceiver::HasLocalProperty(obj, second)); |
| 690 CHECK(obj->HasLocalProperty(*first)); | |
| 691 CHECK(obj->HasLocalProperty(*second)); | |
| 692 | 688 |
| 693 // delete second and then first | 689 // delete second and then first |
| 694 JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION); | 690 JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION); |
| 695 CHECK(obj->HasLocalProperty(*first)); | 691 CHECK(JSReceiver::HasLocalProperty(obj, first)); |
| 696 JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION); | 692 JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION); |
| 697 CHECK(!obj->HasLocalProperty(*first)); | 693 CHECK(!JSReceiver::HasLocalProperty(obj, first)); |
| 698 CHECK(!obj->HasLocalProperty(*second)); | 694 CHECK(!JSReceiver::HasLocalProperty(obj, second)); |
| 699 | 695 |
| 700 // check string and internalized string match | 696 // check string and internalized string match |
| 701 const char* string1 = "fisk"; | 697 const char* string1 = "fisk"; |
| 702 Handle<String> s1 = factory->NewStringFromAscii(CStrVector(string1)); | 698 Handle<String> s1 = factory->NewStringFromAscii(CStrVector(string1)); |
| 703 obj->SetProperty( | 699 JSReceiver::SetProperty(obj, s1, one, NONE, kNonStrictMode); |
| 704 *s1, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); | |
| 705 Handle<String> s1_string = factory->InternalizeUtf8String(string1); | 700 Handle<String> s1_string = factory->InternalizeUtf8String(string1); |
| 706 CHECK(obj->HasLocalProperty(*s1_string)); | 701 CHECK(JSReceiver::HasLocalProperty(obj, s1_string)); |
| 707 | 702 |
| 708 // check internalized string and string match | 703 // check internalized string and string match |
| 709 const char* string2 = "fugl"; | 704 const char* string2 = "fugl"; |
| 710 Handle<String> s2_string = factory->InternalizeUtf8String(string2); | 705 Handle<String> s2_string = factory->InternalizeUtf8String(string2); |
| 711 obj->SetProperty( | 706 JSReceiver::SetProperty(obj, s2_string, one, NONE, kNonStrictMode); |
| 712 *s2_string, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); | |
| 713 Handle<String> s2 = factory->NewStringFromAscii(CStrVector(string2)); | 707 Handle<String> s2 = factory->NewStringFromAscii(CStrVector(string2)); |
| 714 CHECK(obj->HasLocalProperty(*s2)); | 708 CHECK(JSReceiver::HasLocalProperty(obj, s2)); |
| 715 } | 709 } |
| 716 | 710 |
| 717 | 711 |
| 718 TEST(JSObjectMaps) { | 712 TEST(JSObjectMaps) { |
| 719 CcTest::InitializeVM(); | 713 CcTest::InitializeVM(); |
| 720 Isolate* isolate = Isolate::Current(); | 714 Isolate* isolate = CcTest::i_isolate(); |
| 721 Factory* factory = isolate->factory(); | 715 Factory* factory = isolate->factory(); |
| 722 | 716 |
| 723 v8::HandleScope sc(CcTest::isolate()); | 717 v8::HandleScope sc(CcTest::isolate()); |
| 724 Handle<String> name = factory->InternalizeUtf8String("theFunction"); | 718 Handle<String> name = factory->InternalizeUtf8String("theFunction"); |
| 725 Handle<JSFunction> function = | 719 Handle<JSFunction> function = |
| 726 factory->NewFunction(name, factory->undefined_value()); | 720 factory->NewFunction(name, factory->undefined_value()); |
| 727 Handle<Map> initial_map = | 721 Handle<Map> initial_map = |
| 728 factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 722 factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
| 729 function->set_initial_map(*initial_map); | 723 function->set_initial_map(*initial_map); |
| 730 | 724 |
| 731 Handle<String> prop_name = factory->InternalizeUtf8String("theSlot"); | 725 Handle<String> prop_name = factory->InternalizeUtf8String("theSlot"); |
| 732 Handle<JSObject> obj = factory->NewJSObject(function); | 726 Handle<JSObject> obj = factory->NewJSObject(function); |
| 733 | 727 |
| 734 // Set a propery | 728 // Set a propery |
| 735 obj->SetProperty( | 729 Handle<Smi> twenty_three(Smi::FromInt(23), isolate); |
| 736 *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked(); | 730 JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode); |
| 737 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); | 731 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); |
| 738 | 732 |
| 739 // Check the map has changed | 733 // Check the map has changed |
| 740 CHECK(*initial_map != obj->map()); | 734 CHECK(*initial_map != obj->map()); |
| 741 } | 735 } |
| 742 | 736 |
| 743 | 737 |
| 744 TEST(JSArray) { | 738 TEST(JSArray) { |
| 745 CcTest::InitializeVM(); | 739 CcTest::InitializeVM(); |
| 746 Isolate* isolate = Isolate::Current(); | 740 Isolate* isolate = CcTest::i_isolate(); |
| 747 Factory* factory = isolate->factory(); | 741 Factory* factory = isolate->factory(); |
| 748 | 742 |
| 749 v8::HandleScope sc(CcTest::isolate()); | 743 v8::HandleScope sc(CcTest::isolate()); |
| 750 Handle<String> name = factory->InternalizeUtf8String("Array"); | 744 Handle<String> name = factory->InternalizeUtf8String("Array"); |
| 751 Object* raw_object = Isolate::Current()->context()->global_object()-> | 745 Object* raw_object = CcTest::i_isolate()->context()->global_object()-> |
| 752 GetProperty(*name)->ToObjectChecked(); | 746 GetProperty(*name)->ToObjectChecked(); |
| 753 Handle<JSFunction> function = Handle<JSFunction>( | 747 Handle<JSFunction> function = Handle<JSFunction>( |
| 754 JSFunction::cast(raw_object)); | 748 JSFunction::cast(raw_object)); |
| 755 | 749 |
| 756 // Allocate the object. | 750 // Allocate the object. |
| 757 Handle<JSObject> object = factory->NewJSObject(function); | 751 Handle<JSObject> object = factory->NewJSObject(function); |
| 758 Handle<JSArray> array = Handle<JSArray>::cast(object); | 752 Handle<JSArray> array = Handle<JSArray>::cast(object); |
| 759 // We just initialized the VM, no heap allocation failure yet. | 753 // We just initialized the VM, no heap allocation failure yet. |
| 760 array->Initialize(0)->ToObjectChecked(); | 754 array->Initialize(0)->ToObjectChecked(); |
| 761 | 755 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 785 uint32_t new_int_length = 0; | 779 uint32_t new_int_length = 0; |
| 786 CHECK(array->length()->ToArrayIndex(&new_int_length)); | 780 CHECK(array->length()->ToArrayIndex(&new_int_length)); |
| 787 CHECK_EQ(static_cast<double>(int_length), new_int_length - 1); | 781 CHECK_EQ(static_cast<double>(int_length), new_int_length - 1); |
| 788 CHECK_EQ(array->GetElement(isolate, int_length), *name); | 782 CHECK_EQ(array->GetElement(isolate, int_length), *name); |
| 789 CHECK_EQ(array->GetElement(isolate, 0), *name); | 783 CHECK_EQ(array->GetElement(isolate, 0), *name); |
| 790 } | 784 } |
| 791 | 785 |
| 792 | 786 |
| 793 TEST(JSObjectCopy) { | 787 TEST(JSObjectCopy) { |
| 794 CcTest::InitializeVM(); | 788 CcTest::InitializeVM(); |
| 795 Isolate* isolate = Isolate::Current(); | 789 Isolate* isolate = CcTest::i_isolate(); |
| 796 Factory* factory = isolate->factory(); | 790 Factory* factory = isolate->factory(); |
| 797 | 791 |
| 798 v8::HandleScope sc(CcTest::isolate()); | 792 v8::HandleScope sc(CcTest::isolate()); |
| 799 String* object_string = String::cast(HEAP->Object_string()); | 793 String* object_string = String::cast(CcTest::heap()->Object_string()); |
| 800 Object* raw_object = Isolate::Current()->context()->global_object()-> | 794 Object* raw_object = CcTest::i_isolate()->context()->global_object()-> |
| 801 GetProperty(object_string)->ToObjectChecked(); | 795 GetProperty(object_string)->ToObjectChecked(); |
| 802 JSFunction* object_function = JSFunction::cast(raw_object); | 796 JSFunction* object_function = JSFunction::cast(raw_object); |
| 803 Handle<JSFunction> constructor(object_function); | 797 Handle<JSFunction> constructor(object_function); |
| 804 Handle<JSObject> obj = factory->NewJSObject(constructor); | 798 Handle<JSObject> obj = factory->NewJSObject(constructor); |
| 805 Handle<String> first = factory->InternalizeUtf8String("first"); | 799 Handle<String> first = factory->InternalizeUtf8String("first"); |
| 806 Handle<String> second = factory->InternalizeUtf8String("second"); | 800 Handle<String> second = factory->InternalizeUtf8String("second"); |
| 807 | 801 |
| 808 obj->SetProperty( | 802 Handle<Smi> one(Smi::FromInt(1), isolate); |
| 809 *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); | 803 Handle<Smi> two(Smi::FromInt(2), isolate); |
| 810 obj->SetProperty( | 804 |
| 811 *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked(); | 805 JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode); |
| 806 JSReceiver::SetProperty(obj, second, two, NONE, kNonStrictMode); |
| 812 | 807 |
| 813 obj->SetElement(0, *first, NONE, kNonStrictMode)->ToObjectChecked(); | 808 obj->SetElement(0, *first, NONE, kNonStrictMode)->ToObjectChecked(); |
| 814 obj->SetElement(1, *second, NONE, kNonStrictMode)->ToObjectChecked(); | 809 obj->SetElement(1, *second, NONE, kNonStrictMode)->ToObjectChecked(); |
| 815 | 810 |
| 816 // Make the clone. | 811 // Make the clone. |
| 817 Handle<JSObject> clone = JSObject::Copy(obj); | 812 Handle<JSObject> clone = JSObject::Copy(obj); |
| 818 CHECK(!clone.is_identical_to(obj)); | 813 CHECK(!clone.is_identical_to(obj)); |
| 819 | 814 |
| 820 CHECK_EQ(obj->GetElement(isolate, 0), clone->GetElement(isolate, 0)); | 815 CHECK_EQ(obj->GetElement(isolate, 0), clone->GetElement(isolate, 0)); |
| 821 CHECK_EQ(obj->GetElement(isolate, 1), clone->GetElement(isolate, 1)); | 816 CHECK_EQ(obj->GetElement(isolate, 1), clone->GetElement(isolate, 1)); |
| 822 | 817 |
| 823 CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*first)); | 818 CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*first)); |
| 824 CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*second)); | 819 CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*second)); |
| 825 | 820 |
| 826 // Flip the values. | 821 // Flip the values. |
| 827 clone->SetProperty( | 822 JSReceiver::SetProperty(clone, first, two, NONE, kNonStrictMode); |
| 828 *first, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked(); | 823 JSReceiver::SetProperty(clone, second, one, NONE, kNonStrictMode); |
| 829 clone->SetProperty( | |
| 830 *second, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); | |
| 831 | 824 |
| 832 clone->SetElement(0, *second, NONE, kNonStrictMode)->ToObjectChecked(); | 825 clone->SetElement(0, *second, NONE, kNonStrictMode)->ToObjectChecked(); |
| 833 clone->SetElement(1, *first, NONE, kNonStrictMode)->ToObjectChecked(); | 826 clone->SetElement(1, *first, NONE, kNonStrictMode)->ToObjectChecked(); |
| 834 | 827 |
| 835 CHECK_EQ(obj->GetElement(isolate, 1), clone->GetElement(isolate, 0)); | 828 CHECK_EQ(obj->GetElement(isolate, 1), clone->GetElement(isolate, 0)); |
| 836 CHECK_EQ(obj->GetElement(isolate, 0), clone->GetElement(isolate, 1)); | 829 CHECK_EQ(obj->GetElement(isolate, 0), clone->GetElement(isolate, 1)); |
| 837 | 830 |
| 838 CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*first)); | 831 CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*first)); |
| 839 CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*second)); | 832 CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*second)); |
| 840 } | 833 } |
| 841 | 834 |
| 842 | 835 |
| 843 TEST(StringAllocation) { | 836 TEST(StringAllocation) { |
| 844 CcTest::InitializeVM(); | 837 CcTest::InitializeVM(); |
| 845 Isolate* isolate = Isolate::Current(); | 838 Isolate* isolate = CcTest::i_isolate(); |
| 846 Factory* factory = isolate->factory(); | 839 Factory* factory = isolate->factory(); |
| 847 | 840 |
| 848 const unsigned char chars[] = { 0xe5, 0xa4, 0xa7 }; | 841 const unsigned char chars[] = { 0xe5, 0xa4, 0xa7 }; |
| 849 for (int length = 0; length < 100; length++) { | 842 for (int length = 0; length < 100; length++) { |
| 850 v8::HandleScope scope(CcTest::isolate()); | 843 v8::HandleScope scope(CcTest::isolate()); |
| 851 char* non_ascii = NewArray<char>(3 * length + 1); | 844 char* non_ascii = NewArray<char>(3 * length + 1); |
| 852 char* ascii = NewArray<char>(length + 1); | 845 char* ascii = NewArray<char>(length + 1); |
| 853 non_ascii[3 * length] = 0; | 846 non_ascii[3 * length] = 0; |
| 854 ascii[length] = 0; | 847 ascii[length] = 0; |
| 855 for (int i = 0; i < length; i++) { | 848 for (int i = 0; i < length; i++) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 found_count++; | 883 found_count++; |
| 891 } | 884 } |
| 892 } | 885 } |
| 893 } | 886 } |
| 894 return found_count; | 887 return found_count; |
| 895 } | 888 } |
| 896 | 889 |
| 897 | 890 |
| 898 TEST(Iteration) { | 891 TEST(Iteration) { |
| 899 CcTest::InitializeVM(); | 892 CcTest::InitializeVM(); |
| 900 Isolate* isolate = Isolate::Current(); | 893 Isolate* isolate = CcTest::i_isolate(); |
| 901 Factory* factory = isolate->factory(); | 894 Factory* factory = isolate->factory(); |
| 902 v8::HandleScope scope(CcTest::isolate()); | 895 v8::HandleScope scope(CcTest::isolate()); |
| 903 | 896 |
| 904 // Array of objects to scan haep for. | 897 // Array of objects to scan haep for. |
| 905 const int objs_count = 6; | 898 const int objs_count = 6; |
| 906 Handle<Object> objs[objs_count]; | 899 Handle<Object> objs[objs_count]; |
| 907 int next_objs_index = 0; | 900 int next_objs_index = 0; |
| 908 | 901 |
| 909 // Allocate a JS array to OLD_POINTER_SPACE and NEW_SPACE | 902 // Allocate a JS array to OLD_POINTER_SPACE and NEW_SPACE |
| 910 objs[next_objs_index++] = factory->NewJSArray(10); | 903 objs[next_objs_index++] = factory->NewJSArray(10); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 924 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'; |
| 925 str[large_size - 1] = '\0'; | 918 str[large_size - 1] = '\0'; |
| 926 objs[next_objs_index++] = | 919 objs[next_objs_index++] = |
| 927 factory->NewStringFromAscii(CStrVector(str), TENURED); | 920 factory->NewStringFromAscii(CStrVector(str), TENURED); |
| 928 delete[] str; | 921 delete[] str; |
| 929 | 922 |
| 930 // Add a Map object to look for. | 923 // Add a Map object to look for. |
| 931 objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map()); | 924 objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map()); |
| 932 | 925 |
| 933 CHECK_EQ(objs_count, next_objs_index); | 926 CHECK_EQ(objs_count, next_objs_index); |
| 934 CHECK_EQ(objs_count, ObjectsFoundInHeap(HEAP, objs, objs_count)); | 927 CHECK_EQ(objs_count, ObjectsFoundInHeap(CcTest::heap(), objs, objs_count)); |
| 935 } | 928 } |
| 936 | 929 |
| 937 | 930 |
| 938 TEST(EmptyHandleEscapeFrom) { | 931 TEST(EmptyHandleEscapeFrom) { |
| 939 CcTest::InitializeVM(); | 932 CcTest::InitializeVM(); |
| 940 | 933 |
| 941 v8::HandleScope scope(CcTest::isolate()); | 934 v8::HandleScope scope(CcTest::isolate()); |
| 942 Handle<JSObject> runaway; | 935 Handle<JSObject> runaway; |
| 943 | 936 |
| 944 { | 937 { |
| 945 v8::HandleScope nested(CcTest::isolate()); | 938 v8::HandleScope nested(CcTest::isolate()); |
| 946 Handle<JSObject> empty; | 939 Handle<JSObject> empty; |
| 947 runaway = empty.EscapeFrom(&nested); | 940 runaway = empty.EscapeFrom(&nested); |
| 948 } | 941 } |
| 949 | 942 |
| 950 CHECK(runaway.is_null()); | 943 CHECK(runaway.is_null()); |
| 951 } | 944 } |
| 952 | 945 |
| 953 | 946 |
| 954 static int LenFromSize(int size) { | 947 static int LenFromSize(int size) { |
| 955 return (size - FixedArray::kHeaderSize) / kPointerSize; | 948 return (size - FixedArray::kHeaderSize) / kPointerSize; |
| 956 } | 949 } |
| 957 | 950 |
| 958 | 951 |
| 959 TEST(Regression39128) { | 952 TEST(Regression39128) { |
| 960 // Test case for crbug.com/39128. | 953 // Test case for crbug.com/39128. |
| 961 CcTest::InitializeVM(); | 954 CcTest::InitializeVM(); |
| 962 Isolate* isolate = Isolate::Current(); | 955 Isolate* isolate = CcTest::i_isolate(); |
| 963 Factory* factory = isolate->factory(); | 956 Factory* factory = isolate->factory(); |
| 957 Heap* heap = isolate->heap(); |
| 964 | 958 |
| 965 // Increase the chance of 'bump-the-pointer' allocation in old space. | 959 // Increase the chance of 'bump-the-pointer' allocation in old space. |
| 966 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 960 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 967 | 961 |
| 968 v8::HandleScope scope(CcTest::isolate()); | 962 v8::HandleScope scope(CcTest::isolate()); |
| 969 | 963 |
| 970 // The plan: create JSObject which references objects in new space. | 964 // The plan: create JSObject which references objects in new space. |
| 971 // 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 |
| 972 // that region dirty marks are updated correctly. | 966 // that region dirty marks are updated correctly. |
| 973 | 967 |
| 974 // 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. |
| 975 Handle<JSFunction> object_ctor( | 969 Handle<JSFunction> object_ctor( |
| 976 Isolate::Current()->native_context()->object_function()); | 970 CcTest::i_isolate()->native_context()->object_function()); |
| 977 CHECK(object_ctor->has_initial_map()); | 971 CHECK(object_ctor->has_initial_map()); |
| 978 Handle<Map> object_map(object_ctor->initial_map()); | 972 Handle<Map> object_map(object_ctor->initial_map()); |
| 979 // Create a map with single inobject property. | 973 // Create a map with single inobject property. |
| 980 Handle<Map> my_map = factory->CopyMap(object_map, 1); | 974 Handle<Map> my_map = factory->CopyMap(object_map, 1); |
| 981 int n_properties = my_map->inobject_properties(); | 975 int n_properties = my_map->inobject_properties(); |
| 982 CHECK_GT(n_properties, 0); | 976 CHECK_GT(n_properties, 0); |
| 983 | 977 |
| 984 int object_size = my_map->instance_size(); | 978 int object_size = my_map->instance_size(); |
| 985 | 979 |
| 986 // 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 |
| 987 // just enough room to allocate JSObject and thus fill the newspace. | 981 // just enough room to allocate JSObject and thus fill the newspace. |
| 988 | 982 |
| 989 int allocation_amount = Min(FixedArray::kMaxSize, | 983 int allocation_amount = Min(FixedArray::kMaxSize, |
| 990 Page::kMaxNonCodeHeapObjectSize + kPointerSize); | 984 Page::kMaxNonCodeHeapObjectSize + kPointerSize); |
| 991 int allocation_len = LenFromSize(allocation_amount); | 985 int allocation_len = LenFromSize(allocation_amount); |
| 992 NewSpace* new_space = HEAP->new_space(); | 986 NewSpace* new_space = heap->new_space(); |
| 993 Address* top_addr = new_space->allocation_top_address(); | 987 Address* top_addr = new_space->allocation_top_address(); |
| 994 Address* limit_addr = new_space->allocation_limit_address(); | 988 Address* limit_addr = new_space->allocation_limit_address(); |
| 995 while ((*limit_addr - *top_addr) > allocation_amount) { | 989 while ((*limit_addr - *top_addr) > allocation_amount) { |
| 996 CHECK(!HEAP->always_allocate()); | 990 CHECK(!heap->always_allocate()); |
| 997 Object* array = HEAP->AllocateFixedArray(allocation_len)->ToObjectChecked(); | 991 Object* array = heap->AllocateFixedArray(allocation_len)->ToObjectChecked(); |
| 998 CHECK(!array->IsFailure()); | 992 CHECK(!array->IsFailure()); |
| 999 CHECK(new_space->Contains(array)); | 993 CHECK(new_space->Contains(array)); |
| 1000 } | 994 } |
| 1001 | 995 |
| 1002 // 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. |
| 1003 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); |
| 1004 int fixed_array_len = LenFromSize(to_fill); | 998 int fixed_array_len = LenFromSize(to_fill); |
| 1005 CHECK(fixed_array_len < FixedArray::kMaxLength); | 999 CHECK(fixed_array_len < FixedArray::kMaxLength); |
| 1006 | 1000 |
| 1007 CHECK(!HEAP->always_allocate()); | 1001 CHECK(!heap->always_allocate()); |
| 1008 Object* array = HEAP->AllocateFixedArray(fixed_array_len)->ToObjectChecked(); | 1002 Object* array = heap->AllocateFixedArray(fixed_array_len)->ToObjectChecked(); |
| 1009 CHECK(!array->IsFailure()); | 1003 CHECK(!array->IsFailure()); |
| 1010 CHECK(new_space->Contains(array)); | 1004 CHECK(new_space->Contains(array)); |
| 1011 | 1005 |
| 1012 Object* object = HEAP->AllocateJSObjectFromMap(*my_map)->ToObjectChecked(); | 1006 Object* object = heap->AllocateJSObjectFromMap(*my_map)->ToObjectChecked(); |
| 1013 CHECK(new_space->Contains(object)); | 1007 CHECK(new_space->Contains(object)); |
| 1014 JSObject* jsobject = JSObject::cast(object); | 1008 JSObject* jsobject = JSObject::cast(object); |
| 1015 CHECK_EQ(0, FixedArray::cast(jsobject->elements())->length()); | 1009 CHECK_EQ(0, FixedArray::cast(jsobject->elements())->length()); |
| 1016 CHECK_EQ(0, jsobject->properties()->length()); | 1010 CHECK_EQ(0, jsobject->properties()->length()); |
| 1017 // Create a reference to object in new space in jsobject. | 1011 // Create a reference to object in new space in jsobject. |
| 1018 jsobject->FastPropertyAtPut(-1, array); | 1012 jsobject->FastPropertyAtPut(-1, array); |
| 1019 | 1013 |
| 1020 CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr)); | 1014 CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr)); |
| 1021 | 1015 |
| 1022 // 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 |
| 1023 // in old pointer space. | 1017 // in old pointer space. |
| 1024 Address old_pointer_space_top = HEAP->old_pointer_space()->top(); | 1018 Address old_pointer_space_top = heap->old_pointer_space()->top(); |
| 1025 AlwaysAllocateScope aa_scope; | 1019 AlwaysAllocateScope aa_scope; |
| 1026 Object* clone_obj = HEAP->CopyJSObject(jsobject)->ToObjectChecked(); | 1020 Object* clone_obj = heap->CopyJSObject(jsobject)->ToObjectChecked(); |
| 1027 JSObject* clone = JSObject::cast(clone_obj); | 1021 JSObject* clone = JSObject::cast(clone_obj); |
| 1028 if (clone->address() != old_pointer_space_top) { | 1022 if (clone->address() != old_pointer_space_top) { |
| 1029 // Alas, got allocated from free list, we cannot do checks. | 1023 // Alas, got allocated from free list, we cannot do checks. |
| 1030 return; | 1024 return; |
| 1031 } | 1025 } |
| 1032 CHECK(HEAP->old_pointer_space()->Contains(clone->address())); | 1026 CHECK(heap->old_pointer_space()->Contains(clone->address())); |
| 1033 } | 1027 } |
| 1034 | 1028 |
| 1035 | 1029 |
| 1036 TEST(TestCodeFlushing) { | 1030 TEST(TestCodeFlushing) { |
| 1037 // If we do not flush code this test is invalid. | 1031 // If we do not flush code this test is invalid. |
| 1038 if (!FLAG_flush_code) return; | 1032 if (!FLAG_flush_code) return; |
| 1039 i::FLAG_allow_natives_syntax = true; | 1033 i::FLAG_allow_natives_syntax = true; |
| 1040 CcTest::InitializeVM(); | 1034 CcTest::InitializeVM(); |
| 1041 Isolate* isolate = Isolate::Current(); | 1035 Isolate* isolate = CcTest::i_isolate(); |
| 1042 Factory* factory = isolate->factory(); | 1036 Factory* factory = isolate->factory(); |
| 1043 v8::HandleScope scope(CcTest::isolate()); | 1037 v8::HandleScope scope(CcTest::isolate()); |
| 1044 const char* source = "function foo() {" | 1038 const char* source = "function foo() {" |
| 1045 " var x = 42;" | 1039 " var x = 42;" |
| 1046 " var y = 42;" | 1040 " var y = 42;" |
| 1047 " var z = x + y;" | 1041 " var z = x + y;" |
| 1048 "};" | 1042 "};" |
| 1049 "foo()"; | 1043 "foo()"; |
| 1050 Handle<String> foo_name = factory->InternalizeUtf8String("foo"); | 1044 Handle<String> foo_name = factory->InternalizeUtf8String("foo"); |
| 1051 | 1045 |
| 1052 // This compile will add the code to the compilation cache. | 1046 // This compile will add the code to the compilation cache. |
| 1053 { v8::HandleScope scope(CcTest::isolate()); | 1047 { v8::HandleScope scope(CcTest::isolate()); |
| 1054 CompileRun(source); | 1048 CompileRun(source); |
| 1055 } | 1049 } |
| 1056 | 1050 |
| 1057 // Check function is compiled. | 1051 // Check function is compiled. |
| 1058 Object* func_value = Isolate::Current()->context()->global_object()-> | 1052 Object* func_value = CcTest::i_isolate()->context()->global_object()-> |
| 1059 GetProperty(*foo_name)->ToObjectChecked(); | 1053 GetProperty(*foo_name)->ToObjectChecked(); |
| 1060 CHECK(func_value->IsJSFunction()); | 1054 CHECK(func_value->IsJSFunction()); |
| 1061 Handle<JSFunction> function(JSFunction::cast(func_value)); | 1055 Handle<JSFunction> function(JSFunction::cast(func_value)); |
| 1062 CHECK(function->shared()->is_compiled()); | 1056 CHECK(function->shared()->is_compiled()); |
| 1063 | 1057 |
| 1064 // The code will survive at least two GCs. | 1058 // The code will survive at least two GCs. |
| 1065 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1059 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1066 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1060 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1067 CHECK(function->shared()->is_compiled()); | 1061 CHECK(function->shared()->is_compiled()); |
| 1068 | 1062 |
| 1069 // Simulate several GCs that use full marking. | 1063 // Simulate several GCs that use full marking. |
| 1070 const int kAgingThreshold = 6; | 1064 const int kAgingThreshold = 6; |
| 1071 for (int i = 0; i < kAgingThreshold; i++) { | 1065 for (int i = 0; i < kAgingThreshold; i++) { |
| 1072 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1066 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1073 } | 1067 } |
| 1074 | 1068 |
| 1075 // foo should no longer be in the compilation cache | 1069 // foo should no longer be in the compilation cache |
| 1076 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); | 1070 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); |
| 1077 CHECK(!function->is_compiled() || function->IsOptimized()); | 1071 CHECK(!function->is_compiled() || function->IsOptimized()); |
| 1078 // Call foo to get it recompiled. | 1072 // Call foo to get it recompiled. |
| 1079 CompileRun("foo()"); | 1073 CompileRun("foo()"); |
| 1080 CHECK(function->shared()->is_compiled()); | 1074 CHECK(function->shared()->is_compiled()); |
| 1081 CHECK(function->is_compiled()); | 1075 CHECK(function->is_compiled()); |
| 1082 } | 1076 } |
| 1083 | 1077 |
| 1084 | 1078 |
| 1085 TEST(TestCodeFlushingIncremental) { | 1079 TEST(TestCodeFlushingIncremental) { |
| 1086 // If we do not flush code this test is invalid. | 1080 // If we do not flush code this test is invalid. |
| 1087 if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; | 1081 if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; |
| 1088 i::FLAG_allow_natives_syntax = true; | 1082 i::FLAG_allow_natives_syntax = true; |
| 1089 CcTest::InitializeVM(); | 1083 CcTest::InitializeVM(); |
| 1090 Isolate* isolate = Isolate::Current(); | 1084 Isolate* isolate = CcTest::i_isolate(); |
| 1091 Factory* factory = isolate->factory(); | 1085 Factory* factory = isolate->factory(); |
| 1092 v8::HandleScope scope(CcTest::isolate()); | 1086 v8::HandleScope scope(CcTest::isolate()); |
| 1093 const char* source = "function foo() {" | 1087 const char* source = "function foo() {" |
| 1094 " var x = 42;" | 1088 " var x = 42;" |
| 1095 " var y = 42;" | 1089 " var y = 42;" |
| 1096 " var z = x + y;" | 1090 " var z = x + y;" |
| 1097 "};" | 1091 "};" |
| 1098 "foo()"; | 1092 "foo()"; |
| 1099 Handle<String> foo_name = factory->InternalizeUtf8String("foo"); | 1093 Handle<String> foo_name = factory->InternalizeUtf8String("foo"); |
| 1100 | 1094 |
| 1101 // This compile will add the code to the compilation cache. | 1095 // This compile will add the code to the compilation cache. |
| 1102 { v8::HandleScope scope(CcTest::isolate()); | 1096 { v8::HandleScope scope(CcTest::isolate()); |
| 1103 CompileRun(source); | 1097 CompileRun(source); |
| 1104 } | 1098 } |
| 1105 | 1099 |
| 1106 // Check function is compiled. | 1100 // Check function is compiled. |
| 1107 Object* func_value = Isolate::Current()->context()->global_object()-> | 1101 Object* func_value = CcTest::i_isolate()->context()->global_object()-> |
| 1108 GetProperty(*foo_name)->ToObjectChecked(); | 1102 GetProperty(*foo_name)->ToObjectChecked(); |
| 1109 CHECK(func_value->IsJSFunction()); | 1103 CHECK(func_value->IsJSFunction()); |
| 1110 Handle<JSFunction> function(JSFunction::cast(func_value)); | 1104 Handle<JSFunction> function(JSFunction::cast(func_value)); |
| 1111 CHECK(function->shared()->is_compiled()); | 1105 CHECK(function->shared()->is_compiled()); |
| 1112 | 1106 |
| 1113 // The code will survive at least two GCs. | 1107 // The code will survive at least two GCs. |
| 1114 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1108 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1115 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1109 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1116 CHECK(function->shared()->is_compiled()); | 1110 CHECK(function->shared()->is_compiled()); |
| 1117 | 1111 |
| 1118 // Simulate several GCs that use incremental marking. | 1112 // Simulate several GCs that use incremental marking. |
| 1119 const int kAgingThreshold = 6; | 1113 const int kAgingThreshold = 6; |
| 1120 for (int i = 0; i < kAgingThreshold; i++) { | 1114 for (int i = 0; i < kAgingThreshold; i++) { |
| 1121 SimulateIncrementalMarking(); | 1115 SimulateIncrementalMarking(); |
| 1122 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1116 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1123 } | 1117 } |
| 1124 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); | 1118 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); |
| 1125 CHECK(!function->is_compiled() || function->IsOptimized()); | 1119 CHECK(!function->is_compiled() || function->IsOptimized()); |
| 1126 | 1120 |
| 1127 // This compile will compile the function again. | 1121 // This compile will compile the function again. |
| 1128 { v8::HandleScope scope(CcTest::isolate()); | 1122 { v8::HandleScope scope(CcTest::isolate()); |
| 1129 CompileRun("foo();"); | 1123 CompileRun("foo();"); |
| 1130 } | 1124 } |
| 1131 | 1125 |
| 1132 // Simulate several GCs that use incremental marking but make sure | 1126 // Simulate several GCs that use incremental marking but make sure |
| 1133 // the loop breaks once the function is enqueued as a candidate. | 1127 // the loop breaks once the function is enqueued as a candidate. |
| 1134 for (int i = 0; i < kAgingThreshold; i++) { | 1128 for (int i = 0; i < kAgingThreshold; i++) { |
| 1135 SimulateIncrementalMarking(); | 1129 SimulateIncrementalMarking(); |
| 1136 if (!function->next_function_link()->IsUndefined()) break; | 1130 if (!function->next_function_link()->IsUndefined()) break; |
| 1137 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1131 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1138 } | 1132 } |
| 1139 | 1133 |
| 1140 // Force optimization while incremental marking is active and while | 1134 // Force optimization while incremental marking is active and while |
| 1141 // the function is enqueued as a candidate. | 1135 // the function is enqueued as a candidate. |
| 1142 { v8::HandleScope scope(CcTest::isolate()); | 1136 { v8::HandleScope scope(CcTest::isolate()); |
| 1143 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();"); | 1137 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();"); |
| 1144 } | 1138 } |
| 1145 | 1139 |
| 1146 // 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. |
| 1147 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1141 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1148 CHECK(function->shared()->is_compiled() || !function->IsOptimized()); | 1142 CHECK(function->shared()->is_compiled() || !function->IsOptimized()); |
| 1149 CHECK(function->is_compiled() || !function->IsOptimized()); | 1143 CHECK(function->is_compiled() || !function->IsOptimized()); |
| 1150 } | 1144 } |
| 1151 | 1145 |
| 1152 | 1146 |
| 1153 TEST(TestCodeFlushingIncrementalScavenge) { | 1147 TEST(TestCodeFlushingIncrementalScavenge) { |
| 1154 // If we do not flush code this test is invalid. | 1148 // If we do not flush code this test is invalid. |
| 1155 if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; | 1149 if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; |
| 1156 i::FLAG_allow_natives_syntax = true; | 1150 i::FLAG_allow_natives_syntax = true; |
| 1157 CcTest::InitializeVM(); | 1151 CcTest::InitializeVM(); |
| 1158 Isolate* isolate = Isolate::Current(); | 1152 Isolate* isolate = CcTest::i_isolate(); |
| 1159 Factory* factory = isolate->factory(); | 1153 Factory* factory = isolate->factory(); |
| 1160 v8::HandleScope scope(CcTest::isolate()); | 1154 v8::HandleScope scope(CcTest::isolate()); |
| 1161 const char* source = "var foo = function() {" | 1155 const char* source = "var foo = function() {" |
| 1162 " var x = 42;" | 1156 " var x = 42;" |
| 1163 " var y = 42;" | 1157 " var y = 42;" |
| 1164 " var z = x + y;" | 1158 " var z = x + y;" |
| 1165 "};" | 1159 "};" |
| 1166 "foo();" | 1160 "foo();" |
| 1167 "var bar = function() {" | 1161 "var bar = function() {" |
| 1168 " var x = 23;" | 1162 " var x = 23;" |
| 1169 "};" | 1163 "};" |
| 1170 "bar();"; | 1164 "bar();"; |
| 1171 Handle<String> foo_name = factory->InternalizeUtf8String("foo"); | 1165 Handle<String> foo_name = factory->InternalizeUtf8String("foo"); |
| 1172 Handle<String> bar_name = factory->InternalizeUtf8String("bar"); | 1166 Handle<String> bar_name = factory->InternalizeUtf8String("bar"); |
| 1173 | 1167 |
| 1174 // Perfrom one initial GC to enable code flushing. | 1168 // Perfrom one initial GC to enable code flushing. |
| 1175 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1169 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1176 | 1170 |
| 1177 // This compile will add the code to the compilation cache. | 1171 // This compile will add the code to the compilation cache. |
| 1178 { v8::HandleScope scope(CcTest::isolate()); | 1172 { v8::HandleScope scope(CcTest::isolate()); |
| 1179 CompileRun(source); | 1173 CompileRun(source); |
| 1180 } | 1174 } |
| 1181 | 1175 |
| 1182 // Check functions are compiled. | 1176 // Check functions are compiled. |
| 1183 Object* func_value = Isolate::Current()->context()->global_object()-> | 1177 Object* func_value = CcTest::i_isolate()->context()->global_object()-> |
| 1184 GetProperty(*foo_name)->ToObjectChecked(); | 1178 GetProperty(*foo_name)->ToObjectChecked(); |
| 1185 CHECK(func_value->IsJSFunction()); | 1179 CHECK(func_value->IsJSFunction()); |
| 1186 Handle<JSFunction> function(JSFunction::cast(func_value)); | 1180 Handle<JSFunction> function(JSFunction::cast(func_value)); |
| 1187 CHECK(function->shared()->is_compiled()); | 1181 CHECK(function->shared()->is_compiled()); |
| 1188 Object* func_value2 = Isolate::Current()->context()->global_object()-> | 1182 Object* func_value2 = CcTest::i_isolate()->context()->global_object()-> |
| 1189 GetProperty(*bar_name)->ToObjectChecked(); | 1183 GetProperty(*bar_name)->ToObjectChecked(); |
| 1190 CHECK(func_value2->IsJSFunction()); | 1184 CHECK(func_value2->IsJSFunction()); |
| 1191 Handle<JSFunction> function2(JSFunction::cast(func_value2)); | 1185 Handle<JSFunction> function2(JSFunction::cast(func_value2)); |
| 1192 CHECK(function2->shared()->is_compiled()); | 1186 CHECK(function2->shared()->is_compiled()); |
| 1193 | 1187 |
| 1194 // Clear references to functions so that one of them can die. | 1188 // Clear references to functions so that one of them can die. |
| 1195 { v8::HandleScope scope(CcTest::isolate()); | 1189 { v8::HandleScope scope(CcTest::isolate()); |
| 1196 CompileRun("foo = 0; bar = 0;"); | 1190 CompileRun("foo = 0; bar = 0;"); |
| 1197 } | 1191 } |
| 1198 | 1192 |
| 1199 // Bump the code age so that flushing is triggered while the function | 1193 // Bump the code age so that flushing is triggered while the function |
| 1200 // object is still located in new-space. | 1194 // object is still located in new-space. |
| 1201 const int kAgingThreshold = 6; | 1195 const int kAgingThreshold = 6; |
| 1202 for (int i = 0; i < kAgingThreshold; i++) { | 1196 for (int i = 0; i < kAgingThreshold; i++) { |
| 1203 function->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 1197 function->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); |
| 1204 function2->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 1198 function2->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); |
| 1205 } | 1199 } |
| 1206 | 1200 |
| 1207 // Simulate incremental marking so that the functions are enqueued as | 1201 // Simulate incremental marking so that the functions are enqueued as |
| 1208 // code flushing candidates. Then kill one of the functions. Finally | 1202 // code flushing candidates. Then kill one of the functions. Finally |
| 1209 // perform a scavenge while incremental marking is still running. | 1203 // perform a scavenge while incremental marking is still running. |
| 1210 SimulateIncrementalMarking(); | 1204 SimulateIncrementalMarking(); |
| 1211 *function2.location() = NULL; | 1205 *function2.location() = NULL; |
| 1212 HEAP->CollectGarbage(NEW_SPACE, "test scavenge while marking"); | 1206 CcTest::heap()->CollectGarbage(NEW_SPACE, "test scavenge while marking"); |
| 1213 | 1207 |
| 1214 // 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. |
| 1215 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1209 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1216 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); | 1210 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); |
| 1217 CHECK(!function->is_compiled() || function->IsOptimized()); | 1211 CHECK(!function->is_compiled() || function->IsOptimized()); |
| 1218 } | 1212 } |
| 1219 | 1213 |
| 1220 | 1214 |
| 1221 TEST(TestCodeFlushingIncrementalAbort) { | 1215 TEST(TestCodeFlushingIncrementalAbort) { |
| 1222 // If we do not flush code this test is invalid. | 1216 // If we do not flush code this test is invalid. |
| 1223 if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; | 1217 if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; |
| 1224 i::FLAG_allow_natives_syntax = true; | 1218 i::FLAG_allow_natives_syntax = true; |
| 1225 CcTest::InitializeVM(); | 1219 CcTest::InitializeVM(); |
| 1226 Isolate* isolate = Isolate::Current(); | 1220 Isolate* isolate = CcTest::i_isolate(); |
| 1227 Factory* factory = isolate->factory(); | 1221 Factory* factory = isolate->factory(); |
| 1228 Heap* heap = isolate->heap(); | 1222 Heap* heap = isolate->heap(); |
| 1229 v8::HandleScope scope(CcTest::isolate()); | 1223 v8::HandleScope scope(CcTest::isolate()); |
| 1230 const char* source = "function foo() {" | 1224 const char* source = "function foo() {" |
| 1231 " var x = 42;" | 1225 " var x = 42;" |
| 1232 " var y = 42;" | 1226 " var y = 42;" |
| 1233 " var z = x + y;" | 1227 " var z = x + y;" |
| 1234 "};" | 1228 "};" |
| 1235 "foo()"; | 1229 "foo()"; |
| 1236 Handle<String> foo_name = factory->InternalizeUtf8String("foo"); | 1230 Handle<String> foo_name = factory->InternalizeUtf8String("foo"); |
| 1237 | 1231 |
| 1238 // This compile will add the code to the compilation cache. | 1232 // This compile will add the code to the compilation cache. |
| 1239 { v8::HandleScope scope(CcTest::isolate()); | 1233 { v8::HandleScope scope(CcTest::isolate()); |
| 1240 CompileRun(source); | 1234 CompileRun(source); |
| 1241 } | 1235 } |
| 1242 | 1236 |
| 1243 // Check function is compiled. | 1237 // Check function is compiled. |
| 1244 Object* func_value = Isolate::Current()->context()->global_object()-> | 1238 Object* func_value = CcTest::i_isolate()->context()->global_object()-> |
| 1245 GetProperty(*foo_name)->ToObjectChecked(); | 1239 GetProperty(*foo_name)->ToObjectChecked(); |
| 1246 CHECK(func_value->IsJSFunction()); | 1240 CHECK(func_value->IsJSFunction()); |
| 1247 Handle<JSFunction> function(JSFunction::cast(func_value)); | 1241 Handle<JSFunction> function(JSFunction::cast(func_value)); |
| 1248 CHECK(function->shared()->is_compiled()); | 1242 CHECK(function->shared()->is_compiled()); |
| 1249 | 1243 |
| 1250 // The code will survive at least two GCs. | 1244 // The code will survive at least two GCs. |
| 1251 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1245 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1252 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1246 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1253 CHECK(function->shared()->is_compiled()); | 1247 CHECK(function->shared()->is_compiled()); |
| 1254 | 1248 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1280 // 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. |
| 1281 heap->CollectAllGarbage(Heap::kNoGCFlags); | 1275 heap->CollectAllGarbage(Heap::kNoGCFlags); |
| 1282 CHECK(function->shared()->is_compiled() || !function->IsOptimized()); | 1276 CHECK(function->shared()->is_compiled() || !function->IsOptimized()); |
| 1283 CHECK(function->is_compiled() || !function->IsOptimized()); | 1277 CHECK(function->is_compiled() || !function->IsOptimized()); |
| 1284 } | 1278 } |
| 1285 | 1279 |
| 1286 | 1280 |
| 1287 // 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. |
| 1288 int CountNativeContexts() { | 1282 int CountNativeContexts() { |
| 1289 int count = 0; | 1283 int count = 0; |
| 1290 Object* object = HEAP->native_contexts_list(); | 1284 Object* object = CcTest::heap()->native_contexts_list(); |
| 1291 while (!object->IsUndefined()) { | 1285 while (!object->IsUndefined()) { |
| 1292 count++; | 1286 count++; |
| 1293 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); | 1287 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); |
| 1294 } | 1288 } |
| 1295 return count; | 1289 return count; |
| 1296 } | 1290 } |
| 1297 | 1291 |
| 1298 | 1292 |
| 1299 // 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 |
| 1300 // functions attached to a native context. | 1294 // functions attached to a native context. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1312 | 1306 |
| 1313 TEST(TestInternalWeakLists) { | 1307 TEST(TestInternalWeakLists) { |
| 1314 v8::V8::Initialize(); | 1308 v8::V8::Initialize(); |
| 1315 | 1309 |
| 1316 // Some flags turn Scavenge collections into Mark-sweep collections | 1310 // Some flags turn Scavenge collections into Mark-sweep collections |
| 1317 // and hence are incompatible with this test case. | 1311 // and hence are incompatible with this test case. |
| 1318 if (FLAG_gc_global || FLAG_stress_compaction) return; | 1312 if (FLAG_gc_global || FLAG_stress_compaction) return; |
| 1319 | 1313 |
| 1320 static const int kNumTestContexts = 10; | 1314 static const int kNumTestContexts = 10; |
| 1321 | 1315 |
| 1322 Isolate* isolate = Isolate::Current(); | 1316 Isolate* isolate = CcTest::i_isolate(); |
| 1323 Heap* heap = isolate->heap(); | 1317 Heap* heap = isolate->heap(); |
| 1324 HandleScope scope(isolate); | 1318 HandleScope scope(isolate); |
| 1325 v8::Handle<v8::Context> ctx[kNumTestContexts]; | 1319 v8::Handle<v8::Context> ctx[kNumTestContexts]; |
| 1326 | 1320 |
| 1327 CHECK_EQ(0, CountNativeContexts()); | 1321 CHECK_EQ(0, CountNativeContexts()); |
| 1328 | 1322 |
| 1329 // Create a number of global contests which gets linked together. | 1323 // Create a number of global contests which gets linked together. |
| 1330 for (int i = 0; i < kNumTestContexts; i++) { | 1324 for (int i = 0; i < kNumTestContexts; i++) { |
| 1331 ctx[i] = v8::Context::New(v8::Isolate::GetCurrent()); | 1325 ctx[i] = v8::Context::New(CcTest::isolate()); |
| 1332 | 1326 |
| 1333 // Collect garbage that might have been created by one of the | 1327 // Collect garbage that might have been created by one of the |
| 1334 // installed extensions. | 1328 // installed extensions. |
| 1335 isolate->compilation_cache()->Clear(); | 1329 isolate->compilation_cache()->Clear(); |
| 1336 heap->CollectAllGarbage(Heap::kNoGCFlags); | 1330 heap->CollectAllGarbage(Heap::kNoGCFlags); |
| 1337 | 1331 |
| 1338 bool opt = (FLAG_always_opt && isolate->use_crankshaft()); | 1332 bool opt = (FLAG_always_opt && isolate->use_crankshaft()); |
| 1339 | 1333 |
| 1340 CHECK_EQ(i + 1, CountNativeContexts()); | 1334 CHECK_EQ(i + 1, CountNativeContexts()); |
| 1341 | 1335 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1360 CompileRun("f4()"); | 1354 CompileRun("f4()"); |
| 1361 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); | 1355 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1362 CompileRun("f5()"); | 1356 CompileRun("f5()"); |
| 1363 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); | 1357 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1364 | 1358 |
| 1365 // Remove function f1, and | 1359 // Remove function f1, and |
| 1366 CompileRun("f1=null"); | 1360 CompileRun("f1=null"); |
| 1367 | 1361 |
| 1368 // Scavenge treats these references as strong. | 1362 // Scavenge treats these references as strong. |
| 1369 for (int j = 0; j < 10; j++) { | 1363 for (int j = 0; j < 10; j++) { |
| 1370 HEAP->PerformScavenge(); | 1364 CcTest::heap()->PerformScavenge(); |
| 1371 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); | 1365 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1372 } | 1366 } |
| 1373 | 1367 |
| 1374 // Mark compact handles the weak references. | 1368 // Mark compact handles the weak references. |
| 1375 isolate->compilation_cache()->Clear(); | 1369 isolate->compilation_cache()->Clear(); |
| 1376 heap->CollectAllGarbage(Heap::kNoGCFlags); | 1370 heap->CollectAllGarbage(Heap::kNoGCFlags); |
| 1377 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); | 1371 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1378 | 1372 |
| 1379 // Get rid of f3 and f5 in the same way. | 1373 // Get rid of f3 and f5 in the same way. |
| 1380 CompileRun("f3=null"); | 1374 CompileRun("f3=null"); |
| 1381 for (int j = 0; j < 10; j++) { | 1375 for (int j = 0; j < 10; j++) { |
| 1382 HEAP->PerformScavenge(); | 1376 CcTest::heap()->PerformScavenge(); |
| 1383 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); | 1377 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1384 } | 1378 } |
| 1385 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1379 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1386 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); | 1380 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1387 CompileRun("f5=null"); | 1381 CompileRun("f5=null"); |
| 1388 for (int j = 0; j < 10; j++) { | 1382 for (int j = 0; j < 10; j++) { |
| 1389 HEAP->PerformScavenge(); | 1383 CcTest::heap()->PerformScavenge(); |
| 1390 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); | 1384 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1391 } | 1385 } |
| 1392 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1386 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1393 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); | 1387 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1394 | 1388 |
| 1395 ctx[i]->Exit(); | 1389 ctx[i]->Exit(); |
| 1396 } | 1390 } |
| 1397 | 1391 |
| 1398 // Force compilation cache cleanup. | 1392 // Force compilation cache cleanup. |
| 1399 HEAP->NotifyContextDisposed(); | 1393 CcTest::heap()->NotifyContextDisposed(); |
| 1400 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1394 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1401 | 1395 |
| 1402 // Dispose the native contexts one by one. | 1396 // Dispose the native contexts one by one. |
| 1403 for (int i = 0; i < kNumTestContexts; i++) { | 1397 for (int i = 0; i < kNumTestContexts; i++) { |
| 1404 // TODO(dcarney): is there a better way to do this? | 1398 // TODO(dcarney): is there a better way to do this? |
| 1405 i::Object** unsafe = reinterpret_cast<i::Object**>(*ctx[i]); | 1399 i::Object** unsafe = reinterpret_cast<i::Object**>(*ctx[i]); |
| 1406 *unsafe = HEAP->undefined_value(); | 1400 *unsafe = CcTest::heap()->undefined_value(); |
| 1407 ctx[i].Clear(); | 1401 ctx[i].Clear(); |
| 1408 | 1402 |
| 1409 // Scavenge treats these references as strong. | 1403 // Scavenge treats these references as strong. |
| 1410 for (int j = 0; j < 10; j++) { | 1404 for (int j = 0; j < 10; j++) { |
| 1411 HEAP->PerformScavenge(); | 1405 CcTest::heap()->PerformScavenge(); |
| 1412 CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); | 1406 CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); |
| 1413 } | 1407 } |
| 1414 | 1408 |
| 1415 // Mark compact handles the weak references. | 1409 // Mark compact handles the weak references. |
| 1416 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1410 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1417 CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts()); | 1411 CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts()); |
| 1418 } | 1412 } |
| 1419 | 1413 |
| 1420 CHECK_EQ(0, CountNativeContexts()); | 1414 CHECK_EQ(0, CountNativeContexts()); |
| 1421 } | 1415 } |
| 1422 | 1416 |
| 1423 | 1417 |
| 1424 // 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 |
| 1425 // causing a GC after the specified number of elements. | 1419 // causing a GC after the specified number of elements. |
| 1426 static int CountNativeContextsWithGC(Isolate* isolate, int n) { | 1420 static int CountNativeContextsWithGC(Isolate* isolate, int n) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1455 object = Handle<Object>( | 1449 object = Handle<Object>( |
| 1456 Object::cast(JSFunction::cast(*object)->next_function_link()), | 1450 Object::cast(JSFunction::cast(*object)->next_function_link()), |
| 1457 isolate); | 1451 isolate); |
| 1458 } | 1452 } |
| 1459 return count; | 1453 return count; |
| 1460 } | 1454 } |
| 1461 | 1455 |
| 1462 | 1456 |
| 1463 TEST(TestInternalWeakListsTraverseWithGC) { | 1457 TEST(TestInternalWeakListsTraverseWithGC) { |
| 1464 v8::V8::Initialize(); | 1458 v8::V8::Initialize(); |
| 1465 Isolate* isolate = Isolate::Current(); | 1459 Isolate* isolate = CcTest::i_isolate(); |
| 1466 | 1460 |
| 1467 static const int kNumTestContexts = 10; | 1461 static const int kNumTestContexts = 10; |
| 1468 | 1462 |
| 1469 HandleScope scope(isolate); | 1463 HandleScope scope(isolate); |
| 1470 v8::Handle<v8::Context> ctx[kNumTestContexts]; | 1464 v8::Handle<v8::Context> ctx[kNumTestContexts]; |
| 1471 | 1465 |
| 1472 CHECK_EQ(0, CountNativeContexts()); | 1466 CHECK_EQ(0, CountNativeContexts()); |
| 1473 | 1467 |
| 1474 // Create an number of contexts and check the length of the weak list both | 1468 // Create an number of contexts and check the length of the weak list both |
| 1475 // with and without GCs while iterating the list. | 1469 // with and without GCs while iterating the list. |
| 1476 for (int i = 0; i < kNumTestContexts; i++) { | 1470 for (int i = 0; i < kNumTestContexts; i++) { |
| 1477 ctx[i] = v8::Context::New(v8::Isolate::GetCurrent()); | 1471 ctx[i] = v8::Context::New(CcTest::isolate()); |
| 1478 CHECK_EQ(i + 1, CountNativeContexts()); | 1472 CHECK_EQ(i + 1, CountNativeContexts()); |
| 1479 CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1)); | 1473 CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1)); |
| 1480 } | 1474 } |
| 1481 | 1475 |
| 1482 bool opt = (FLAG_always_opt && isolate->use_crankshaft()); | 1476 bool opt = (FLAG_always_opt && isolate->use_crankshaft()); |
| 1483 | 1477 |
| 1484 // Compile a number of functions the length of the weak list of optimized | 1478 // Compile a number of functions the length of the weak list of optimized |
| 1485 // functions both with and without GCs while iterating the list. | 1479 // functions both with and without GCs while iterating the list. |
| 1486 ctx[0]->Enter(); | 1480 ctx[0]->Enter(); |
| 1487 const char* source = "function f1() { };" | 1481 const char* source = "function f1() { };" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1509 | 1503 |
| 1510 ctx[0]->Exit(); | 1504 ctx[0]->Exit(); |
| 1511 } | 1505 } |
| 1512 | 1506 |
| 1513 | 1507 |
| 1514 TEST(TestSizeOfObjects) { | 1508 TEST(TestSizeOfObjects) { |
| 1515 v8::V8::Initialize(); | 1509 v8::V8::Initialize(); |
| 1516 | 1510 |
| 1517 // Get initial heap size after several full GCs, which will stabilize | 1511 // Get initial heap size after several full GCs, which will stabilize |
| 1518 // the heap size and return with sweeping finished completely. | 1512 // the heap size and return with sweeping finished completely. |
| 1519 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1513 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1520 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1514 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1521 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1515 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1522 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1516 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1523 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1517 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1524 CHECK(HEAP->old_pointer_space()->IsLazySweepingComplete()); | 1518 CHECK(CcTest::heap()->old_pointer_space()->IsLazySweepingComplete()); |
| 1525 int initial_size = static_cast<int>(HEAP->SizeOfObjects()); | 1519 int initial_size = static_cast<int>(CcTest::heap()->SizeOfObjects()); |
| 1526 | 1520 |
| 1527 { | 1521 { |
| 1528 // Allocate objects on several different old-space pages so that | 1522 // Allocate objects on several different old-space pages so that |
| 1529 // lazy sweeping kicks in for subsequent GC runs. | 1523 // lazy sweeping kicks in for subsequent GC runs. |
| 1530 AlwaysAllocateScope always_allocate; | 1524 AlwaysAllocateScope always_allocate; |
| 1531 int filler_size = static_cast<int>(FixedArray::SizeFor(8192)); | 1525 int filler_size = static_cast<int>(FixedArray::SizeFor(8192)); |
| 1532 for (int i = 1; i <= 100; i++) { | 1526 for (int i = 1; i <= 100; i++) { |
| 1533 HEAP->AllocateFixedArray(8192, TENURED)->ToObjectChecked(); | 1527 CcTest::heap()->AllocateFixedArray(8192, TENURED)->ToObjectChecked(); |
| 1534 CHECK_EQ(initial_size + i * filler_size, | 1528 CHECK_EQ(initial_size + i * filler_size, |
| 1535 static_cast<int>(HEAP->SizeOfObjects())); | 1529 static_cast<int>(CcTest::heap()->SizeOfObjects())); |
| 1536 } | 1530 } |
| 1537 } | 1531 } |
| 1538 | 1532 |
| 1539 // 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 |
| 1540 // though sweeping didn't finish yet. | 1534 // though sweeping didn't finish yet. |
| 1541 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1535 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1542 | 1536 |
| 1543 // Normally sweeping would not be complete here, but no guarantees. | 1537 // Normally sweeping would not be complete here, but no guarantees. |
| 1544 | 1538 |
| 1545 CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects())); | 1539 CHECK_EQ(initial_size, static_cast<int>(CcTest::heap()->SizeOfObjects())); |
| 1546 | 1540 |
| 1547 // Advancing the sweeper step-wise should not change the heap size. | 1541 // Advancing the sweeper step-wise should not change the heap size. |
| 1548 while (!HEAP->old_pointer_space()->IsLazySweepingComplete()) { | 1542 while (!CcTest::heap()->old_pointer_space()->IsLazySweepingComplete()) { |
| 1549 HEAP->old_pointer_space()->AdvanceSweeper(KB); | 1543 CcTest::heap()->old_pointer_space()->AdvanceSweeper(KB); |
| 1550 CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects())); | 1544 CHECK_EQ(initial_size, static_cast<int>(CcTest::heap()->SizeOfObjects())); |
| 1551 } | 1545 } |
| 1552 } | 1546 } |
| 1553 | 1547 |
| 1554 | 1548 |
| 1555 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) { | 1549 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) { |
| 1556 CcTest::InitializeVM(); | 1550 CcTest::InitializeVM(); |
| 1557 HEAP->EnsureHeapIsIterable(); | 1551 CcTest::heap()->EnsureHeapIsIterable(); |
| 1558 intptr_t size_of_objects_1 = HEAP->SizeOfObjects(); | 1552 intptr_t size_of_objects_1 = CcTest::heap()->SizeOfObjects(); |
| 1559 HeapIterator iterator(HEAP); | 1553 HeapIterator iterator(CcTest::heap()); |
| 1560 intptr_t size_of_objects_2 = 0; | 1554 intptr_t size_of_objects_2 = 0; |
| 1561 for (HeapObject* obj = iterator.next(); | 1555 for (HeapObject* obj = iterator.next(); |
| 1562 obj != NULL; | 1556 obj != NULL; |
| 1563 obj = iterator.next()) { | 1557 obj = iterator.next()) { |
| 1564 if (!obj->IsFreeSpace()) { | 1558 if (!obj->IsFreeSpace()) { |
| 1565 size_of_objects_2 += obj->Size(); | 1559 size_of_objects_2 += obj->Size(); |
| 1566 } | 1560 } |
| 1567 } | 1561 } |
| 1568 // Delta must be within 5% of the larger result. | 1562 // Delta must be within 5% of the larger result. |
| 1569 // 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... |
| 1598 intptr_t available = new_space->EffectiveCapacity() - new_space->Size(); | 1592 intptr_t available = new_space->EffectiveCapacity() - new_space->Size(); |
| 1599 intptr_t number_of_fillers = (available / FixedArray::SizeFor(32)) - 1; | 1593 intptr_t number_of_fillers = (available / FixedArray::SizeFor(32)) - 1; |
| 1600 for (intptr_t i = 0; i < number_of_fillers; i++) { | 1594 for (intptr_t i = 0; i < number_of_fillers; i++) { |
| 1601 CHECK(heap->InNewSpace(*factory->NewFixedArray(32, NOT_TENURED))); | 1595 CHECK(heap->InNewSpace(*factory->NewFixedArray(32, NOT_TENURED))); |
| 1602 } | 1596 } |
| 1603 } | 1597 } |
| 1604 | 1598 |
| 1605 | 1599 |
| 1606 TEST(GrowAndShrinkNewSpace) { | 1600 TEST(GrowAndShrinkNewSpace) { |
| 1607 CcTest::InitializeVM(); | 1601 CcTest::InitializeVM(); |
| 1608 NewSpace* new_space = HEAP->new_space(); | 1602 Heap* heap = CcTest::heap(); |
| 1603 NewSpace* new_space = heap->new_space(); |
| 1609 | 1604 |
| 1610 if (HEAP->ReservedSemiSpaceSize() == HEAP->InitialSemiSpaceSize() || | 1605 if (heap->ReservedSemiSpaceSize() == heap->InitialSemiSpaceSize() || |
| 1611 HEAP->MaxSemiSpaceSize() == HEAP->InitialSemiSpaceSize()) { | 1606 heap->MaxSemiSpaceSize() == heap->InitialSemiSpaceSize()) { |
| 1612 // 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 |
| 1613 // 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 |
| 1614 // 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. |
| 1615 return; | 1610 return; |
| 1616 } | 1611 } |
| 1617 | 1612 |
| 1618 // Explicitly growing should double the space capacity. | 1613 // Explicitly growing should double the space capacity. |
| 1619 intptr_t old_capacity, new_capacity; | 1614 intptr_t old_capacity, new_capacity; |
| 1620 old_capacity = new_space->Capacity(); | 1615 old_capacity = new_space->Capacity(); |
| 1621 new_space->Grow(); | 1616 new_space->Grow(); |
| 1622 new_capacity = new_space->Capacity(); | 1617 new_capacity = new_space->Capacity(); |
| 1623 CHECK(2 * old_capacity == new_capacity); | 1618 CHECK(2 * old_capacity == new_capacity); |
| 1624 | 1619 |
| 1625 old_capacity = new_space->Capacity(); | 1620 old_capacity = new_space->Capacity(); |
| 1626 FillUpNewSpace(new_space); | 1621 FillUpNewSpace(new_space); |
| 1627 new_capacity = new_space->Capacity(); | 1622 new_capacity = new_space->Capacity(); |
| 1628 CHECK(old_capacity == new_capacity); | 1623 CHECK(old_capacity == new_capacity); |
| 1629 | 1624 |
| 1630 // Explicitly shrinking should not affect space capacity. | 1625 // Explicitly shrinking should not affect space capacity. |
| 1631 old_capacity = new_space->Capacity(); | 1626 old_capacity = new_space->Capacity(); |
| 1632 new_space->Shrink(); | 1627 new_space->Shrink(); |
| 1633 new_capacity = new_space->Capacity(); | 1628 new_capacity = new_space->Capacity(); |
| 1634 CHECK(old_capacity == new_capacity); | 1629 CHECK(old_capacity == new_capacity); |
| 1635 | 1630 |
| 1636 // Let the scavenger empty the new space. | 1631 // Let the scavenger empty the new space. |
| 1637 HEAP->CollectGarbage(NEW_SPACE); | 1632 heap->CollectGarbage(NEW_SPACE); |
| 1638 CHECK_LE(new_space->Size(), old_capacity); | 1633 CHECK_LE(new_space->Size(), old_capacity); |
| 1639 | 1634 |
| 1640 // Explicitly shrinking should halve the space capacity. | 1635 // Explicitly shrinking should halve the space capacity. |
| 1641 old_capacity = new_space->Capacity(); | 1636 old_capacity = new_space->Capacity(); |
| 1642 new_space->Shrink(); | 1637 new_space->Shrink(); |
| 1643 new_capacity = new_space->Capacity(); | 1638 new_capacity = new_space->Capacity(); |
| 1644 CHECK(old_capacity == 2 * new_capacity); | 1639 CHECK(old_capacity == 2 * new_capacity); |
| 1645 | 1640 |
| 1646 // Consecutive shrinking should not affect space capacity. | 1641 // Consecutive shrinking should not affect space capacity. |
| 1647 old_capacity = new_space->Capacity(); | 1642 old_capacity = new_space->Capacity(); |
| 1648 new_space->Shrink(); | 1643 new_space->Shrink(); |
| 1649 new_space->Shrink(); | 1644 new_space->Shrink(); |
| 1650 new_space->Shrink(); | 1645 new_space->Shrink(); |
| 1651 new_capacity = new_space->Capacity(); | 1646 new_capacity = new_space->Capacity(); |
| 1652 CHECK(old_capacity == new_capacity); | 1647 CHECK(old_capacity == new_capacity); |
| 1653 } | 1648 } |
| 1654 | 1649 |
| 1655 | 1650 |
| 1656 TEST(CollectingAllAvailableGarbageShrinksNewSpace) { | 1651 TEST(CollectingAllAvailableGarbageShrinksNewSpace) { |
| 1657 CcTest::InitializeVM(); | 1652 CcTest::InitializeVM(); |
| 1658 | 1653 Heap* heap = CcTest::heap(); |
| 1659 if (HEAP->ReservedSemiSpaceSize() == HEAP->InitialSemiSpaceSize() || | 1654 if (heap->ReservedSemiSpaceSize() == heap->InitialSemiSpaceSize() || |
| 1660 HEAP->MaxSemiSpaceSize() == HEAP->InitialSemiSpaceSize()) { | 1655 heap->MaxSemiSpaceSize() == heap->InitialSemiSpaceSize()) { |
| 1661 // 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 |
| 1662 // 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 |
| 1663 // 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. |
| 1664 return; | 1659 return; |
| 1665 } | 1660 } |
| 1666 | 1661 |
| 1667 v8::HandleScope scope(CcTest::isolate()); | 1662 v8::HandleScope scope(CcTest::isolate()); |
| 1668 NewSpace* new_space = HEAP->new_space(); | 1663 NewSpace* new_space = heap->new_space(); |
| 1669 intptr_t old_capacity, new_capacity; | 1664 intptr_t old_capacity, new_capacity; |
| 1670 old_capacity = new_space->Capacity(); | 1665 old_capacity = new_space->Capacity(); |
| 1671 new_space->Grow(); | 1666 new_space->Grow(); |
| 1672 new_capacity = new_space->Capacity(); | 1667 new_capacity = new_space->Capacity(); |
| 1673 CHECK(2 * old_capacity == new_capacity); | 1668 CHECK(2 * old_capacity == new_capacity); |
| 1674 FillUpNewSpace(new_space); | 1669 FillUpNewSpace(new_space); |
| 1675 HEAP->CollectAllAvailableGarbage(); | 1670 heap->CollectAllAvailableGarbage(); |
| 1676 new_capacity = new_space->Capacity(); | 1671 new_capacity = new_space->Capacity(); |
| 1677 CHECK(old_capacity == new_capacity); | 1672 CHECK(old_capacity == new_capacity); |
| 1678 } | 1673 } |
| 1679 | 1674 |
| 1680 | 1675 |
| 1681 static int NumberOfGlobalObjects() { | 1676 static int NumberOfGlobalObjects() { |
| 1682 int count = 0; | 1677 int count = 0; |
| 1683 HeapIterator iterator(HEAP); | 1678 HeapIterator iterator(CcTest::heap()); |
| 1684 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 1679 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 1685 if (obj->IsGlobalObject()) count++; | 1680 if (obj->IsGlobalObject()) count++; |
| 1686 } | 1681 } |
| 1687 return count; | 1682 return count; |
| 1688 } | 1683 } |
| 1689 | 1684 |
| 1690 | 1685 |
| 1691 // Test that we don't embed maps from foreign contexts into | 1686 // Test that we don't embed maps from foreign contexts into |
| 1692 // optimized code. | 1687 // optimized code. |
| 1693 TEST(LeakNativeContextViaMap) { | 1688 TEST(LeakNativeContextViaMap) { |
| 1694 i::FLAG_allow_natives_syntax = true; | 1689 i::FLAG_allow_natives_syntax = true; |
| 1695 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 1690 v8::Isolate* isolate = CcTest::isolate(); |
| 1696 v8::HandleScope outer_scope(isolate); | 1691 v8::HandleScope outer_scope(isolate); |
| 1697 v8::Persistent<v8::Context> ctx1p; | 1692 v8::Persistent<v8::Context> ctx1p; |
| 1698 v8::Persistent<v8::Context> ctx2p; | 1693 v8::Persistent<v8::Context> ctx2p; |
| 1699 { | 1694 { |
| 1700 v8::HandleScope scope(isolate); | 1695 v8::HandleScope scope(isolate); |
| 1701 ctx1p.Reset(isolate, v8::Context::New(isolate)); | 1696 ctx1p.Reset(isolate, v8::Context::New(isolate)); |
| 1702 ctx2p.Reset(isolate, v8::Context::New(isolate)); | 1697 ctx2p.Reset(isolate, v8::Context::New(isolate)); |
| 1703 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); | 1698 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); |
| 1704 } | 1699 } |
| 1705 | 1700 |
| 1706 HEAP->CollectAllAvailableGarbage(); | 1701 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1707 CHECK_EQ(4, NumberOfGlobalObjects()); | 1702 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 1708 | 1703 |
| 1709 { | 1704 { |
| 1710 v8::HandleScope inner_scope(isolate); | 1705 v8::HandleScope inner_scope(isolate); |
| 1711 CompileRun("var v = {x: 42}"); | 1706 CompileRun("var v = {x: 42}"); |
| 1712 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); |
| 1713 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); |
| 1714 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 1709 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 1715 ctx2->Enter(); | 1710 ctx2->Enter(); |
| 1716 ctx2->Global()->Set(v8_str("o"), v); | 1711 ctx2->Global()->Set(v8_str("o"), v); |
| 1717 v8::Local<v8::Value> res = CompileRun( | 1712 v8::Local<v8::Value> res = CompileRun( |
| 1718 "function f() { return o.x; }" | 1713 "function f() { return o.x; }" |
| 1719 "for (var i = 0; i < 10; ++i) f();" | 1714 "for (var i = 0; i < 10; ++i) f();" |
| 1720 "%OptimizeFunctionOnNextCall(f);" | 1715 "%OptimizeFunctionOnNextCall(f);" |
| 1721 "f();"); | 1716 "f();"); |
| 1722 CHECK_EQ(42, res->Int32Value()); | 1717 CHECK_EQ(42, res->Int32Value()); |
| 1723 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); | 1718 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
| 1724 ctx2->Exit(); | 1719 ctx2->Exit(); |
| 1725 v8::Local<v8::Context>::New(isolate, ctx1)->Exit(); | 1720 v8::Local<v8::Context>::New(isolate, ctx1)->Exit(); |
| 1726 ctx1p.Dispose(); | 1721 ctx1p.Dispose(); |
| 1727 v8::V8::ContextDisposedNotification(); | 1722 v8::V8::ContextDisposedNotification(); |
| 1728 } | 1723 } |
| 1729 HEAP->CollectAllAvailableGarbage(); | 1724 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1730 CHECK_EQ(2, NumberOfGlobalObjects()); | 1725 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 1731 ctx2p.Dispose(); | 1726 ctx2p.Dispose(); |
| 1732 HEAP->CollectAllAvailableGarbage(); | 1727 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1733 CHECK_EQ(0, NumberOfGlobalObjects()); | 1728 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 1734 } | 1729 } |
| 1735 | 1730 |
| 1736 | 1731 |
| 1737 // Test that we don't embed functions from foreign contexts into | 1732 // Test that we don't embed functions from foreign contexts into |
| 1738 // optimized code. | 1733 // optimized code. |
| 1739 TEST(LeakNativeContextViaFunction) { | 1734 TEST(LeakNativeContextViaFunction) { |
| 1740 i::FLAG_allow_natives_syntax = true; | 1735 i::FLAG_allow_natives_syntax = true; |
| 1741 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 1736 v8::Isolate* isolate = CcTest::isolate(); |
| 1742 v8::HandleScope outer_scope(isolate); | 1737 v8::HandleScope outer_scope(isolate); |
| 1743 v8::Persistent<v8::Context> ctx1p; | 1738 v8::Persistent<v8::Context> ctx1p; |
| 1744 v8::Persistent<v8::Context> ctx2p; | 1739 v8::Persistent<v8::Context> ctx2p; |
| 1745 { | 1740 { |
| 1746 v8::HandleScope scope(isolate); | 1741 v8::HandleScope scope(isolate); |
| 1747 ctx1p.Reset(isolate, v8::Context::New(isolate)); | 1742 ctx1p.Reset(isolate, v8::Context::New(isolate)); |
| 1748 ctx2p.Reset(isolate, v8::Context::New(isolate)); | 1743 ctx2p.Reset(isolate, v8::Context::New(isolate)); |
| 1749 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); | 1744 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); |
| 1750 } | 1745 } |
| 1751 | 1746 |
| 1752 HEAP->CollectAllAvailableGarbage(); | 1747 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1753 CHECK_EQ(4, NumberOfGlobalObjects()); | 1748 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 1754 | 1749 |
| 1755 { | 1750 { |
| 1756 v8::HandleScope inner_scope(isolate); | 1751 v8::HandleScope inner_scope(isolate); |
| 1757 CompileRun("var v = function() { return 42; }"); | 1752 CompileRun("var v = function() { return 42; }"); |
| 1758 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); |
| 1759 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); |
| 1760 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 1755 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 1761 ctx2->Enter(); | 1756 ctx2->Enter(); |
| 1762 ctx2->Global()->Set(v8_str("o"), v); | 1757 ctx2->Global()->Set(v8_str("o"), v); |
| 1763 v8::Local<v8::Value> res = CompileRun( | 1758 v8::Local<v8::Value> res = CompileRun( |
| 1764 "function f(x) { return x(); }" | 1759 "function f(x) { return x(); }" |
| 1765 "for (var i = 0; i < 10; ++i) f(o);" | 1760 "for (var i = 0; i < 10; ++i) f(o);" |
| 1766 "%OptimizeFunctionOnNextCall(f);" | 1761 "%OptimizeFunctionOnNextCall(f);" |
| 1767 "f(o);"); | 1762 "f(o);"); |
| 1768 CHECK_EQ(42, res->Int32Value()); | 1763 CHECK_EQ(42, res->Int32Value()); |
| 1769 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); | 1764 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
| 1770 ctx2->Exit(); | 1765 ctx2->Exit(); |
| 1771 ctx1->Exit(); | 1766 ctx1->Exit(); |
| 1772 ctx1p.Dispose(); | 1767 ctx1p.Dispose(); |
| 1773 v8::V8::ContextDisposedNotification(); | 1768 v8::V8::ContextDisposedNotification(); |
| 1774 } | 1769 } |
| 1775 HEAP->CollectAllAvailableGarbage(); | 1770 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1776 CHECK_EQ(2, NumberOfGlobalObjects()); | 1771 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 1777 ctx2p.Dispose(); | 1772 ctx2p.Dispose(); |
| 1778 HEAP->CollectAllAvailableGarbage(); | 1773 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1779 CHECK_EQ(0, NumberOfGlobalObjects()); | 1774 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 1780 } | 1775 } |
| 1781 | 1776 |
| 1782 | 1777 |
| 1783 TEST(LeakNativeContextViaMapKeyed) { | 1778 TEST(LeakNativeContextViaMapKeyed) { |
| 1784 i::FLAG_allow_natives_syntax = true; | 1779 i::FLAG_allow_natives_syntax = true; |
| 1785 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 1780 v8::Isolate* isolate = CcTest::isolate(); |
| 1786 v8::HandleScope outer_scope(isolate); | 1781 v8::HandleScope outer_scope(isolate); |
| 1787 v8::Persistent<v8::Context> ctx1p; | 1782 v8::Persistent<v8::Context> ctx1p; |
| 1788 v8::Persistent<v8::Context> ctx2p; | 1783 v8::Persistent<v8::Context> ctx2p; |
| 1789 { | 1784 { |
| 1790 v8::HandleScope scope(isolate); | 1785 v8::HandleScope scope(isolate); |
| 1791 ctx1p.Reset(isolate, v8::Context::New(isolate)); | 1786 ctx1p.Reset(isolate, v8::Context::New(isolate)); |
| 1792 ctx2p.Reset(isolate, v8::Context::New(isolate)); | 1787 ctx2p.Reset(isolate, v8::Context::New(isolate)); |
| 1793 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); | 1788 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); |
| 1794 } | 1789 } |
| 1795 | 1790 |
| 1796 HEAP->CollectAllAvailableGarbage(); | 1791 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1797 CHECK_EQ(4, NumberOfGlobalObjects()); | 1792 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 1798 | 1793 |
| 1799 { | 1794 { |
| 1800 v8::HandleScope inner_scope(isolate); | 1795 v8::HandleScope inner_scope(isolate); |
| 1801 CompileRun("var v = [42, 43]"); | 1796 CompileRun("var v = [42, 43]"); |
| 1802 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); |
| 1803 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); |
| 1804 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 1799 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 1805 ctx2->Enter(); | 1800 ctx2->Enter(); |
| 1806 ctx2->Global()->Set(v8_str("o"), v); | 1801 ctx2->Global()->Set(v8_str("o"), v); |
| 1807 v8::Local<v8::Value> res = CompileRun( | 1802 v8::Local<v8::Value> res = CompileRun( |
| 1808 "function f() { return o[0]; }" | 1803 "function f() { return o[0]; }" |
| 1809 "for (var i = 0; i < 10; ++i) f();" | 1804 "for (var i = 0; i < 10; ++i) f();" |
| 1810 "%OptimizeFunctionOnNextCall(f);" | 1805 "%OptimizeFunctionOnNextCall(f);" |
| 1811 "f();"); | 1806 "f();"); |
| 1812 CHECK_EQ(42, res->Int32Value()); | 1807 CHECK_EQ(42, res->Int32Value()); |
| 1813 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); | 1808 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
| 1814 ctx2->Exit(); | 1809 ctx2->Exit(); |
| 1815 ctx1->Exit(); | 1810 ctx1->Exit(); |
| 1816 ctx1p.Dispose(); | 1811 ctx1p.Dispose(); |
| 1817 v8::V8::ContextDisposedNotification(); | 1812 v8::V8::ContextDisposedNotification(); |
| 1818 } | 1813 } |
| 1819 HEAP->CollectAllAvailableGarbage(); | 1814 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1820 CHECK_EQ(2, NumberOfGlobalObjects()); | 1815 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 1821 ctx2p.Dispose(); | 1816 ctx2p.Dispose(); |
| 1822 HEAP->CollectAllAvailableGarbage(); | 1817 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1823 CHECK_EQ(0, NumberOfGlobalObjects()); | 1818 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 1824 } | 1819 } |
| 1825 | 1820 |
| 1826 | 1821 |
| 1827 TEST(LeakNativeContextViaMapProto) { | 1822 TEST(LeakNativeContextViaMapProto) { |
| 1828 i::FLAG_allow_natives_syntax = true; | 1823 i::FLAG_allow_natives_syntax = true; |
| 1829 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 1824 v8::Isolate* isolate = CcTest::isolate(); |
| 1830 v8::HandleScope outer_scope(isolate); | 1825 v8::HandleScope outer_scope(isolate); |
| 1831 v8::Persistent<v8::Context> ctx1p; | 1826 v8::Persistent<v8::Context> ctx1p; |
| 1832 v8::Persistent<v8::Context> ctx2p; | 1827 v8::Persistent<v8::Context> ctx2p; |
| 1833 { | 1828 { |
| 1834 v8::HandleScope scope(isolate); | 1829 v8::HandleScope scope(isolate); |
| 1835 ctx1p.Reset(isolate, v8::Context::New(isolate)); | 1830 ctx1p.Reset(isolate, v8::Context::New(isolate)); |
| 1836 ctx2p.Reset(isolate, v8::Context::New(isolate)); | 1831 ctx2p.Reset(isolate, v8::Context::New(isolate)); |
| 1837 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); | 1832 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); |
| 1838 } | 1833 } |
| 1839 | 1834 |
| 1840 HEAP->CollectAllAvailableGarbage(); | 1835 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1841 CHECK_EQ(4, NumberOfGlobalObjects()); | 1836 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 1842 | 1837 |
| 1843 { | 1838 { |
| 1844 v8::HandleScope inner_scope(isolate); | 1839 v8::HandleScope inner_scope(isolate); |
| 1845 CompileRun("var v = { y: 42}"); | 1840 CompileRun("var v = { y: 42}"); |
| 1846 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); |
| 1847 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); |
| 1848 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 1843 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 1849 ctx2->Enter(); | 1844 ctx2->Enter(); |
| 1850 ctx2->Global()->Set(v8_str("o"), v); | 1845 ctx2->Global()->Set(v8_str("o"), v); |
| 1851 v8::Local<v8::Value> res = CompileRun( | 1846 v8::Local<v8::Value> res = CompileRun( |
| 1852 "function f() {" | 1847 "function f() {" |
| 1853 " var p = {x: 42};" | 1848 " var p = {x: 42};" |
| 1854 " p.__proto__ = o;" | 1849 " p.__proto__ = o;" |
| 1855 " return p.x;" | 1850 " return p.x;" |
| 1856 "}" | 1851 "}" |
| 1857 "for (var i = 0; i < 10; ++i) f();" | 1852 "for (var i = 0; i < 10; ++i) f();" |
| 1858 "%OptimizeFunctionOnNextCall(f);" | 1853 "%OptimizeFunctionOnNextCall(f);" |
| 1859 "f();"); | 1854 "f();"); |
| 1860 CHECK_EQ(42, res->Int32Value()); | 1855 CHECK_EQ(42, res->Int32Value()); |
| 1861 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); | 1856 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
| 1862 ctx2->Exit(); | 1857 ctx2->Exit(); |
| 1863 ctx1->Exit(); | 1858 ctx1->Exit(); |
| 1864 ctx1p.Dispose(); | 1859 ctx1p.Dispose(); |
| 1865 v8::V8::ContextDisposedNotification(); | 1860 v8::V8::ContextDisposedNotification(); |
| 1866 } | 1861 } |
| 1867 HEAP->CollectAllAvailableGarbage(); | 1862 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1868 CHECK_EQ(2, NumberOfGlobalObjects()); | 1863 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 1869 ctx2p.Dispose(); | 1864 ctx2p.Dispose(); |
| 1870 HEAP->CollectAllAvailableGarbage(); | 1865 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1871 CHECK_EQ(0, NumberOfGlobalObjects()); | 1866 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 1872 } | 1867 } |
| 1873 | 1868 |
| 1874 | 1869 |
| 1875 TEST(InstanceOfStubWriteBarrier) { | 1870 TEST(InstanceOfStubWriteBarrier) { |
| 1876 i::FLAG_allow_natives_syntax = true; | 1871 i::FLAG_allow_natives_syntax = true; |
| 1877 #ifdef VERIFY_HEAP | 1872 #ifdef VERIFY_HEAP |
| 1878 i::FLAG_verify_heap = true; | 1873 i::FLAG_verify_heap = true; |
| 1879 #endif | 1874 #endif |
| 1880 | 1875 |
| 1881 CcTest::InitializeVM(); | 1876 CcTest::InitializeVM(); |
| 1882 if (!i::Isolate::Current()->use_crankshaft()) return; | 1877 if (!CcTest::i_isolate()->use_crankshaft()) return; |
| 1883 if (i::FLAG_force_marking_deque_overflows) return; | 1878 if (i::FLAG_force_marking_deque_overflows) return; |
| 1884 v8::HandleScope outer_scope(v8::Isolate::GetCurrent()); | 1879 v8::HandleScope outer_scope(CcTest::isolate()); |
| 1885 | 1880 |
| 1886 { | 1881 { |
| 1887 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1882 v8::HandleScope scope(CcTest::isolate()); |
| 1888 CompileRun( | 1883 CompileRun( |
| 1889 "function foo () { }" | 1884 "function foo () { }" |
| 1890 "function mkbar () { return new (new Function(\"\")) (); }" | 1885 "function mkbar () { return new (new Function(\"\")) (); }" |
| 1891 "function f (x) { return (x instanceof foo); }" | 1886 "function f (x) { return (x instanceof foo); }" |
| 1892 "function g () { f(mkbar()); }" | 1887 "function g () { f(mkbar()); }" |
| 1893 "f(new foo()); f(new foo());" | 1888 "f(new foo()); f(new foo());" |
| 1894 "%OptimizeFunctionOnNextCall(f);" | 1889 "%OptimizeFunctionOnNextCall(f);" |
| 1895 "f(new foo()); g();"); | 1890 "f(new foo()); g();"); |
| 1896 } | 1891 } |
| 1897 | 1892 |
| 1898 IncrementalMarking* marking = HEAP->incremental_marking(); | 1893 IncrementalMarking* marking = CcTest::heap()->incremental_marking(); |
| 1899 marking->Abort(); | 1894 marking->Abort(); |
| 1900 marking->Start(); | 1895 marking->Start(); |
| 1901 | 1896 |
| 1902 Handle<JSFunction> f = | 1897 Handle<JSFunction> f = |
| 1903 v8::Utils::OpenHandle( | 1898 v8::Utils::OpenHandle( |
| 1904 *v8::Handle<v8::Function>::Cast( | 1899 *v8::Handle<v8::Function>::Cast( |
| 1905 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 1900 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 1906 | 1901 |
| 1907 CHECK(f->IsOptimized()); | 1902 CHECK(f->IsOptimized()); |
| 1908 | 1903 |
| 1909 while (!Marking::IsBlack(Marking::MarkBitFrom(f->code())) && | 1904 while (!Marking::IsBlack(Marking::MarkBitFrom(f->code())) && |
| 1910 !marking->IsStopped()) { | 1905 !marking->IsStopped()) { |
| 1911 // 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 |
| 1912 // code below. | 1907 // code below. |
| 1913 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | 1908 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 1914 } | 1909 } |
| 1915 | 1910 |
| 1916 CHECK(marking->IsMarking()); | 1911 CHECK(marking->IsMarking()); |
| 1917 | 1912 |
| 1918 { | 1913 { |
| 1919 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1914 v8::HandleScope scope(CcTest::isolate()); |
| 1920 v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global(); | 1915 v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global(); |
| 1921 v8::Handle<v8::Function> g = | 1916 v8::Handle<v8::Function> g = |
| 1922 v8::Handle<v8::Function>::Cast(global->Get(v8_str("g"))); | 1917 v8::Handle<v8::Function>::Cast(global->Get(v8_str("g"))); |
| 1923 g->Call(global, 0, NULL); | 1918 g->Call(global, 0, NULL); |
| 1924 } | 1919 } |
| 1925 | 1920 |
| 1926 HEAP->incremental_marking()->set_should_hurry(true); | 1921 CcTest::heap()->incremental_marking()->set_should_hurry(true); |
| 1927 HEAP->CollectGarbage(OLD_POINTER_SPACE); | 1922 CcTest::heap()->CollectGarbage(OLD_POINTER_SPACE); |
| 1928 } | 1923 } |
| 1929 | 1924 |
| 1930 | 1925 |
| 1931 TEST(PrototypeTransitionClearing) { | 1926 TEST(PrototypeTransitionClearing) { |
| 1932 CcTest::InitializeVM(); | 1927 CcTest::InitializeVM(); |
| 1933 Isolate* isolate = Isolate::Current(); | 1928 Isolate* isolate = CcTest::i_isolate(); |
| 1934 Factory* factory = isolate->factory(); | 1929 Factory* factory = isolate->factory(); |
| 1935 v8::HandleScope scope(CcTest::isolate()); | 1930 v8::HandleScope scope(CcTest::isolate()); |
| 1936 | 1931 |
| 1937 CompileRun( | 1932 CompileRun( |
| 1938 "var base = {};" | 1933 "var base = {};" |
| 1939 "var live = [];" | 1934 "var live = [];" |
| 1940 "for (var i = 0; i < 10; i++) {" | 1935 "for (var i = 0; i < 10; i++) {" |
| 1941 " var object = {};" | 1936 " var object = {};" |
| 1942 " var prototype = {};" | 1937 " var prototype = {};" |
| 1943 " object.__proto__ = prototype;" | 1938 " object.__proto__ = prototype;" |
| 1944 " if (i >= 3) live.push(object, prototype);" | 1939 " if (i >= 3) live.push(object, prototype);" |
| 1945 "}"); | 1940 "}"); |
| 1946 | 1941 |
| 1947 Handle<JSObject> baseObject = | 1942 Handle<JSObject> baseObject = |
| 1948 v8::Utils::OpenHandle( | 1943 v8::Utils::OpenHandle( |
| 1949 *v8::Handle<v8::Object>::Cast( | 1944 *v8::Handle<v8::Object>::Cast( |
| 1950 v8::Context::GetCurrent()->Global()->Get(v8_str("base")))); | 1945 v8::Context::GetCurrent()->Global()->Get(v8_str("base")))); |
| 1951 | 1946 |
| 1952 // Verify that only dead prototype transitions are cleared. | 1947 // Verify that only dead prototype transitions are cleared. |
| 1953 CHECK_EQ(10, baseObject->map()->NumberOfProtoTransitions()); | 1948 CHECK_EQ(10, baseObject->map()->NumberOfProtoTransitions()); |
| 1954 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1949 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 1955 const int transitions = 10 - 3; | 1950 const int transitions = 10 - 3; |
| 1956 CHECK_EQ(transitions, baseObject->map()->NumberOfProtoTransitions()); | 1951 CHECK_EQ(transitions, baseObject->map()->NumberOfProtoTransitions()); |
| 1957 | 1952 |
| 1958 // Verify that prototype transitions array was compacted. | 1953 // Verify that prototype transitions array was compacted. |
| 1959 FixedArray* trans = baseObject->map()->GetPrototypeTransitions(); | 1954 FixedArray* trans = baseObject->map()->GetPrototypeTransitions(); |
| 1960 for (int i = 0; i < transitions; i++) { | 1955 for (int i = 0; i < transitions; i++) { |
| 1961 int j = Map::kProtoTransitionHeaderSize + | 1956 int j = Map::kProtoTransitionHeaderSize + |
| 1962 i * Map::kProtoTransitionElementsPerEntry; | 1957 i * Map::kProtoTransitionElementsPerEntry; |
| 1963 CHECK(trans->get(j + Map::kProtoTransitionMapOffset)->IsMap()); | 1958 CHECK(trans->get(j + Map::kProtoTransitionMapOffset)->IsMap()); |
| 1964 Object* proto = trans->get(j + Map::kProtoTransitionPrototypeOffset); | 1959 Object* proto = trans->get(j + Map::kProtoTransitionPrototypeOffset); |
| 1965 CHECK(proto->IsTheHole() || proto->IsJSObject()); | 1960 CHECK(proto->IsTheHole() || proto->IsJSObject()); |
| 1966 } | 1961 } |
| 1967 | 1962 |
| 1968 // 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. |
| 1969 Handle<JSObject> prototype; | 1964 Handle<JSObject> prototype; |
| 1970 PagedSpace* space = HEAP->old_pointer_space(); | 1965 PagedSpace* space = CcTest::heap()->old_pointer_space(); |
| 1971 { | 1966 { |
| 1972 AlwaysAllocateScope always_allocate; | 1967 AlwaysAllocateScope always_allocate; |
| 1973 SimulateFullSpace(space); | 1968 SimulateFullSpace(space); |
| 1974 prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED); | 1969 prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED); |
| 1975 } | 1970 } |
| 1976 | 1971 |
| 1977 // Add a prototype on an evacuation candidate and verify that transition | 1972 // Add a prototype on an evacuation candidate and verify that transition |
| 1978 // clearing correctly records slots in prototype transition array. | 1973 // clearing correctly records slots in prototype transition array. |
| 1979 i::FLAG_always_compact = true; | 1974 i::FLAG_always_compact = true; |
| 1980 Handle<Map> map(baseObject->map()); | 1975 Handle<Map> map(baseObject->map()); |
| 1981 CHECK(!space->LastPage()->Contains( | 1976 CHECK(!space->LastPage()->Contains( |
| 1982 map->GetPrototypeTransitions()->address())); | 1977 map->GetPrototypeTransitions()->address())); |
| 1983 CHECK(space->LastPage()->Contains(prototype->address())); | 1978 CHECK(space->LastPage()->Contains(prototype->address())); |
| 1984 JSObject::SetPrototype(baseObject, prototype, false); | 1979 JSObject::SetPrototype(baseObject, prototype, false); |
| 1985 CHECK(Map::GetPrototypeTransition(map, prototype)->IsMap()); | 1980 CHECK(Map::GetPrototypeTransition(map, prototype)->IsMap()); |
| 1986 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1981 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 1987 CHECK(Map::GetPrototypeTransition(map, prototype)->IsMap()); | 1982 CHECK(Map::GetPrototypeTransition(map, prototype)->IsMap()); |
| 1988 } | 1983 } |
| 1989 | 1984 |
| 1990 | 1985 |
| 1991 TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { | 1986 TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { |
| 1992 i::FLAG_stress_compaction = false; | 1987 i::FLAG_stress_compaction = false; |
| 1993 i::FLAG_allow_natives_syntax = true; | 1988 i::FLAG_allow_natives_syntax = true; |
| 1994 #ifdef VERIFY_HEAP | 1989 #ifdef VERIFY_HEAP |
| 1995 i::FLAG_verify_heap = true; | 1990 i::FLAG_verify_heap = true; |
| 1996 #endif | 1991 #endif |
| 1997 | 1992 |
| 1998 CcTest::InitializeVM(); | 1993 CcTest::InitializeVM(); |
| 1999 if (!i::Isolate::Current()->use_crankshaft()) return; | 1994 if (!CcTest::i_isolate()->use_crankshaft()) return; |
| 2000 v8::HandleScope outer_scope(v8::Isolate::GetCurrent()); | 1995 v8::HandleScope outer_scope(CcTest::isolate()); |
| 2001 | 1996 |
| 2002 { | 1997 { |
| 2003 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1998 v8::HandleScope scope(CcTest::isolate()); |
| 2004 CompileRun( | 1999 CompileRun( |
| 2005 "function f () {" | 2000 "function f () {" |
| 2006 " var s = 0;" | 2001 " var s = 0;" |
| 2007 " for (var i = 0; i < 100; i++) s += i;" | 2002 " for (var i = 0; i < 100; i++) s += i;" |
| 2008 " return s;" | 2003 " return s;" |
| 2009 "}" | 2004 "}" |
| 2010 "f(); f();" | 2005 "f(); f();" |
| 2011 "%OptimizeFunctionOnNextCall(f);" | 2006 "%OptimizeFunctionOnNextCall(f);" |
| 2012 "f();"); | 2007 "f();"); |
| 2013 } | 2008 } |
| 2014 Handle<JSFunction> f = | 2009 Handle<JSFunction> f = |
| 2015 v8::Utils::OpenHandle( | 2010 v8::Utils::OpenHandle( |
| 2016 *v8::Handle<v8::Function>::Cast( | 2011 *v8::Handle<v8::Function>::Cast( |
| 2017 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2012 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2018 CHECK(f->IsOptimized()); | 2013 CHECK(f->IsOptimized()); |
| 2019 | 2014 |
| 2020 IncrementalMarking* marking = HEAP->incremental_marking(); | 2015 IncrementalMarking* marking = CcTest::heap()->incremental_marking(); |
| 2021 marking->Abort(); | 2016 marking->Abort(); |
| 2022 marking->Start(); | 2017 marking->Start(); |
| 2023 | 2018 |
| 2024 // The following two calls will increment HEAP->global_ic_age(). | 2019 // The following two calls will increment CcTest::heap()->global_ic_age(). |
| 2025 const int kLongIdlePauseInMs = 1000; | 2020 const int kLongIdlePauseInMs = 1000; |
| 2026 v8::V8::ContextDisposedNotification(); | 2021 v8::V8::ContextDisposedNotification(); |
| 2027 v8::V8::IdleNotification(kLongIdlePauseInMs); | 2022 v8::V8::IdleNotification(kLongIdlePauseInMs); |
| 2028 | 2023 |
| 2029 while (!marking->IsStopped() && !marking->IsComplete()) { | 2024 while (!marking->IsStopped() && !marking->IsComplete()) { |
| 2030 marking->Step(1 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | 2025 marking->Step(1 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 2031 } | 2026 } |
| 2032 if (!marking->IsStopped() || marking->should_hurry()) { | 2027 if (!marking->IsStopped() || marking->should_hurry()) { |
| 2033 // 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 |
| 2034 // 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 |
| 2035 // 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 |
| 2036 // JS code running to trigger the interrupt, so we explicitly finalize | 2031 // JS code running to trigger the interrupt, so we explicitly finalize |
| 2037 // here. | 2032 // here. |
| 2038 HEAP->CollectAllGarbage(Heap::kNoGCFlags, | 2033 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 2039 "Test finalizing incremental mark-sweep"); | 2034 "Test finalizing incremental mark-sweep"); |
| 2040 } | 2035 } |
| 2041 | 2036 |
| 2042 CHECK_EQ(HEAP->global_ic_age(), f->shared()->ic_age()); | 2037 CHECK_EQ(CcTest::heap()->global_ic_age(), f->shared()->ic_age()); |
| 2043 CHECK_EQ(0, f->shared()->opt_count()); | 2038 CHECK_EQ(0, f->shared()->opt_count()); |
| 2044 CHECK_EQ(0, f->shared()->code()->profiler_ticks()); | 2039 CHECK_EQ(0, f->shared()->code()->profiler_ticks()); |
| 2045 } | 2040 } |
| 2046 | 2041 |
| 2047 | 2042 |
| 2048 TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) { | 2043 TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) { |
| 2049 i::FLAG_stress_compaction = false; | 2044 i::FLAG_stress_compaction = false; |
| 2050 i::FLAG_allow_natives_syntax = true; | 2045 i::FLAG_allow_natives_syntax = true; |
| 2051 #ifdef VERIFY_HEAP | 2046 #ifdef VERIFY_HEAP |
| 2052 i::FLAG_verify_heap = true; | 2047 i::FLAG_verify_heap = true; |
| 2053 #endif | 2048 #endif |
| 2054 | 2049 |
| 2055 CcTest::InitializeVM(); | 2050 CcTest::InitializeVM(); |
| 2056 if (!i::Isolate::Current()->use_crankshaft()) return; | 2051 if (!CcTest::i_isolate()->use_crankshaft()) return; |
| 2057 v8::HandleScope outer_scope(CcTest::isolate()); | 2052 v8::HandleScope outer_scope(CcTest::isolate()); |
| 2058 | 2053 |
| 2059 { | 2054 { |
| 2060 v8::HandleScope scope(CcTest::isolate()); | 2055 v8::HandleScope scope(CcTest::isolate()); |
| 2061 CompileRun( | 2056 CompileRun( |
| 2062 "function f () {" | 2057 "function f () {" |
| 2063 " var s = 0;" | 2058 " var s = 0;" |
| 2064 " for (var i = 0; i < 100; i++) s += i;" | 2059 " for (var i = 0; i < 100; i++) s += i;" |
| 2065 " return s;" | 2060 " return s;" |
| 2066 "}" | 2061 "}" |
| 2067 "f(); f();" | 2062 "f(); f();" |
| 2068 "%OptimizeFunctionOnNextCall(f);" | 2063 "%OptimizeFunctionOnNextCall(f);" |
| 2069 "f();"); | 2064 "f();"); |
| 2070 } | 2065 } |
| 2071 Handle<JSFunction> f = | 2066 Handle<JSFunction> f = |
| 2072 v8::Utils::OpenHandle( | 2067 v8::Utils::OpenHandle( |
| 2073 *v8::Handle<v8::Function>::Cast( | 2068 *v8::Handle<v8::Function>::Cast( |
| 2074 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2069 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2075 CHECK(f->IsOptimized()); | 2070 CHECK(f->IsOptimized()); |
| 2076 | 2071 |
| 2077 HEAP->incremental_marking()->Abort(); | 2072 CcTest::heap()->incremental_marking()->Abort(); |
| 2078 | 2073 |
| 2079 // The following two calls will increment HEAP->global_ic_age(). | 2074 // The following two calls will increment CcTest::heap()->global_ic_age(). |
| 2080 // Since incremental marking is off, IdleNotification will do full GC. | 2075 // Since incremental marking is off, IdleNotification will do full GC. |
| 2081 const int kLongIdlePauseInMs = 1000; | 2076 const int kLongIdlePauseInMs = 1000; |
| 2082 v8::V8::ContextDisposedNotification(); | 2077 v8::V8::ContextDisposedNotification(); |
| 2083 v8::V8::IdleNotification(kLongIdlePauseInMs); | 2078 v8::V8::IdleNotification(kLongIdlePauseInMs); |
| 2084 | 2079 |
| 2085 CHECK_EQ(HEAP->global_ic_age(), f->shared()->ic_age()); | 2080 CHECK_EQ(CcTest::heap()->global_ic_age(), f->shared()->ic_age()); |
| 2086 CHECK_EQ(0, f->shared()->opt_count()); | 2081 CHECK_EQ(0, f->shared()->opt_count()); |
| 2087 CHECK_EQ(0, f->shared()->code()->profiler_ticks()); | 2082 CHECK_EQ(0, f->shared()->code()->profiler_ticks()); |
| 2088 } | 2083 } |
| 2089 | 2084 |
| 2090 | 2085 |
| 2091 // Test that HAllocateObject will always return an object in new-space. | 2086 // Test that HAllocateObject will always return an object in new-space. |
| 2092 TEST(OptimizedAllocationAlwaysInNewSpace) { | 2087 TEST(OptimizedAllocationAlwaysInNewSpace) { |
| 2093 i::FLAG_allow_natives_syntax = true; | 2088 i::FLAG_allow_natives_syntax = true; |
| 2094 CcTest::InitializeVM(); | 2089 CcTest::InitializeVM(); |
| 2095 if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; | 2090 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2096 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2091 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2097 v8::HandleScope scope(CcTest::isolate()); | 2092 v8::HandleScope scope(CcTest::isolate()); |
| 2098 | 2093 |
| 2099 SimulateFullSpace(HEAP->new_space()); | 2094 SimulateFullSpace(CcTest::heap()->new_space()); |
| 2100 AlwaysAllocateScope always_allocate; | 2095 AlwaysAllocateScope always_allocate; |
| 2101 v8::Local<v8::Value> res = CompileRun( | 2096 v8::Local<v8::Value> res = CompileRun( |
| 2102 "function c(x) {" | 2097 "function c(x) {" |
| 2103 " this.x = x;" | 2098 " this.x = x;" |
| 2104 " for (var i = 0; i < 32; i++) {" | 2099 " for (var i = 0; i < 32; i++) {" |
| 2105 " this['x' + i] = x;" | 2100 " this['x' + i] = x;" |
| 2106 " }" | 2101 " }" |
| 2107 "}" | 2102 "}" |
| 2108 "function f(x) { return new c(x); };" | 2103 "function f(x) { return new c(x); };" |
| 2109 "f(1); f(2); f(3);" | 2104 "f(1); f(2); f(3);" |
| 2110 "%OptimizeFunctionOnNextCall(f);" | 2105 "%OptimizeFunctionOnNextCall(f);" |
| 2111 "f(4);"); | 2106 "f(4);"); |
| 2112 CHECK_EQ(4, res->ToObject()->GetRealNamedProperty(v8_str("x"))->Int32Value()); | 2107 CHECK_EQ(4, res->ToObject()->GetRealNamedProperty(v8_str("x"))->Int32Value()); |
| 2113 | 2108 |
| 2114 Handle<JSObject> o = | 2109 Handle<JSObject> o = |
| 2115 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2110 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2116 | 2111 |
| 2117 CHECK(HEAP->InNewSpace(*o)); | 2112 CHECK(CcTest::heap()->InNewSpace(*o)); |
| 2118 } | 2113 } |
| 2119 | 2114 |
| 2120 | 2115 |
| 2121 TEST(OptimizedPretenuringAllocationFolding) { | 2116 TEST(OptimizedPretenuringAllocationFolding) { |
| 2122 i::FLAG_allow_natives_syntax = true; | 2117 i::FLAG_allow_natives_syntax = true; |
| 2123 CcTest::InitializeVM(); | 2118 CcTest::InitializeVM(); |
| 2124 if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; | 2119 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2125 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2120 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2126 v8::HandleScope scope(CcTest::isolate()); | 2121 v8::HandleScope scope(CcTest::isolate()); |
| 2127 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2122 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2128 | 2123 |
| 2129 v8::Local<v8::Value> res = CompileRun( | 2124 v8::Local<v8::Value> res = CompileRun( |
| 2130 "function DataObject() {" | 2125 "function DataObject() {" |
| 2131 " this.a = 1.1;" | 2126 " this.a = 1.1;" |
| 2132 " this.b = [{}];" | 2127 " this.b = [{}];" |
| 2133 " this.c = 1.2;" | 2128 " this.c = 1.2;" |
| 2134 " this.d = [{}];" | 2129 " this.d = [{}];" |
| 2135 " this.e = 1.3;" | 2130 " this.e = 1.3;" |
| 2136 " this.f = [{}];" | 2131 " this.f = [{}];" |
| 2137 "}" | 2132 "}" |
| 2138 "function f() {" | 2133 "function f() {" |
| 2139 " return new DataObject();" | 2134 " return new DataObject();" |
| 2140 "};" | 2135 "};" |
| 2141 "f(); f(); f();" | 2136 "f(); f(); f();" |
| 2142 "%OptimizeFunctionOnNextCall(f);" | 2137 "%OptimizeFunctionOnNextCall(f);" |
| 2143 "f();"); | 2138 "f();"); |
| 2144 | 2139 |
| 2145 Handle<JSObject> o = | 2140 Handle<JSObject> o = |
| 2146 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2141 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2147 | 2142 |
| 2148 CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(0))); | 2143 CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(0))); |
| 2149 CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(1))); | 2144 CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(1))); |
| 2150 CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(2))); | 2145 CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(2))); |
| 2151 CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(3))); | 2146 CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(3))); |
| 2152 CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(4))); | 2147 CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(4))); |
| 2153 CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(5))); | 2148 CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(5))); |
| 2154 } | 2149 } |
| 2155 | 2150 |
| 2156 | 2151 |
| 2157 TEST(OptimizedPretenuringAllocationFoldingBlocks) { | 2152 TEST(OptimizedPretenuringAllocationFoldingBlocks) { |
| 2158 i::FLAG_allow_natives_syntax = true; | 2153 i::FLAG_allow_natives_syntax = true; |
| 2159 CcTest::InitializeVM(); | 2154 CcTest::InitializeVM(); |
| 2160 if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; | 2155 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2161 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2156 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2162 v8::HandleScope scope(CcTest::isolate()); | 2157 v8::HandleScope scope(CcTest::isolate()); |
| 2163 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2158 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2164 | 2159 |
| 2165 v8::Local<v8::Value> res = CompileRun( | 2160 v8::Local<v8::Value> res = CompileRun( |
| 2166 "function DataObject() {" | 2161 "function DataObject() {" |
| 2167 " this.a = [{}];" | 2162 " this.a = [{}];" |
| 2168 " this.b = [{}];" | 2163 " this.b = [{}];" |
| 2169 " this.c = 1.1;" | 2164 " this.c = 1.1;" |
| 2170 " this.d = 1.2;" | 2165 " this.d = 1.2;" |
| 2171 " this.e = [{}];" | 2166 " this.e = [{}];" |
| 2172 " this.f = 1.3;" | 2167 " this.f = 1.3;" |
| 2173 "}" | 2168 "}" |
| 2174 "function f() {" | 2169 "function f() {" |
| 2175 " return new DataObject();" | 2170 " return new DataObject();" |
| 2176 "};" | 2171 "};" |
| 2177 "f(); f(); f();" | 2172 "f(); f(); f();" |
| 2178 "%OptimizeFunctionOnNextCall(f);" | 2173 "%OptimizeFunctionOnNextCall(f);" |
| 2179 "f();"); | 2174 "f();"); |
| 2180 | 2175 |
| 2181 Handle<JSObject> o = | 2176 Handle<JSObject> o = |
| 2182 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2177 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2183 | 2178 |
| 2184 CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(0))); | 2179 CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(0))); |
| 2185 CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(1))); | 2180 CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(1))); |
| 2186 CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(2))); | 2181 CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(2))); |
| 2187 CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(3))); | 2182 CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(3))); |
| 2188 CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(4))); | 2183 CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(4))); |
| 2189 CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(5))); | 2184 CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(5))); |
| 2190 } | 2185 } |
| 2191 | 2186 |
| 2192 | 2187 |
| 2193 TEST(OptimizedPretenuringObjectArrayLiterals) { | 2188 TEST(OptimizedPretenuringObjectArrayLiterals) { |
| 2194 i::FLAG_allow_natives_syntax = true; | 2189 i::FLAG_allow_natives_syntax = true; |
| 2195 CcTest::InitializeVM(); | 2190 CcTest::InitializeVM(); |
| 2196 if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; | 2191 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2197 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2192 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2198 v8::HandleScope scope(CcTest::isolate()); | 2193 v8::HandleScope scope(CcTest::isolate()); |
| 2199 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2194 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2200 | 2195 |
| 2201 v8::Local<v8::Value> res = CompileRun( | 2196 v8::Local<v8::Value> res = CompileRun( |
| 2202 "function f() {" | 2197 "function f() {" |
| 2203 " var numbers = [{}, {}, {}];" | 2198 " var numbers = [{}, {}, {}];" |
| 2204 " return numbers;" | 2199 " return numbers;" |
| 2205 "};" | 2200 "};" |
| 2206 "f(); f(); f();" | 2201 "f(); f(); f();" |
| 2207 "%OptimizeFunctionOnNextCall(f);" | 2202 "%OptimizeFunctionOnNextCall(f);" |
| 2208 "f();"); | 2203 "f();"); |
| 2209 | 2204 |
| 2210 Handle<JSObject> o = | 2205 Handle<JSObject> o = |
| 2211 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2206 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2212 | 2207 |
| 2213 CHECK(HEAP->InOldPointerSpace(o->elements())); | 2208 CHECK(CcTest::heap()->InOldPointerSpace(o->elements())); |
| 2214 CHECK(HEAP->InOldPointerSpace(*o)); | 2209 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2215 } | 2210 } |
| 2216 | 2211 |
| 2217 | 2212 |
| 2218 TEST(OptimizedPretenuringMixedInObjectProperties) { | 2213 TEST(OptimizedPretenuringMixedInObjectProperties) { |
| 2219 i::FLAG_allow_natives_syntax = true; | 2214 i::FLAG_allow_natives_syntax = true; |
| 2220 CcTest::InitializeVM(); | 2215 CcTest::InitializeVM(); |
| 2221 if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; | 2216 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2222 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2217 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2223 v8::HandleScope scope(CcTest::isolate()); | 2218 v8::HandleScope scope(CcTest::isolate()); |
| 2224 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2219 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2225 | 2220 |
| 2226 v8::Local<v8::Value> res = CompileRun( | 2221 v8::Local<v8::Value> res = CompileRun( |
| 2227 "function f() {" | 2222 "function f() {" |
| 2228 " var numbers = {a: {c: 2.2, d: {}}, b: 1.1};" | 2223 " var numbers = {a: {c: 2.2, d: {}}, b: 1.1};" |
| 2229 " return numbers;" | 2224 " return numbers;" |
| 2230 "};" | 2225 "};" |
| 2231 "f(); f(); f();" | 2226 "f(); f(); f();" |
| 2232 "%OptimizeFunctionOnNextCall(f);" | 2227 "%OptimizeFunctionOnNextCall(f);" |
| 2233 "f();"); | 2228 "f();"); |
| 2234 | 2229 |
| 2235 Handle<JSObject> o = | 2230 Handle<JSObject> o = |
| 2236 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2231 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2237 | 2232 |
| 2238 CHECK(HEAP->InOldPointerSpace(*o)); | 2233 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2239 CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(0))); | 2234 CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(0))); |
| 2240 CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(1))); | 2235 CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(1))); |
| 2241 | 2236 |
| 2242 JSObject* inner_object = reinterpret_cast<JSObject*>(o->RawFastPropertyAt(0)); | 2237 JSObject* inner_object = reinterpret_cast<JSObject*>(o->RawFastPropertyAt(0)); |
| 2243 CHECK(HEAP->InOldPointerSpace(inner_object)); | 2238 CHECK(CcTest::heap()->InOldPointerSpace(inner_object)); |
| 2244 CHECK(HEAP->InOldDataSpace(inner_object->RawFastPropertyAt(0))); | 2239 CHECK(CcTest::heap()->InOldDataSpace(inner_object->RawFastPropertyAt(0))); |
| 2245 CHECK(HEAP->InOldPointerSpace(inner_object->RawFastPropertyAt(1))); | 2240 CHECK(CcTest::heap()->InOldPointerSpace(inner_object->RawFastPropertyAt(1))); |
| 2246 } | 2241 } |
| 2247 | 2242 |
| 2248 | 2243 |
| 2249 TEST(OptimizedPretenuringDoubleArrayProperties) { | 2244 TEST(OptimizedPretenuringDoubleArrayProperties) { |
| 2250 i::FLAG_allow_natives_syntax = true; | 2245 i::FLAG_allow_natives_syntax = true; |
| 2251 CcTest::InitializeVM(); | 2246 CcTest::InitializeVM(); |
| 2252 if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; | 2247 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2253 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2248 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2254 v8::HandleScope scope(CcTest::isolate()); | 2249 v8::HandleScope scope(CcTest::isolate()); |
| 2255 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2250 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2256 | 2251 |
| 2257 v8::Local<v8::Value> res = CompileRun( | 2252 v8::Local<v8::Value> res = CompileRun( |
| 2258 "function f() {" | 2253 "function f() {" |
| 2259 " var numbers = {a: 1.1, b: 2.2};" | 2254 " var numbers = {a: 1.1, b: 2.2};" |
| 2260 " return numbers;" | 2255 " return numbers;" |
| 2261 "};" | 2256 "};" |
| 2262 "f(); f(); f();" | 2257 "f(); f(); f();" |
| 2263 "%OptimizeFunctionOnNextCall(f);" | 2258 "%OptimizeFunctionOnNextCall(f);" |
| 2264 "f();"); | 2259 "f();"); |
| 2265 | 2260 |
| 2266 Handle<JSObject> o = | 2261 Handle<JSObject> o = |
| 2267 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2262 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2268 | 2263 |
| 2269 CHECK(HEAP->InOldPointerSpace(*o)); | 2264 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2270 CHECK(HEAP->InOldDataSpace(o->properties())); | 2265 CHECK(CcTest::heap()->InOldDataSpace(o->properties())); |
| 2271 } | 2266 } |
| 2272 | 2267 |
| 2273 | 2268 |
| 2274 TEST(OptimizedPretenuringdoubleArrayLiterals) { | 2269 TEST(OptimizedPretenuringdoubleArrayLiterals) { |
| 2275 i::FLAG_allow_natives_syntax = true; | 2270 i::FLAG_allow_natives_syntax = true; |
| 2276 CcTest::InitializeVM(); | 2271 CcTest::InitializeVM(); |
| 2277 if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; | 2272 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2278 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2273 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2279 v8::HandleScope scope(CcTest::isolate()); | 2274 v8::HandleScope scope(CcTest::isolate()); |
| 2280 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2275 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2281 | 2276 |
| 2282 v8::Local<v8::Value> res = CompileRun( | 2277 v8::Local<v8::Value> res = CompileRun( |
| 2283 "function f() {" | 2278 "function f() {" |
| 2284 " var numbers = [1.1, 2.2, 3.3];" | 2279 " var numbers = [1.1, 2.2, 3.3];" |
| 2285 " return numbers;" | 2280 " return numbers;" |
| 2286 "};" | 2281 "};" |
| 2287 "f(); f(); f();" | 2282 "f(); f(); f();" |
| 2288 "%OptimizeFunctionOnNextCall(f);" | 2283 "%OptimizeFunctionOnNextCall(f);" |
| 2289 "f();"); | 2284 "f();"); |
| 2290 | 2285 |
| 2291 Handle<JSObject> o = | 2286 Handle<JSObject> o = |
| 2292 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2287 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2293 | 2288 |
| 2294 CHECK(HEAP->InOldDataSpace(o->elements())); | 2289 CHECK(CcTest::heap()->InOldDataSpace(o->elements())); |
| 2295 CHECK(HEAP->InOldPointerSpace(*o)); | 2290 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2296 } | 2291 } |
| 2297 | 2292 |
| 2298 | 2293 |
| 2299 TEST(OptimizedPretenuringNestedMixedArrayLiterals) { | 2294 TEST(OptimizedPretenuringNestedMixedArrayLiterals) { |
| 2300 i::FLAG_allow_natives_syntax = true; | 2295 i::FLAG_allow_natives_syntax = true; |
| 2301 CcTest::InitializeVM(); | 2296 CcTest::InitializeVM(); |
| 2302 if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; | 2297 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2303 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2298 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2304 v8::HandleScope scope(CcTest::isolate()); | 2299 v8::HandleScope scope(CcTest::isolate()); |
| 2305 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2300 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2306 | 2301 |
| 2307 v8::Local<v8::Value> res = CompileRun( | 2302 v8::Local<v8::Value> res = CompileRun( |
| 2308 "function f() {" | 2303 "function f() {" |
| 2309 " var numbers = [[{}, {}, {}],[1.1, 2.2, 3.3]];" | 2304 " var numbers = [[{}, {}, {}],[1.1, 2.2, 3.3]];" |
| 2310 " return numbers;" | 2305 " return numbers;" |
| 2311 "};" | 2306 "};" |
| 2312 "f(); f(); f();" | 2307 "f(); f(); f();" |
| 2313 "%OptimizeFunctionOnNextCall(f);" | 2308 "%OptimizeFunctionOnNextCall(f);" |
| 2314 "f();"); | 2309 "f();"); |
| 2315 | 2310 |
| 2316 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")); |
| 2317 Handle<JSObject> int_array_handle = | 2312 Handle<JSObject> int_array_handle = |
| 2318 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array)); | 2313 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array)); |
| 2319 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")); |
| 2320 Handle<JSObject> double_array_handle = | 2315 Handle<JSObject> double_array_handle = |
| 2321 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array)); | 2316 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array)); |
| 2322 | 2317 |
| 2323 Handle<JSObject> o = | 2318 Handle<JSObject> o = |
| 2324 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2319 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2325 CHECK(HEAP->InOldPointerSpace(*o)); | 2320 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2326 CHECK(HEAP->InOldPointerSpace(*int_array_handle)); | 2321 CHECK(CcTest::heap()->InOldPointerSpace(*int_array_handle)); |
| 2327 CHECK(HEAP->InOldPointerSpace(int_array_handle->elements())); | 2322 CHECK(CcTest::heap()->InOldPointerSpace(int_array_handle->elements())); |
| 2328 CHECK(HEAP->InOldPointerSpace(*double_array_handle)); | 2323 CHECK(CcTest::heap()->InOldPointerSpace(*double_array_handle)); |
| 2329 CHECK(HEAP->InOldDataSpace(double_array_handle->elements())); | 2324 CHECK(CcTest::heap()->InOldDataSpace(double_array_handle->elements())); |
| 2330 } | 2325 } |
| 2331 | 2326 |
| 2332 | 2327 |
| 2333 TEST(OptimizedPretenuringNestedObjectLiterals) { | 2328 TEST(OptimizedPretenuringNestedObjectLiterals) { |
| 2334 i::FLAG_allow_natives_syntax = true; | 2329 i::FLAG_allow_natives_syntax = true; |
| 2335 CcTest::InitializeVM(); | 2330 CcTest::InitializeVM(); |
| 2336 if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; | 2331 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2337 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2332 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2338 v8::HandleScope scope(CcTest::isolate()); | 2333 v8::HandleScope scope(CcTest::isolate()); |
| 2339 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2334 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2340 | 2335 |
| 2341 v8::Local<v8::Value> res = CompileRun( | 2336 v8::Local<v8::Value> res = CompileRun( |
| 2342 "function f() {" | 2337 "function f() {" |
| 2343 " var numbers = [[{}, {}, {}],[{}, {}, {}]];" | 2338 " var numbers = [[{}, {}, {}],[{}, {}, {}]];" |
| 2344 " return numbers;" | 2339 " return numbers;" |
| 2345 "};" | 2340 "};" |
| 2346 "f(); f(); f();" | 2341 "f(); f(); f();" |
| 2347 "%OptimizeFunctionOnNextCall(f);" | 2342 "%OptimizeFunctionOnNextCall(f);" |
| 2348 "f();"); | 2343 "f();"); |
| 2349 | 2344 |
| 2350 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")); |
| 2351 Handle<JSObject> int_array_handle_1 = | 2346 Handle<JSObject> int_array_handle_1 = |
| 2352 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array_1)); | 2347 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array_1)); |
| 2353 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")); |
| 2354 Handle<JSObject> int_array_handle_2 = | 2349 Handle<JSObject> int_array_handle_2 = |
| 2355 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array_2)); | 2350 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array_2)); |
| 2356 | 2351 |
| 2357 Handle<JSObject> o = | 2352 Handle<JSObject> o = |
| 2358 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2353 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2359 CHECK(HEAP->InOldPointerSpace(*o)); | 2354 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2360 CHECK(HEAP->InOldPointerSpace(*int_array_handle_1)); | 2355 CHECK(CcTest::heap()->InOldPointerSpace(*int_array_handle_1)); |
| 2361 CHECK(HEAP->InOldPointerSpace(int_array_handle_1->elements())); | 2356 CHECK(CcTest::heap()->InOldPointerSpace(int_array_handle_1->elements())); |
| 2362 CHECK(HEAP->InOldPointerSpace(*int_array_handle_2)); | 2357 CHECK(CcTest::heap()->InOldPointerSpace(*int_array_handle_2)); |
| 2363 CHECK(HEAP->InOldPointerSpace(int_array_handle_2->elements())); | 2358 CHECK(CcTest::heap()->InOldPointerSpace(int_array_handle_2->elements())); |
| 2364 } | 2359 } |
| 2365 | 2360 |
| 2366 | 2361 |
| 2367 TEST(OptimizedPretenuringNestedDoubleLiterals) { | 2362 TEST(OptimizedPretenuringNestedDoubleLiterals) { |
| 2368 i::FLAG_allow_natives_syntax = true; | 2363 i::FLAG_allow_natives_syntax = true; |
| 2369 CcTest::InitializeVM(); | 2364 CcTest::InitializeVM(); |
| 2370 if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; | 2365 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2371 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2366 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2372 v8::HandleScope scope(CcTest::isolate()); | 2367 v8::HandleScope scope(CcTest::isolate()); |
| 2373 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2368 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2374 | 2369 |
| 2375 v8::Local<v8::Value> res = CompileRun( | 2370 v8::Local<v8::Value> res = CompileRun( |
| 2376 "function f() {" | 2371 "function f() {" |
| 2377 " 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]];" |
| 2378 " return numbers;" | 2373 " return numbers;" |
| 2379 "};" | 2374 "};" |
| 2380 "f(); f(); f();" | 2375 "f(); f(); f();" |
| 2381 "%OptimizeFunctionOnNextCall(f);" | 2376 "%OptimizeFunctionOnNextCall(f);" |
| 2382 "f();"); | 2377 "f();"); |
| 2383 | 2378 |
| 2384 v8::Local<v8::Value> double_array_1 = | 2379 v8::Local<v8::Value> double_array_1 = |
| 2385 v8::Object::Cast(*res)->Get(v8_str("0")); | 2380 v8::Object::Cast(*res)->Get(v8_str("0")); |
| 2386 Handle<JSObject> double_array_handle_1 = | 2381 Handle<JSObject> double_array_handle_1 = |
| 2387 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array_1)); | 2382 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array_1)); |
| 2388 v8::Local<v8::Value> double_array_2 = | 2383 v8::Local<v8::Value> double_array_2 = |
| 2389 v8::Object::Cast(*res)->Get(v8_str("1")); | 2384 v8::Object::Cast(*res)->Get(v8_str("1")); |
| 2390 Handle<JSObject> double_array_handle_2 = | 2385 Handle<JSObject> double_array_handle_2 = |
| 2391 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array_2)); | 2386 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array_2)); |
| 2392 | 2387 |
| 2393 Handle<JSObject> o = | 2388 Handle<JSObject> o = |
| 2394 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2389 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2395 CHECK(HEAP->InOldPointerSpace(*o)); | 2390 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2396 CHECK(HEAP->InOldPointerSpace(*double_array_handle_1)); | 2391 CHECK(CcTest::heap()->InOldPointerSpace(*double_array_handle_1)); |
| 2397 CHECK(HEAP->InOldDataSpace(double_array_handle_1->elements())); | 2392 CHECK(CcTest::heap()->InOldDataSpace(double_array_handle_1->elements())); |
| 2398 CHECK(HEAP->InOldPointerSpace(*double_array_handle_2)); | 2393 CHECK(CcTest::heap()->InOldPointerSpace(*double_array_handle_2)); |
| 2399 CHECK(HEAP->InOldDataSpace(double_array_handle_2->elements())); | 2394 CHECK(CcTest::heap()->InOldDataSpace(double_array_handle_2->elements())); |
| 2400 } | 2395 } |
| 2401 | 2396 |
| 2402 | 2397 |
| 2403 // Test regular array literals allocation. | 2398 // Test regular array literals allocation. |
| 2404 TEST(OptimizedAllocationArrayLiterals) { | 2399 TEST(OptimizedAllocationArrayLiterals) { |
| 2405 i::FLAG_allow_natives_syntax = true; | 2400 i::FLAG_allow_natives_syntax = true; |
| 2406 CcTest::InitializeVM(); | 2401 CcTest::InitializeVM(); |
| 2407 if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; | 2402 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2408 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2403 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2409 v8::HandleScope scope(CcTest::isolate()); | 2404 v8::HandleScope scope(CcTest::isolate()); |
| 2410 | 2405 |
| 2411 v8::Local<v8::Value> res = CompileRun( | 2406 v8::Local<v8::Value> res = CompileRun( |
| 2412 "function f() {" | 2407 "function f() {" |
| 2413 " var numbers = new Array(1, 2, 3);" | 2408 " var numbers = new Array(1, 2, 3);" |
| 2414 " numbers[0] = 3.14;" | 2409 " numbers[0] = 3.14;" |
| 2415 " return numbers;" | 2410 " return numbers;" |
| 2416 "};" | 2411 "};" |
| 2417 "f(); f(); f();" | 2412 "f(); f(); f();" |
| 2418 "%OptimizeFunctionOnNextCall(f);" | 2413 "%OptimizeFunctionOnNextCall(f);" |
| 2419 "f();"); | 2414 "f();"); |
| 2420 CHECK_EQ(static_cast<int>(3.14), | 2415 CHECK_EQ(static_cast<int>(3.14), |
| 2421 v8::Object::Cast(*res)->Get(v8_str("0"))->Int32Value()); | 2416 v8::Object::Cast(*res)->Get(v8_str("0"))->Int32Value()); |
| 2422 | 2417 |
| 2423 Handle<JSObject> o = | 2418 Handle<JSObject> o = |
| 2424 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2419 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2425 | 2420 |
| 2426 CHECK(HEAP->InNewSpace(o->elements())); | 2421 CHECK(CcTest::heap()->InNewSpace(o->elements())); |
| 2427 } | 2422 } |
| 2428 | 2423 |
| 2429 | 2424 |
| 2430 TEST(OptimizedPretenuringCallNew) { | 2425 TEST(OptimizedPretenuringCallNew) { |
| 2431 i::FLAG_allow_natives_syntax = true; | 2426 i::FLAG_allow_natives_syntax = true; |
| 2432 i::FLAG_pretenuring_call_new = true; | 2427 i::FLAG_pretenuring_call_new = true; |
| 2433 CcTest::InitializeVM(); | 2428 CcTest::InitializeVM(); |
| 2434 if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; | 2429 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2435 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2430 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2436 v8::HandleScope scope(CcTest::isolate()); | 2431 v8::HandleScope scope(CcTest::isolate()); |
| 2437 HEAP->SetNewSpaceHighPromotionModeActive(true); | 2432 CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); |
| 2438 | 2433 |
| 2439 AlwaysAllocateScope always_allocate; | 2434 AlwaysAllocateScope always_allocate; |
| 2440 v8::Local<v8::Value> res = CompileRun( | 2435 v8::Local<v8::Value> res = CompileRun( |
| 2441 "function g() { this.a = 0; }" | 2436 "function g() { this.a = 0; }" |
| 2442 "function f() {" | 2437 "function f() {" |
| 2443 " return new g();" | 2438 " return new g();" |
| 2444 "};" | 2439 "};" |
| 2445 "f(); f(); f();" | 2440 "f(); f(); f();" |
| 2446 "%OptimizeFunctionOnNextCall(f);" | 2441 "%OptimizeFunctionOnNextCall(f);" |
| 2447 "f();"); | 2442 "f();"); |
| 2448 | 2443 |
| 2449 Handle<JSObject> o = | 2444 Handle<JSObject> o = |
| 2450 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2445 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2451 CHECK(HEAP->InOldPointerSpace(*o)); | 2446 CHECK(CcTest::heap()->InOldPointerSpace(*o)); |
| 2452 } | 2447 } |
| 2453 | 2448 |
| 2454 | 2449 |
| 2455 static int CountMapTransitions(Map* map) { | 2450 static int CountMapTransitions(Map* map) { |
| 2456 return map->transitions()->number_of_transitions(); | 2451 return map->transitions()->number_of_transitions(); |
| 2457 } | 2452 } |
| 2458 | 2453 |
| 2459 | 2454 |
| 2460 // Test that map transitions are cleared and maps are collected with | 2455 // Test that map transitions are cleared and maps are collected with |
| 2461 // incremental marking as well. | 2456 // incremental marking as well. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2481 v8::Utils::OpenHandle( | 2476 v8::Utils::OpenHandle( |
| 2482 *v8::Handle<v8::Object>::Cast( | 2477 *v8::Handle<v8::Object>::Cast( |
| 2483 v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); | 2478 v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); |
| 2484 | 2479 |
| 2485 // Count number of live transitions before marking. | 2480 // Count number of live transitions before marking. |
| 2486 int transitions_before = CountMapTransitions(root->map()); | 2481 int transitions_before = CountMapTransitions(root->map()); |
| 2487 CompileRun("%DebugPrint(root);"); | 2482 CompileRun("%DebugPrint(root);"); |
| 2488 CHECK_EQ(transitions_count, transitions_before); | 2483 CHECK_EQ(transitions_count, transitions_before); |
| 2489 | 2484 |
| 2490 SimulateIncrementalMarking(); | 2485 SimulateIncrementalMarking(); |
| 2491 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2486 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2492 | 2487 |
| 2493 // Count number of live transitions after marking. Note that one transition | 2488 // Count number of live transitions after marking. Note that one transition |
| 2494 // 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. |
| 2495 int transitions_after = CountMapTransitions(root->map()); | 2490 int transitions_after = CountMapTransitions(root->map()); |
| 2496 CompileRun("%DebugPrint(root);"); | 2491 CompileRun("%DebugPrint(root);"); |
| 2497 CHECK_EQ(1, transitions_after); | 2492 CHECK_EQ(1, transitions_after); |
| 2498 } | 2493 } |
| 2499 | 2494 |
| 2500 | 2495 |
| 2501 TEST(Regress2143a) { | 2496 TEST(Regress2143a) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2515 // Compile a StoreIC that performs the prepared map transition. This | 2510 // Compile a StoreIC that performs the prepared map transition. This |
| 2516 // will restart incremental marking and should make sure the root is | 2511 // will restart incremental marking and should make sure the root is |
| 2517 // marked grey again. | 2512 // marked grey again. |
| 2518 CompileRun("function f(o) {" | 2513 CompileRun("function f(o) {" |
| 2519 " o.foo = 0;" | 2514 " o.foo = 0;" |
| 2520 "}" | 2515 "}" |
| 2521 "f(new Object);" | 2516 "f(new Object);" |
| 2522 "f(root);"); | 2517 "f(root);"); |
| 2523 | 2518 |
| 2524 // This bug only triggers with aggressive IC clearing. | 2519 // This bug only triggers with aggressive IC clearing. |
| 2525 HEAP->AgeInlineCaches(); | 2520 CcTest::heap()->AgeInlineCaches(); |
| 2526 | 2521 |
| 2527 // Explicitly request GC to perform final marking step and sweeping. | 2522 // Explicitly request GC to perform final marking step and sweeping. |
| 2528 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2523 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2529 | 2524 |
| 2530 Handle<JSObject> root = | 2525 Handle<JSObject> root = |
| 2531 v8::Utils::OpenHandle( | 2526 v8::Utils::OpenHandle( |
| 2532 *v8::Handle<v8::Object>::Cast( | 2527 *v8::Handle<v8::Object>::Cast( |
| 2533 v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); | 2528 v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); |
| 2534 | 2529 |
| 2535 // The root object should be in a sane state. | 2530 // The root object should be in a sane state. |
| 2536 CHECK(root->IsJSObject()); | 2531 CHECK(root->IsJSObject()); |
| 2537 CHECK(root->map()->IsMap()); | 2532 CHECK(root->map()->IsMap()); |
| 2538 } | 2533 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2559 CompileRun("function f(o) {" | 2554 CompileRun("function f(o) {" |
| 2560 " o.foo = 0;" | 2555 " o.foo = 0;" |
| 2561 "}" | 2556 "}" |
| 2562 "f(new Object);" | 2557 "f(new Object);" |
| 2563 "f(new Object);" | 2558 "f(new Object);" |
| 2564 "%OptimizeFunctionOnNextCall(f);" | 2559 "%OptimizeFunctionOnNextCall(f);" |
| 2565 "f(root);" | 2560 "f(root);" |
| 2566 "%DeoptimizeFunction(f);"); | 2561 "%DeoptimizeFunction(f);"); |
| 2567 | 2562 |
| 2568 // This bug only triggers with aggressive IC clearing. | 2563 // This bug only triggers with aggressive IC clearing. |
| 2569 HEAP->AgeInlineCaches(); | 2564 CcTest::heap()->AgeInlineCaches(); |
| 2570 | 2565 |
| 2571 // Explicitly request GC to perform final marking step and sweeping. | 2566 // Explicitly request GC to perform final marking step and sweeping. |
| 2572 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2567 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2573 | 2568 |
| 2574 Handle<JSObject> root = | 2569 Handle<JSObject> root = |
| 2575 v8::Utils::OpenHandle( | 2570 v8::Utils::OpenHandle( |
| 2576 *v8::Handle<v8::Object>::Cast( | 2571 *v8::Handle<v8::Object>::Cast( |
| 2577 v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); | 2572 v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); |
| 2578 | 2573 |
| 2579 // The root object should be in a sane state. | 2574 // The root object should be in a sane state. |
| 2580 CHECK(root->IsJSObject()); | 2575 CHECK(root->IsJSObject()); |
| 2581 CHECK(root->map()->IsMap()); | 2576 CHECK(root->map()->IsMap()); |
| 2582 } | 2577 } |
| 2583 | 2578 |
| 2584 | 2579 |
| 2585 TEST(ReleaseOverReservedPages) { | 2580 TEST(ReleaseOverReservedPages) { |
| 2586 i::FLAG_trace_gc = true; | 2581 i::FLAG_trace_gc = true; |
| 2587 // The optimizer can allocate stuff, messing up the test. | 2582 // The optimizer can allocate stuff, messing up the test. |
| 2588 i::FLAG_crankshaft = false; | 2583 i::FLAG_crankshaft = false; |
| 2589 i::FLAG_always_opt = false; | 2584 i::FLAG_always_opt = false; |
| 2590 CcTest::InitializeVM(); | 2585 CcTest::InitializeVM(); |
| 2591 Isolate* isolate = Isolate::Current(); | 2586 Isolate* isolate = CcTest::i_isolate(); |
| 2592 Factory* factory = isolate->factory(); | 2587 Factory* factory = isolate->factory(); |
| 2588 Heap* heap = isolate->heap(); |
| 2593 v8::HandleScope scope(CcTest::isolate()); | 2589 v8::HandleScope scope(CcTest::isolate()); |
| 2594 static const int number_of_test_pages = 20; | 2590 static const int number_of_test_pages = 20; |
| 2595 | 2591 |
| 2596 // Prepare many pages with low live-bytes count. | 2592 // Prepare many pages with low live-bytes count. |
| 2597 PagedSpace* old_pointer_space = HEAP->old_pointer_space(); | 2593 PagedSpace* old_pointer_space = heap->old_pointer_space(); |
| 2598 CHECK_EQ(1, old_pointer_space->CountTotalPages()); | 2594 CHECK_EQ(1, old_pointer_space->CountTotalPages()); |
| 2599 for (int i = 0; i < number_of_test_pages; i++) { | 2595 for (int i = 0; i < number_of_test_pages; i++) { |
| 2600 AlwaysAllocateScope always_allocate; | 2596 AlwaysAllocateScope always_allocate; |
| 2601 SimulateFullSpace(old_pointer_space); | 2597 SimulateFullSpace(old_pointer_space); |
| 2602 factory->NewFixedArray(1, TENURED); | 2598 factory->NewFixedArray(1, TENURED); |
| 2603 } | 2599 } |
| 2604 CHECK_EQ(number_of_test_pages + 1, old_pointer_space->CountTotalPages()); | 2600 CHECK_EQ(number_of_test_pages + 1, old_pointer_space->CountTotalPages()); |
| 2605 | 2601 |
| 2606 // 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 |
| 2607 // even spread across all allocated pages. | 2603 // even spread across all allocated pages. |
| 2608 HEAP->CollectAllGarbage(Heap::kNoGCFlags, "triggered for preparation"); | 2604 heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered for preparation"); |
| 2609 CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages()); | 2605 CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages()); |
| 2610 | 2606 |
| 2611 // Triggering subsequent GCs should cause at least half of the pages | 2607 // Triggering subsequent GCs should cause at least half of the pages |
| 2612 // to be released to the OS after at most two cycles. | 2608 // to be released to the OS after at most two cycles. |
| 2613 HEAP->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 1"); | 2609 heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 1"); |
| 2614 CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages()); | 2610 CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages()); |
| 2615 HEAP->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 2"); | 2611 heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 2"); |
| 2616 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); |
| 2617 | 2613 |
| 2618 // 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 |
| 2619 // 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 |
| 2620 // 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 |
| 2621 // 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 |
| 2622 // 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 |
| 2623 // 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 |
| 2624 // an indication that it is too small. | 2620 // an indication that it is too small. |
| 2625 HEAP->CollectAllAvailableGarbage("triggered really hard"); | 2621 heap->CollectAllAvailableGarbage("triggered really hard"); |
| 2626 CHECK_EQ(1, old_pointer_space->CountTotalPages()); | 2622 CHECK_EQ(1, old_pointer_space->CountTotalPages()); |
| 2627 } | 2623 } |
| 2628 | 2624 |
| 2629 | 2625 |
| 2630 TEST(Regress2237) { | 2626 TEST(Regress2237) { |
| 2631 i::FLAG_stress_compaction = false; | 2627 i::FLAG_stress_compaction = false; |
| 2632 CcTest::InitializeVM(); | 2628 CcTest::InitializeVM(); |
| 2633 Isolate* isolate = Isolate::Current(); | 2629 Isolate* isolate = CcTest::i_isolate(); |
| 2634 Factory* factory = isolate->factory(); | 2630 Factory* factory = isolate->factory(); |
| 2635 v8::HandleScope scope(CcTest::isolate()); | 2631 v8::HandleScope scope(CcTest::isolate()); |
| 2636 Handle<String> slice(HEAP->empty_string()); | 2632 Handle<String> slice(CcTest::heap()->empty_string()); |
| 2637 | 2633 |
| 2638 { | 2634 { |
| 2639 // Generate a parent that lives in new-space. | 2635 // Generate a parent that lives in new-space. |
| 2640 v8::HandleScope inner_scope(CcTest::isolate()); | 2636 v8::HandleScope inner_scope(CcTest::isolate()); |
| 2641 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."; |
| 2642 Handle<String> s = factory->NewStringFromAscii(CStrVector(c)); | 2638 Handle<String> s = factory->NewStringFromAscii(CStrVector(c)); |
| 2643 CHECK(s->IsSeqOneByteString()); | 2639 CHECK(s->IsSeqOneByteString()); |
| 2644 CHECK(HEAP->InNewSpace(*s)); | 2640 CHECK(CcTest::heap()->InNewSpace(*s)); |
| 2645 | 2641 |
| 2646 // 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 |
| 2647 // lives in old-space. | 2643 // lives in old-space. |
| 2648 SimulateFullSpace(HEAP->new_space()); | 2644 SimulateFullSpace(CcTest::heap()->new_space()); |
| 2649 AlwaysAllocateScope always_allocate; | 2645 AlwaysAllocateScope always_allocate; |
| 2650 Handle<String> t = factory->NewProperSubString(s, 5, 35); | 2646 Handle<String> t = factory->NewProperSubString(s, 5, 35); |
| 2651 CHECK(t->IsSlicedString()); | 2647 CHECK(t->IsSlicedString()); |
| 2652 CHECK(!HEAP->InNewSpace(*t)); | 2648 CHECK(!CcTest::heap()->InNewSpace(*t)); |
| 2653 *slice.location() = *t.location(); | 2649 *slice.location() = *t.location(); |
| 2654 } | 2650 } |
| 2655 | 2651 |
| 2656 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString()); | 2652 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString()); |
| 2657 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2653 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2658 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString()); | 2654 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString()); |
| 2659 } | 2655 } |
| 2660 | 2656 |
| 2661 | 2657 |
| 2662 #ifdef OBJECT_PRINT | 2658 #ifdef OBJECT_PRINT |
| 2663 TEST(PrintSharedFunctionInfo) { | 2659 TEST(PrintSharedFunctionInfo) { |
| 2664 CcTest::InitializeVM(); | 2660 CcTest::InitializeVM(); |
| 2665 v8::HandleScope scope(CcTest::isolate()); | 2661 v8::HandleScope scope(CcTest::isolate()); |
| 2666 const char* source = "f = function() { return 987654321; }\n" | 2662 const char* source = "f = function() { return 987654321; }\n" |
| 2667 "g = function() { return 123456789; }\n"; | 2663 "g = function() { return 123456789; }\n"; |
| 2668 CompileRun(source); | 2664 CompileRun(source); |
| 2669 Handle<JSFunction> g = | 2665 Handle<JSFunction> g = |
| 2670 v8::Utils::OpenHandle( | 2666 v8::Utils::OpenHandle( |
| 2671 *v8::Handle<v8::Function>::Cast( | 2667 *v8::Handle<v8::Function>::Cast( |
| 2672 v8::Context::GetCurrent()->Global()->Get(v8_str("g")))); | 2668 v8::Context::GetCurrent()->Global()->Get(v8_str("g")))); |
| 2673 | 2669 |
| 2674 DisallowHeapAllocation no_allocation; | 2670 DisallowHeapAllocation no_allocation; |
| 2675 g->shared()->PrintLn(); | 2671 g->shared()->PrintLn(); |
| 2676 } | 2672 } |
| 2677 #endif // OBJECT_PRINT | 2673 #endif // OBJECT_PRINT |
| 2678 | 2674 |
| 2679 | 2675 |
| 2680 TEST(Regress2211) { | 2676 TEST(Regress2211) { |
| 2681 CcTest::InitializeVM(); | 2677 CcTest::InitializeVM(); |
| 2682 v8::HandleScope scope(CcTest::isolate()); | 2678 v8::HandleScope scope(CcTest::isolate()); |
| 2683 | 2679 |
| 2684 v8::Handle<v8::String> value = v8_str("val string"); | 2680 v8::Handle<v8::String> value = v8_str("val string"); |
| 2685 Smi* hash = Smi::FromInt(321); | 2681 Smi* hash = Smi::FromInt(321); |
| 2686 Heap* heap = Isolate::Current()->heap(); | 2682 Heap* heap = CcTest::heap(); |
| 2687 | 2683 |
| 2688 for (int i = 0; i < 2; i++) { | 2684 for (int i = 0; i < 2; i++) { |
| 2689 // Store identity hash first and common hidden property second. | 2685 // Store identity hash first and common hidden property second. |
| 2690 v8::Handle<v8::Object> obj = v8::Object::New(); | 2686 v8::Handle<v8::Object> obj = v8::Object::New(); |
| 2691 Handle<JSObject> internal_obj = v8::Utils::OpenHandle(*obj); | 2687 Handle<JSObject> internal_obj = v8::Utils::OpenHandle(*obj); |
| 2692 CHECK(internal_obj->HasFastProperties()); | 2688 CHECK(internal_obj->HasFastProperties()); |
| 2693 | 2689 |
| 2694 // 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. |
| 2695 // In the second iteration, reverse the order. | 2691 // In the second iteration, reverse the order. |
| 2696 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... |
| 2740 *v8::Handle<v8::Function>::Cast( | 2736 *v8::Handle<v8::Function>::Cast( |
| 2741 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2737 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2742 Handle<TypeFeedbackCells> cells(TypeFeedbackInfo::cast( | 2738 Handle<TypeFeedbackCells> cells(TypeFeedbackInfo::cast( |
| 2743 f->shared()->code()->type_feedback_info())->type_feedback_cells()); | 2739 f->shared()->code()->type_feedback_info())->type_feedback_cells()); |
| 2744 | 2740 |
| 2745 CHECK_EQ(2, cells->CellCount()); | 2741 CHECK_EQ(2, cells->CellCount()); |
| 2746 CHECK(cells->GetCell(0)->value()->IsJSFunction()); | 2742 CHECK(cells->GetCell(0)->value()->IsJSFunction()); |
| 2747 CHECK(cells->GetCell(1)->value()->IsJSFunction()); | 2743 CHECK(cells->GetCell(1)->value()->IsJSFunction()); |
| 2748 | 2744 |
| 2749 SimulateIncrementalMarking(); | 2745 SimulateIncrementalMarking(); |
| 2750 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2746 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2751 | 2747 |
| 2752 CHECK_EQ(2, cells->CellCount()); | 2748 CHECK_EQ(2, cells->CellCount()); |
| 2753 CHECK(cells->GetCell(0)->value()->IsTheHole()); | 2749 CHECK(cells->GetCell(0)->value()->IsTheHole()); |
| 2754 CHECK(cells->GetCell(1)->value()->IsTheHole()); | 2750 CHECK(cells->GetCell(1)->value()->IsTheHole()); |
| 2755 } | 2751 } |
| 2756 | 2752 |
| 2757 | 2753 |
| 2758 static Code* FindFirstIC(Code* code, Code::Kind kind) { | 2754 static Code* FindFirstIC(Code* code, Code::Kind kind) { |
| 2759 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | | 2755 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
| 2760 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | | 2756 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2782 "function f(o) { return o.x; } f(obj); f(obj);"); | 2778 "function f(o) { return o.x; } f(obj); f(obj);"); |
| 2783 Handle<JSFunction> f = | 2779 Handle<JSFunction> f = |
| 2784 v8::Utils::OpenHandle( | 2780 v8::Utils::OpenHandle( |
| 2785 *v8::Handle<v8::Function>::Cast( | 2781 *v8::Handle<v8::Function>::Cast( |
| 2786 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2782 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2787 | 2783 |
| 2788 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2784 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2789 CHECK(ic_before->ic_state() == MONOMORPHIC); | 2785 CHECK(ic_before->ic_state() == MONOMORPHIC); |
| 2790 | 2786 |
| 2791 SimulateIncrementalMarking(); | 2787 SimulateIncrementalMarking(); |
| 2792 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2788 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2793 | 2789 |
| 2794 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2790 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2795 CHECK(ic_after->ic_state() == MONOMORPHIC); | 2791 CHECK(ic_after->ic_state() == MONOMORPHIC); |
| 2796 } | 2792 } |
| 2797 | 2793 |
| 2798 | 2794 |
| 2799 TEST(IncrementalMarkingClearsMonomorhpicIC) { | 2795 TEST(IncrementalMarkingClearsMonomorhpicIC) { |
| 2800 if (i::FLAG_always_opt) return; | 2796 if (i::FLAG_always_opt) return; |
| 2801 CcTest::InitializeVM(); | 2797 CcTest::InitializeVM(); |
| 2802 v8::HandleScope scope(CcTest::isolate()); | 2798 v8::HandleScope scope(CcTest::isolate()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2816 v8::Utils::OpenHandle( | 2812 v8::Utils::OpenHandle( |
| 2817 *v8::Handle<v8::Function>::Cast( | 2813 *v8::Handle<v8::Function>::Cast( |
| 2818 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2814 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2819 | 2815 |
| 2820 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2816 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2821 CHECK(ic_before->ic_state() == MONOMORPHIC); | 2817 CHECK(ic_before->ic_state() == MONOMORPHIC); |
| 2822 | 2818 |
| 2823 // Fire context dispose notification. | 2819 // Fire context dispose notification. |
| 2824 v8::V8::ContextDisposedNotification(); | 2820 v8::V8::ContextDisposedNotification(); |
| 2825 SimulateIncrementalMarking(); | 2821 SimulateIncrementalMarking(); |
| 2826 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2822 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2827 | 2823 |
| 2828 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2824 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2829 CHECK(ic_after->ic_state() == UNINITIALIZED); | 2825 CHECK(ic_after->ic_state() == UNINITIALIZED); |
| 2830 } | 2826 } |
| 2831 | 2827 |
| 2832 | 2828 |
| 2833 TEST(IncrementalMarkingClearsPolymorhpicIC) { | 2829 TEST(IncrementalMarkingClearsPolymorhpicIC) { |
| 2834 if (i::FLAG_always_opt) return; | 2830 if (i::FLAG_always_opt) return; |
| 2835 CcTest::InitializeVM(); | 2831 CcTest::InitializeVM(); |
| 2836 v8::HandleScope scope(CcTest::isolate()); | 2832 v8::HandleScope scope(CcTest::isolate()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2857 v8::Utils::OpenHandle( | 2853 v8::Utils::OpenHandle( |
| 2858 *v8::Handle<v8::Function>::Cast( | 2854 *v8::Handle<v8::Function>::Cast( |
| 2859 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2855 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2860 | 2856 |
| 2861 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2857 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2862 CHECK(ic_before->ic_state() == POLYMORPHIC); | 2858 CHECK(ic_before->ic_state() == POLYMORPHIC); |
| 2863 | 2859 |
| 2864 // Fire context dispose notification. | 2860 // Fire context dispose notification. |
| 2865 v8::V8::ContextDisposedNotification(); | 2861 v8::V8::ContextDisposedNotification(); |
| 2866 SimulateIncrementalMarking(); | 2862 SimulateIncrementalMarking(); |
| 2867 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2863 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2868 | 2864 |
| 2869 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2865 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2870 CHECK(ic_after->ic_state() == UNINITIALIZED); | 2866 CHECK(ic_after->ic_state() == UNINITIALIZED); |
| 2871 } | 2867 } |
| 2872 | 2868 |
| 2873 | 2869 |
| 2874 class SourceResource: public v8::String::ExternalAsciiStringResource { | 2870 class SourceResource: public v8::String::ExternalAsciiStringResource { |
| 2875 public: | 2871 public: |
| 2876 explicit SourceResource(const char* data) | 2872 explicit SourceResource(const char* data) |
| 2877 : data_(data), length_(strlen(data)) { } | 2873 : data_(data), length_(strlen(data)) { } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2893 }; | 2889 }; |
| 2894 | 2890 |
| 2895 | 2891 |
| 2896 void ReleaseStackTraceDataTest(const char* source, const char* accessor) { | 2892 void ReleaseStackTraceDataTest(const char* source, const char* accessor) { |
| 2897 // Test that the data retained by the Error.stack accessor is released | 2893 // Test that the data retained by the Error.stack accessor is released |
| 2898 // after the first time the accessor is fired. We use external string | 2894 // after the first time the accessor is fired. We use external string |
| 2899 // 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 |
| 2900 // 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. |
| 2901 FLAG_use_ic = false; // ICs retain objects. | 2897 FLAG_use_ic = false; // ICs retain objects. |
| 2902 FLAG_concurrent_recompilation = false; | 2898 FLAG_concurrent_recompilation = false; |
| 2903 CcTest::InitializeVM(); | |
| 2904 v8::HandleScope scope(CcTest::isolate()); | 2899 v8::HandleScope scope(CcTest::isolate()); |
| 2905 SourceResource* resource = new SourceResource(i::StrDup(source)); | 2900 SourceResource* resource = new SourceResource(i::StrDup(source)); |
| 2906 { | 2901 { |
| 2907 v8::HandleScope scope(CcTest::isolate()); | 2902 v8::HandleScope scope(CcTest::isolate()); |
| 2908 v8::Handle<v8::String> source_string = v8::String::NewExternal(resource); | 2903 v8::Handle<v8::String> source_string = v8::String::NewExternal(resource); |
| 2909 HEAP->CollectAllAvailableGarbage(); | 2904 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2910 v8::Script::Compile(source_string)->Run(); | 2905 v8::Script::Compile(source_string)->Run(); |
| 2911 CHECK(!resource->IsDisposed()); | 2906 CHECK(!resource->IsDisposed()); |
| 2912 } | 2907 } |
| 2913 // HEAP->CollectAllAvailableGarbage(); | 2908 // CcTest::heap()->CollectAllAvailableGarbage(); |
| 2914 CHECK(!resource->IsDisposed()); | 2909 CHECK(!resource->IsDisposed()); |
| 2915 | 2910 |
| 2916 CompileRun(accessor); | 2911 CompileRun(accessor); |
| 2917 HEAP->CollectAllAvailableGarbage(); | 2912 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2918 | 2913 |
| 2919 // External source has been released. | 2914 // External source has been released. |
| 2920 CHECK(resource->IsDisposed()); | 2915 CHECK(resource->IsDisposed()); |
| 2921 delete resource; | 2916 delete resource; |
| 2922 } | 2917 } |
| 2923 | 2918 |
| 2924 | 2919 |
| 2925 TEST(ReleaseStackTraceData) { | 2920 TEST(ReleaseStackTraceData) { |
| 2921 CcTest::InitializeVM(); |
| 2926 static const char* source1 = "var error = null; " | 2922 static const char* source1 = "var error = null; " |
| 2927 /* Normal Error */ "try { " | 2923 /* Normal Error */ "try { " |
| 2928 " throw new Error(); " | 2924 " throw new Error(); " |
| 2929 "} catch (e) { " | 2925 "} catch (e) { " |
| 2930 " error = e; " | 2926 " error = e; " |
| 2931 "} "; | 2927 "} "; |
| 2932 static const char* source2 = "var error = null; " | 2928 static const char* source2 = "var error = null; " |
| 2933 /* Stack overflow */ "try { " | 2929 /* Stack overflow */ "try { " |
| 2934 " (function f() { f(); })(); " | 2930 " (function f() { f(); })(); " |
| 2935 "} catch (e) { " | 2931 "} catch (e) { " |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2961 ReleaseStackTraceDataTest(source1, getter); | 2957 ReleaseStackTraceDataTest(source1, getter); |
| 2962 ReleaseStackTraceDataTest(source2, getter); | 2958 ReleaseStackTraceDataTest(source2, getter); |
| 2963 ReleaseStackTraceDataTest(source3, getter); | 2959 ReleaseStackTraceDataTest(source3, getter); |
| 2964 ReleaseStackTraceDataTest(source4, getter); | 2960 ReleaseStackTraceDataTest(source4, getter); |
| 2965 } | 2961 } |
| 2966 | 2962 |
| 2967 | 2963 |
| 2968 TEST(Regression144230) { | 2964 TEST(Regression144230) { |
| 2969 i::FLAG_stress_compaction = false; | 2965 i::FLAG_stress_compaction = false; |
| 2970 CcTest::InitializeVM(); | 2966 CcTest::InitializeVM(); |
| 2971 Isolate* isolate = Isolate::Current(); | 2967 Isolate* isolate = CcTest::i_isolate(); |
| 2972 Heap* heap = isolate->heap(); | 2968 Heap* heap = isolate->heap(); |
| 2973 HandleScope scope(isolate); | 2969 HandleScope scope(isolate); |
| 2974 | 2970 |
| 2975 // First make sure that the uninitialized CallIC stub is on a single page | 2971 // First make sure that the uninitialized CallIC stub is on a single page |
| 2976 // that will later be selected as an evacuation candidate. | 2972 // that will later be selected as an evacuation candidate. |
| 2977 { | 2973 { |
| 2978 HandleScope inner_scope(isolate); | 2974 HandleScope inner_scope(isolate); |
| 2979 AlwaysAllocateScope always_allocate; | 2975 AlwaysAllocateScope always_allocate; |
| 2980 SimulateFullSpace(heap->code_space()); | 2976 SimulateFullSpace(heap->code_space()); |
| 2981 isolate->stub_cache()->ComputeCallInitialize(9, RelocInfo::CODE_TARGET); | 2977 isolate->stub_cache()->ComputeCallInitialize(9, RelocInfo::CODE_TARGET); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3002 " 'f' + i + '();');" | 2998 " 'f' + i + '();');" |
| 3003 "}"); | 2999 "}"); |
| 3004 } | 3000 } |
| 3005 heap->CollectAllGarbage(Heap::kNoGCFlags); | 3001 heap->CollectAllGarbage(Heap::kNoGCFlags); |
| 3006 | 3002 |
| 3007 // Fourth is the tricky part. Make sure the code containing the CallIC is | 3003 // Fourth is the tricky part. Make sure the code containing the CallIC is |
| 3008 // visited first without clearing the IC. The shared function info is then | 3004 // visited first without clearing the IC. The shared function info is then |
| 3009 // visited later, causing the CallIC to be cleared. | 3005 // visited later, causing the CallIC to be cleared. |
| 3010 Handle<String> name = isolate->factory()->InternalizeUtf8String("call"); | 3006 Handle<String> name = isolate->factory()->InternalizeUtf8String("call"); |
| 3011 Handle<GlobalObject> global(isolate->context()->global_object()); | 3007 Handle<GlobalObject> global(isolate->context()->global_object()); |
| 3008 Handle<Smi> zero(Smi::FromInt(0), isolate); |
| 3012 MaybeObject* maybe_call = global->GetProperty(*name); | 3009 MaybeObject* maybe_call = global->GetProperty(*name); |
| 3013 JSFunction* call = JSFunction::cast(maybe_call->ToObjectChecked()); | 3010 JSFunction* call = JSFunction::cast(maybe_call->ToObjectChecked()); |
| 3014 USE(global->SetProperty(*name, Smi::FromInt(0), NONE, kNonStrictMode)); | 3011 JSReceiver::SetProperty(global, name, zero, NONE, kNonStrictMode); |
| 3015 isolate->compilation_cache()->Clear(); | 3012 isolate->compilation_cache()->Clear(); |
| 3016 call->shared()->set_ic_age(heap->global_ic_age() + 1); | 3013 call->shared()->set_ic_age(heap->global_ic_age() + 1); |
| 3017 Handle<Object> call_code(call->code(), isolate); | 3014 Handle<Object> call_code(call->code(), isolate); |
| 3018 Handle<Object> call_function(call, isolate); | 3015 Handle<Object> call_function(call, isolate); |
| 3019 | 3016 |
| 3020 // Now we are ready to mess up the heap. | 3017 // Now we are ready to mess up the heap. |
| 3021 heap->CollectAllGarbage(Heap::kReduceMemoryFootprintMask); | 3018 heap->CollectAllGarbage(Heap::kReduceMemoryFootprintMask); |
| 3022 | 3019 |
| 3023 // Either heap verification caught the problem already or we go kaboom once | 3020 // Either heap verification caught the problem already or we go kaboom once |
| 3024 // the CallIC is executed the next time. | 3021 // the CallIC is executed the next time. |
| 3025 USE(global->SetProperty(*name, *call_function, NONE, kNonStrictMode)); | 3022 JSReceiver::SetProperty(global, name, call_function, NONE, kNonStrictMode); |
| 3026 CompileRun("call();"); | 3023 CompileRun("call();"); |
| 3027 } | 3024 } |
| 3028 | 3025 |
| 3029 | 3026 |
| 3030 TEST(Regress159140) { | 3027 TEST(Regress159140) { |
| 3031 i::FLAG_allow_natives_syntax = true; | 3028 i::FLAG_allow_natives_syntax = true; |
| 3032 i::FLAG_flush_code_incrementally = true; | 3029 i::FLAG_flush_code_incrementally = true; |
| 3033 CcTest::InitializeVM(); | 3030 CcTest::InitializeVM(); |
| 3034 Isolate* isolate = Isolate::Current(); | 3031 Isolate* isolate = CcTest::i_isolate(); |
| 3035 Heap* heap = isolate->heap(); | 3032 Heap* heap = isolate->heap(); |
| 3036 HandleScope scope(isolate); | 3033 HandleScope scope(isolate); |
| 3037 | 3034 |
| 3038 // Perform one initial GC to enable code flushing. | 3035 // Perform one initial GC to enable code flushing. |
| 3039 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 3036 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 3040 | 3037 |
| 3041 // Prepare several closures that are all eligible for code flushing | 3038 // Prepare several closures that are all eligible for code flushing |
| 3042 // because all reachable ones are not optimized. Make sure that the | 3039 // because all reachable ones are not optimized. Make sure that the |
| 3043 // optimized code object is directly reachable through a handle so | 3040 // optimized code object is directly reachable through a handle so |
| 3044 // that it is marked black during incremental marking. | 3041 // that it is marked black during incremental marking. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3086 | 3083 |
| 3087 // Unoptimized code is missing and the deoptimizer will go ballistic. | 3084 // Unoptimized code is missing and the deoptimizer will go ballistic. |
| 3088 CompileRun("g('bozo');"); | 3085 CompileRun("g('bozo');"); |
| 3089 } | 3086 } |
| 3090 | 3087 |
| 3091 | 3088 |
| 3092 TEST(Regress165495) { | 3089 TEST(Regress165495) { |
| 3093 i::FLAG_allow_natives_syntax = true; | 3090 i::FLAG_allow_natives_syntax = true; |
| 3094 i::FLAG_flush_code_incrementally = true; | 3091 i::FLAG_flush_code_incrementally = true; |
| 3095 CcTest::InitializeVM(); | 3092 CcTest::InitializeVM(); |
| 3096 Isolate* isolate = Isolate::Current(); | 3093 Isolate* isolate = CcTest::i_isolate(); |
| 3097 Heap* heap = isolate->heap(); | 3094 Heap* heap = isolate->heap(); |
| 3098 HandleScope scope(isolate); | 3095 HandleScope scope(isolate); |
| 3099 | 3096 |
| 3100 // Perform one initial GC to enable code flushing. | 3097 // Perform one initial GC to enable code flushing. |
| 3101 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 3098 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 3102 | 3099 |
| 3103 // Prepare an optimized closure that the optimized code map will get | 3100 // Prepare an optimized closure that the optimized code map will get |
| 3104 // populated. Then age the unoptimized code to trigger code flushing | 3101 // populated. Then age the unoptimized code to trigger code flushing |
| 3105 // but make sure the optimized code is unreachable. | 3102 // but make sure the optimized code is unreachable. |
| 3106 { | 3103 { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 3135 CompileRun("var g = mkClosure(); g('bozo');"); | 3132 CompileRun("var g = mkClosure(); g('bozo');"); |
| 3136 } | 3133 } |
| 3137 | 3134 |
| 3138 | 3135 |
| 3139 TEST(Regress169209) { | 3136 TEST(Regress169209) { |
| 3140 i::FLAG_stress_compaction = false; | 3137 i::FLAG_stress_compaction = false; |
| 3141 i::FLAG_allow_natives_syntax = true; | 3138 i::FLAG_allow_natives_syntax = true; |
| 3142 i::FLAG_flush_code_incrementally = true; | 3139 i::FLAG_flush_code_incrementally = true; |
| 3143 | 3140 |
| 3144 CcTest::InitializeVM(); | 3141 CcTest::InitializeVM(); |
| 3145 Isolate* isolate = Isolate::Current(); | 3142 Isolate* isolate = CcTest::i_isolate(); |
| 3146 Heap* heap = isolate->heap(); | 3143 Heap* heap = isolate->heap(); |
| 3147 HandleScope scope(isolate); | 3144 HandleScope scope(isolate); |
| 3148 | 3145 |
| 3149 // Perform one initial GC to enable code flushing. | 3146 // Perform one initial GC to enable code flushing. |
| 3150 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 3147 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 3151 | 3148 |
| 3152 // Prepare a shared function info eligible for code flushing for which | 3149 // Prepare a shared function info eligible for code flushing for which |
| 3153 // the unoptimized code will be replaced during optimization. | 3150 // the unoptimized code will be replaced during optimization. |
| 3154 Handle<SharedFunctionInfo> shared1; | 3151 Handle<SharedFunctionInfo> shared1; |
| 3155 { | 3152 { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3221 v8::internal::MaybeObject* maybe = space->AllocateRaw(new_linear_size); | 3218 v8::internal::MaybeObject* maybe = space->AllocateRaw(new_linear_size); |
| 3222 v8::internal::FreeListNode* node = v8::internal::FreeListNode::cast(maybe); | 3219 v8::internal::FreeListNode* node = v8::internal::FreeListNode::cast(maybe); |
| 3223 node->set_size(space->heap(), new_linear_size); | 3220 node->set_size(space->heap(), new_linear_size); |
| 3224 } | 3221 } |
| 3225 | 3222 |
| 3226 | 3223 |
| 3227 TEST(Regress169928) { | 3224 TEST(Regress169928) { |
| 3228 i::FLAG_allow_natives_syntax = true; | 3225 i::FLAG_allow_natives_syntax = true; |
| 3229 i::FLAG_crankshaft = false; | 3226 i::FLAG_crankshaft = false; |
| 3230 CcTest::InitializeVM(); | 3227 CcTest::InitializeVM(); |
| 3231 Isolate* isolate = Isolate::Current(); | 3228 Isolate* isolate = CcTest::i_isolate(); |
| 3232 Factory* factory = isolate->factory(); | 3229 Factory* factory = isolate->factory(); |
| 3233 v8::HandleScope scope(CcTest::isolate()); | 3230 v8::HandleScope scope(CcTest::isolate()); |
| 3234 | 3231 |
| 3235 // Some flags turn Scavenge collections into Mark-sweep collections | 3232 // Some flags turn Scavenge collections into Mark-sweep collections |
| 3236 // and hence are incompatible with this test case. | 3233 // and hence are incompatible with this test case. |
| 3237 if (FLAG_gc_global || FLAG_stress_compaction) return; | 3234 if (FLAG_gc_global || FLAG_stress_compaction) return; |
| 3238 | 3235 |
| 3239 // Prepare the environment | 3236 // Prepare the environment |
| 3240 CompileRun("function fastliteralcase(literal, value) {" | 3237 CompileRun("function fastliteralcase(literal, value) {" |
| 3241 " literal[0] = value;" | 3238 " literal[0] = value;" |
| 3242 " return literal;" | 3239 " return literal;" |
| 3243 "}" | 3240 "}" |
| 3244 "function get_standard_literal() {" | 3241 "function get_standard_literal() {" |
| 3245 " var literal = [1, 2, 3];" | 3242 " var literal = [1, 2, 3];" |
| 3246 " return literal;" | 3243 " return literal;" |
| 3247 "}" | 3244 "}" |
| 3248 "obj = fastliteralcase(get_standard_literal(), 1);" | 3245 "obj = fastliteralcase(get_standard_literal(), 1);" |
| 3249 "obj = fastliteralcase(get_standard_literal(), 1.5);" | 3246 "obj = fastliteralcase(get_standard_literal(), 1.5);" |
| 3250 "obj = fastliteralcase(get_standard_literal(), 2);"); | 3247 "obj = fastliteralcase(get_standard_literal(), 2);"); |
| 3251 | 3248 |
| 3252 // prepare the heap | 3249 // prepare the heap |
| 3253 v8::Local<v8::String> mote_code_string = | 3250 v8::Local<v8::String> mote_code_string = |
| 3254 v8_str("fastliteralcase(mote, 2.5);"); | 3251 v8_str("fastliteralcase(mote, 2.5);"); |
| 3255 | 3252 |
| 3256 v8::Local<v8::String> array_name = v8_str("mote"); | 3253 v8::Local<v8::String> array_name = v8_str("mote"); |
| 3257 v8::Context::GetCurrent()->Global()->Set(array_name, v8::Int32::New(0)); | 3254 v8::Context::GetCurrent()->Global()->Set(array_name, v8::Int32::New(0)); |
| 3258 | 3255 |
| 3259 // First make sure we flip spaces | 3256 // First make sure we flip spaces |
| 3260 HEAP->CollectGarbage(NEW_SPACE); | 3257 CcTest::heap()->CollectGarbage(NEW_SPACE); |
| 3261 | 3258 |
| 3262 // Allocate the object. | 3259 // Allocate the object. |
| 3263 Handle<FixedArray> array_data = factory->NewFixedArray(2, NOT_TENURED); | 3260 Handle<FixedArray> array_data = factory->NewFixedArray(2, NOT_TENURED); |
| 3264 array_data->set(0, Smi::FromInt(1)); | 3261 array_data->set(0, Smi::FromInt(1)); |
| 3265 array_data->set(1, Smi::FromInt(2)); | 3262 array_data->set(1, Smi::FromInt(2)); |
| 3266 | 3263 |
| 3267 AllocateAllButNBytes(HEAP->new_space(), | 3264 AllocateAllButNBytes(CcTest::heap()->new_space(), |
| 3268 JSArray::kSize + AllocationMemento::kSize + | 3265 JSArray::kSize + AllocationMemento::kSize + |
| 3269 kPointerSize); | 3266 kPointerSize); |
| 3270 | 3267 |
| 3271 Handle<JSArray> array = factory->NewJSArrayWithElements(array_data, | 3268 Handle<JSArray> array = factory->NewJSArrayWithElements(array_data, |
| 3272 FAST_SMI_ELEMENTS, | 3269 FAST_SMI_ELEMENTS, |
| 3273 NOT_TENURED); | 3270 NOT_TENURED); |
| 3274 | 3271 |
| 3275 CHECK_EQ(Smi::FromInt(2), array->length()); | 3272 CHECK_EQ(Smi::FromInt(2), array->length()); |
| 3276 CHECK(array->HasFastSmiOrObjectElements()); | 3273 CHECK(array->HasFastSmiOrObjectElements()); |
| 3277 | 3274 |
| 3278 // We need filler the size of AllocationMemento object, plus an extra | 3275 // We need filler the size of AllocationMemento object, plus an extra |
| 3279 // fill pointer value. | 3276 // fill pointer value. |
| 3280 MaybeObject* maybe_object = HEAP->AllocateRaw( | 3277 MaybeObject* maybe_object = CcTest::heap()->AllocateRaw( |
| 3281 AllocationMemento::kSize + kPointerSize, NEW_SPACE, OLD_POINTER_SPACE); | 3278 AllocationMemento::kSize + kPointerSize, NEW_SPACE, OLD_POINTER_SPACE); |
| 3282 Object* obj = NULL; | 3279 Object* obj = NULL; |
| 3283 CHECK(maybe_object->ToObject(&obj)); | 3280 CHECK(maybe_object->ToObject(&obj)); |
| 3284 Address addr_obj = reinterpret_cast<Address>( | 3281 Address addr_obj = reinterpret_cast<Address>( |
| 3285 reinterpret_cast<byte*>(obj - kHeapObjectTag)); | 3282 reinterpret_cast<byte*>(obj - kHeapObjectTag)); |
| 3286 HEAP->CreateFillerObjectAt(addr_obj, | 3283 CcTest::heap()->CreateFillerObjectAt(addr_obj, |
| 3287 AllocationMemento::kSize + kPointerSize); | 3284 AllocationMemento::kSize + kPointerSize); |
| 3288 | 3285 |
| 3289 // Give the array a name, making sure not to allocate strings. | 3286 // Give the array a name, making sure not to allocate strings. |
| 3290 v8::Handle<v8::Object> array_obj = v8::Utils::ToLocal(array); | 3287 v8::Handle<v8::Object> array_obj = v8::Utils::ToLocal(array); |
| 3291 v8::Context::GetCurrent()->Global()->Set(array_name, array_obj); | 3288 v8::Context::GetCurrent()->Global()->Set(array_name, array_obj); |
| 3292 | 3289 |
| 3293 // 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 |
| 3294 // with the bug. | 3291 // with the bug. |
| 3295 AlwaysAllocateScope aa_scope; | 3292 AlwaysAllocateScope aa_scope; |
| 3296 v8::Script::Compile(mote_code_string)->Run(); | 3293 v8::Script::Compile(mote_code_string)->Run(); |
| 3297 } | 3294 } |
| 3298 | 3295 |
| 3299 | 3296 |
| 3300 TEST(Regress168801) { | 3297 TEST(Regress168801) { |
| 3301 i::FLAG_always_compact = true; | 3298 i::FLAG_always_compact = true; |
| 3302 i::FLAG_cache_optimized_code = false; | 3299 i::FLAG_cache_optimized_code = false; |
| 3303 i::FLAG_allow_natives_syntax = true; | 3300 i::FLAG_allow_natives_syntax = true; |
| 3304 i::FLAG_flush_code_incrementally = true; | 3301 i::FLAG_flush_code_incrementally = true; |
| 3305 CcTest::InitializeVM(); | 3302 CcTest::InitializeVM(); |
| 3306 Isolate* isolate = Isolate::Current(); | 3303 Isolate* isolate = CcTest::i_isolate(); |
| 3307 Heap* heap = isolate->heap(); | 3304 Heap* heap = isolate->heap(); |
| 3308 HandleScope scope(isolate); | 3305 HandleScope scope(isolate); |
| 3309 | 3306 |
| 3310 // Perform one initial GC to enable code flushing. | 3307 // Perform one initial GC to enable code flushing. |
| 3311 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 3308 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 3312 | 3309 |
| 3313 // Ensure the code ends up on an evacuation candidate. | 3310 // Ensure the code ends up on an evacuation candidate. |
| 3314 SimulateFullSpace(heap->code_space()); | 3311 SimulateFullSpace(heap->code_space()); |
| 3315 | 3312 |
| 3316 // Prepare an unoptimized function that is eligible for code flushing. | 3313 // Prepare an unoptimized function that is eligible for code flushing. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3352 heap->CollectAllGarbage(Heap::kNoGCFlags); | 3349 heap->CollectAllGarbage(Heap::kNoGCFlags); |
| 3353 } | 3350 } |
| 3354 | 3351 |
| 3355 | 3352 |
| 3356 TEST(Regress173458) { | 3353 TEST(Regress173458) { |
| 3357 i::FLAG_always_compact = true; | 3354 i::FLAG_always_compact = true; |
| 3358 i::FLAG_cache_optimized_code = false; | 3355 i::FLAG_cache_optimized_code = false; |
| 3359 i::FLAG_allow_natives_syntax = true; | 3356 i::FLAG_allow_natives_syntax = true; |
| 3360 i::FLAG_flush_code_incrementally = true; | 3357 i::FLAG_flush_code_incrementally = true; |
| 3361 CcTest::InitializeVM(); | 3358 CcTest::InitializeVM(); |
| 3362 Isolate* isolate = Isolate::Current(); | 3359 Isolate* isolate = CcTest::i_isolate(); |
| 3363 Heap* heap = isolate->heap(); | 3360 Heap* heap = isolate->heap(); |
| 3364 HandleScope scope(isolate); | 3361 HandleScope scope(isolate); |
| 3365 | 3362 |
| 3366 // Perform one initial GC to enable code flushing. | 3363 // Perform one initial GC to enable code flushing. |
| 3367 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 3364 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 3368 | 3365 |
| 3369 // Ensure the code ends up on an evacuation candidate. | 3366 // Ensure the code ends up on an evacuation candidate. |
| 3370 SimulateFullSpace(heap->code_space()); | 3367 SimulateFullSpace(heap->code_space()); |
| 3371 | 3368 |
| 3372 // Prepare an unoptimized function that is eligible for code flushing. | 3369 // Prepare an unoptimized function that is eligible for code flushing. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3409 | 3406 |
| 3410 | 3407 |
| 3411 class DummyVisitor : public ObjectVisitor { | 3408 class DummyVisitor : public ObjectVisitor { |
| 3412 public: | 3409 public: |
| 3413 void VisitPointers(Object** start, Object** end) { } | 3410 void VisitPointers(Object** start, Object** end) { } |
| 3414 }; | 3411 }; |
| 3415 | 3412 |
| 3416 | 3413 |
| 3417 TEST(DeferredHandles) { | 3414 TEST(DeferredHandles) { |
| 3418 CcTest::InitializeVM(); | 3415 CcTest::InitializeVM(); |
| 3419 Isolate* isolate = Isolate::Current(); | 3416 Isolate* isolate = CcTest::i_isolate(); |
| 3420 Heap* heap = isolate->heap(); | 3417 Heap* heap = isolate->heap(); |
| 3421 v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate)); | 3418 v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate)); |
| 3422 v8::ImplementationUtilities::HandleScopeData* data = | 3419 v8::ImplementationUtilities::HandleScopeData* data = |
| 3423 isolate->handle_scope_data(); | 3420 isolate->handle_scope_data(); |
| 3424 Handle<Object> init(heap->empty_string(), isolate); | 3421 Handle<Object> init(heap->empty_string(), isolate); |
| 3425 while (data->next < data->limit) { | 3422 while (data->next < data->limit) { |
| 3426 Handle<Object> obj(heap->empty_string(), isolate); | 3423 Handle<Object> obj(heap->empty_string(), isolate); |
| 3427 } | 3424 } |
| 3428 // An entire block of handles has been filled. | 3425 // An entire block of handles has been filled. |
| 3429 // Next handle would require a new block. | 3426 // Next handle would require a new block. |
| 3430 ASSERT(data->next == data->limit); | 3427 ASSERT(data->next == data->limit); |
| 3431 | 3428 |
| 3432 DeferredHandleScope deferred(isolate); | 3429 DeferredHandleScope deferred(isolate); |
| 3433 DummyVisitor visitor; | 3430 DummyVisitor visitor; |
| 3434 isolate->handle_scope_implementer()->Iterate(&visitor); | 3431 isolate->handle_scope_implementer()->Iterate(&visitor); |
| 3435 deferred.Detach(); | 3432 deferred.Detach(); |
| 3436 } | 3433 } |
| 3437 | 3434 |
| 3438 | 3435 |
| 3439 TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) { | 3436 TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) { |
| 3440 CcTest::InitializeVM(); | 3437 CcTest::InitializeVM(); |
| 3441 v8::HandleScope scope(CcTest::isolate()); | 3438 v8::HandleScope scope(CcTest::isolate()); |
| 3442 CompileRun("function f(n) {" | 3439 CompileRun("function f(n) {" |
| 3443 " var a = new Array(n);" | 3440 " var a = new Array(n);" |
| 3444 " for (var i = 0; i < n; i += 100) a[i] = i;" | 3441 " for (var i = 0; i < n; i += 100) a[i] = i;" |
| 3445 "};" | 3442 "};" |
| 3446 "f(10 * 1024 * 1024);"); | 3443 "f(10 * 1024 * 1024);"); |
| 3447 IncrementalMarking* marking = HEAP->incremental_marking(); | 3444 IncrementalMarking* marking = CcTest::heap()->incremental_marking(); |
| 3448 if (marking->IsStopped()) marking->Start(); | 3445 if (marking->IsStopped()) marking->Start(); |
| 3449 // This big step should be sufficient to mark the whole array. | 3446 // This big step should be sufficient to mark the whole array. |
| 3450 marking->Step(100 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | 3447 marking->Step(100 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 3451 ASSERT(marking->IsComplete()); | 3448 ASSERT(marking->IsComplete()); |
| 3452 } | 3449 } |
| OLD | NEW |