| 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 21464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21475 { | 21475 { |
| 21476 v8::MicrotasksScope scope(env->GetIsolate(), | 21476 v8::MicrotasksScope scope(env->GetIsolate(), |
| 21477 v8::MicrotasksScope::kDoNotRunMicrotasks); | 21477 v8::MicrotasksScope::kDoNotRunMicrotasks); |
| 21478 CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); | 21478 CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); |
| 21479 CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); | 21479 CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); |
| 21480 } | 21480 } |
| 21481 | 21481 |
| 21482 env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto); | 21482 env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto); |
| 21483 } | 21483 } |
| 21484 | 21484 |
| 21485 #if defined(ENABLE_DISASSEMBLER) && !defined(V8_USE_EXTERNAL_STARTUP_DATA) |
| 21486 // FLAG_test_primary_stub_cache and FLAG_test_secondary_stub_cache are read |
| 21487 // only when ENABLE_DISASSEMBLER is not defined. |
| 21488 // These tests are valid only for no-snapshot mode. |
| 21485 | 21489 |
| 21486 #ifdef ENABLE_DISASSEMBLER | 21490 namespace { |
| 21487 static int probes_counter = 0; | |
| 21488 static int misses_counter = 0; | |
| 21489 static int updates_counter = 0; | |
| 21490 | 21491 |
| 21492 int probes_counter = 0; |
| 21493 int misses_counter = 0; |
| 21494 int updates_counter = 0; |
| 21491 | 21495 |
| 21492 static int* LookupCounter(const char* name) { | 21496 int* LookupCounter(const char* name) { |
| 21493 if (strcmp(name, "c:V8.MegamorphicStubCacheProbes") == 0) { | 21497 if (strcmp(name, "c:V8.MegamorphicStubCacheProbes") == 0) { |
| 21494 return &probes_counter; | 21498 return &probes_counter; |
| 21495 } else if (strcmp(name, "c:V8.MegamorphicStubCacheMisses") == 0) { | 21499 } else if (strcmp(name, "c:V8.MegamorphicStubCacheMisses") == 0) { |
| 21496 return &misses_counter; | 21500 return &misses_counter; |
| 21497 } else if (strcmp(name, "c:V8.MegamorphicStubCacheUpdates") == 0) { | 21501 } else if (strcmp(name, "c:V8.MegamorphicStubCacheUpdates") == 0) { |
| 21498 return &updates_counter; | 21502 return &updates_counter; |
| 21499 } | 21503 } |
| 21500 return NULL; | 21504 return NULL; |
| 21501 } | 21505 } |
| 21502 | 21506 |
| 21507 const char* kMegamorphicTestProgram = |
| 21508 "function CreateClass(name) {\n" |
| 21509 " var src = \n" |
| 21510 " ` function ${name}() {};` +\n" |
| 21511 " ` ${name}.prototype.foo = function() {};` +\n" |
| 21512 " ` ${name};\\n`;\n" |
| 21513 " return (0, eval)(src);\n" |
| 21514 "}\n" |
| 21515 "function fooify(obj) { obj.foo(); };\n" |
| 21516 "var objs = [];\n" |
| 21517 "for (var i = 0; i < 6; i++) {\n" |
| 21518 " var Class = CreateClass('Class' + i);\n" |
| 21519 " var obj = new Class();\n" |
| 21520 " objs.push(obj);\n" |
| 21521 "}\n" |
| 21522 "for (var i = 0; i < 10000; i++) {\n" |
| 21523 " for (var obj of objs) {\n" |
| 21524 " fooify(obj);\n" |
| 21525 " }\n" |
| 21526 "}\n"; |
| 21503 | 21527 |
| 21504 static const char* kMegamorphicTestProgram = | 21528 void StubCacheHelper(bool primary) { |
| 21505 "function ClassA() { };" | |
| 21506 "function ClassB() { };" | |
| 21507 "ClassA.prototype.foo = function() { };" | |
| 21508 "ClassB.prototype.foo = function() { };" | |
| 21509 "function fooify(obj) { obj.foo(); };" | |
| 21510 "var a = new ClassA();" | |
| 21511 "var b = new ClassB();" | |
| 21512 "for (var i = 0; i < 10000; i++) {" | |
| 21513 " fooify(a);" | |
| 21514 " fooify(b);" | |
| 21515 "}"; | |
| 21516 #endif | |
| 21517 | |
| 21518 | |
| 21519 static void StubCacheHelper(bool primary) { | |
| 21520 #ifdef ENABLE_DISASSEMBLER | |
| 21521 i::FLAG_native_code_counters = true; | 21529 i::FLAG_native_code_counters = true; |
| 21522 if (primary) { | 21530 if (primary) { |
| 21523 i::FLAG_test_primary_stub_cache = true; | 21531 i::FLAG_test_primary_stub_cache = true; |
| 21524 } else { | 21532 } else { |
| 21525 i::FLAG_test_secondary_stub_cache = true; | 21533 i::FLAG_test_secondary_stub_cache = true; |
| 21526 } | 21534 } |
| 21527 i::FLAG_crankshaft = false; | 21535 i::FLAG_crankshaft = false; |
| 21528 LocalContext env; | 21536 i::FLAG_turbo = false; |
| 21529 env->GetIsolate()->SetCounterFunction(LookupCounter); | 21537 v8::Isolate::CreateParams create_params; |
| 21530 v8::HandleScope scope(env->GetIsolate()); | 21538 create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); |
| 21531 int initial_probes = probes_counter; | 21539 v8::Isolate* isolate = v8::Isolate::New(create_params); |
| 21532 int initial_misses = misses_counter; | 21540 |
| 21533 int initial_updates = updates_counter; | 21541 isolate->SetCounterFunction(LookupCounter); |
| 21534 CompileRun(kMegamorphicTestProgram); | 21542 |
| 21535 int probes = probes_counter - initial_probes; | 21543 { |
| 21536 int misses = misses_counter - initial_misses; | 21544 v8::Isolate::Scope isolate_scope(isolate); |
| 21537 int updates = updates_counter - initial_updates; | 21545 LocalContext env(isolate); |
| 21538 CHECK_LT(updates, 10); | 21546 v8::HandleScope scope(isolate); |
| 21539 CHECK_LT(misses, 10); | 21547 |
| 21540 // TODO(verwaest): Update this test to overflow the degree of polymorphism | 21548 int initial_probes = probes_counter; |
| 21541 // before megamorphism. The number of probes will only work once we teach the | 21549 int initial_misses = misses_counter; |
| 21542 // serializer to embed references to counters in the stubs, given that the | 21550 int initial_updates = updates_counter; |
| 21543 // megamorphic_stub_cache_probes is updated in a snapshot-generated stub. | 21551 CompileRun(kMegamorphicTestProgram); |
| 21544 CHECK_GE(probes, 0); | 21552 int probes = probes_counter - initial_probes; |
| 21545 #endif | 21553 int misses = misses_counter - initial_misses; |
| 21554 int updates = updates_counter - initial_updates; |
| 21555 const int kClassesCount = 6; |
| 21556 // Check that updates and misses counts are bounded. |
| 21557 CHECK_LE(kClassesCount, updates); |
| 21558 CHECK_LT(updates, kClassesCount * 3); |
| 21559 CHECK_LE(1, misses); |
| 21560 CHECK_LT(misses, kClassesCount * 2); |
| 21561 // 2 is for PREMONOMORPHIC and MONOMORPHIC states, |
| 21562 // 4 is for POLYMORPHIC states, |
| 21563 // and all the others probes are for MEGAMORPHIC state. |
| 21564 CHECK_EQ(10000 * kClassesCount - 2 - 4, probes); |
| 21565 } |
| 21566 isolate->Dispose(); |
| 21546 } | 21567 } |
| 21547 | 21568 |
| 21569 } // namespace |
| 21548 | 21570 |
| 21549 TEST(SecondaryStubCache) { | 21571 UNINITIALIZED_TEST(PrimaryStubCache) { StubCacheHelper(true); } |
| 21550 StubCacheHelper(true); | |
| 21551 } | |
| 21552 | 21572 |
| 21573 UNINITIALIZED_TEST(SecondaryStubCache) { StubCacheHelper(false); } |
| 21553 | 21574 |
| 21554 TEST(PrimaryStubCache) { | 21575 #endif // ENABLE_DISASSEMBLER && !V8_USE_EXTERNAL_STARTUP_DATA |
| 21555 StubCacheHelper(false); | |
| 21556 } | |
| 21557 | |
| 21558 | 21576 |
| 21559 #ifdef DEBUG | 21577 #ifdef DEBUG |
| 21560 static int cow_arrays_created_runtime = 0; | 21578 static int cow_arrays_created_runtime = 0; |
| 21561 | 21579 |
| 21562 | 21580 |
| 21563 static int* LookupCounterCOWArrays(const char* name) { | 21581 static int* LookupCounterCOWArrays(const char* name) { |
| 21564 if (strcmp(name, "c:V8.COWArraysCreatedRuntime") == 0) { | 21582 if (strcmp(name, "c:V8.COWArraysCreatedRuntime") == 0) { |
| 21565 return &cow_arrays_created_runtime; | 21583 return &cow_arrays_created_runtime; |
| 21566 } | 21584 } |
| 21567 return NULL; | 21585 return NULL; |
| (...skipping 3784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 25352 } | 25370 } |
| 25353 | 25371 |
| 25354 TEST(PrivateForApiIsNumber) { | 25372 TEST(PrivateForApiIsNumber) { |
| 25355 LocalContext context; | 25373 LocalContext context; |
| 25356 v8::Isolate* isolate = CcTest::isolate(); | 25374 v8::Isolate* isolate = CcTest::isolate(); |
| 25357 v8::HandleScope scope(isolate); | 25375 v8::HandleScope scope(isolate); |
| 25358 | 25376 |
| 25359 // Shouldn't crash. | 25377 // Shouldn't crash. |
| 25360 v8::Private::ForApi(isolate, v8_str("42")); | 25378 v8::Private::ForApi(isolate, v8_str("42")); |
| 25361 } | 25379 } |
| OLD | NEW |