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 23 matching lines...) Expand all Loading... |
34 | 34 |
35 #if V8_OS_POSIX | 35 #if V8_OS_POSIX |
36 #include <unistd.h> // NOLINT | 36 #include <unistd.h> // NOLINT |
37 #endif | 37 #endif |
38 | 38 |
39 #include "include/v8-util.h" | 39 #include "include/v8-util.h" |
40 #include "src/api.h" | 40 #include "src/api.h" |
41 #include "src/arguments.h" | 41 #include "src/arguments.h" |
42 #include "src/base/platform/platform.h" | 42 #include "src/base/platform/platform.h" |
43 #include "src/base/smart-pointers.h" | 43 #include "src/base/smart-pointers.h" |
| 44 #include "src/code-stubs.h" |
44 #include "src/compilation-cache.h" | 45 #include "src/compilation-cache.h" |
45 #include "src/debug/debug.h" | 46 #include "src/debug/debug.h" |
46 #include "src/execution.h" | 47 #include "src/execution.h" |
47 #include "src/futex-emulation.h" | 48 #include "src/futex-emulation.h" |
48 #include "src/objects.h" | 49 #include "src/objects.h" |
49 #include "src/parsing/parser.h" | 50 #include "src/parsing/parser.h" |
50 #include "src/profiler/cpu-profiler.h" | 51 #include "src/profiler/cpu-profiler.h" |
51 #include "src/unicode-inl.h" | 52 #include "src/unicode-inl.h" |
52 #include "src/utils.h" | 53 #include "src/utils.h" |
53 #include "src/vm-state.h" | 54 #include "src/vm-state.h" |
(...skipping 21395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
21449 const char* kMegamorphicTestProgram = | 21450 const char* kMegamorphicTestProgram = |
21450 "function CreateClass(name) {\n" | 21451 "function CreateClass(name) {\n" |
21451 " var src = \n" | 21452 " var src = \n" |
21452 " ` function ${name}() {};` +\n" | 21453 " ` function ${name}() {};` +\n" |
21453 " ` ${name}.prototype.foo = function() {};` +\n" | 21454 " ` ${name}.prototype.foo = function() {};` +\n" |
21454 " ` ${name};\\n`;\n" | 21455 " ` ${name};\\n`;\n" |
21455 " return (0, eval)(src);\n" | 21456 " return (0, eval)(src);\n" |
21456 "}\n" | 21457 "}\n" |
21457 "function fooify(obj) { obj.foo(); };\n" | 21458 "function fooify(obj) { obj.foo(); };\n" |
21458 "var objs = [];\n" | 21459 "var objs = [];\n" |
21459 "for (var i = 0; i < 6; i++) {\n" | 21460 "for (var i = 0; i < 50; i++) {\n" |
21460 " var Class = CreateClass('Class' + i);\n" | 21461 " var Class = CreateClass('Class' + i);\n" |
21461 " var obj = new Class();\n" | 21462 " var obj = new Class();\n" |
21462 " objs.push(obj);\n" | 21463 " objs.push(obj);\n" |
21463 "}\n" | 21464 "}\n" |
21464 "for (var i = 0; i < 10000; i++) {\n" | 21465 "for (var i = 0; i < 1000; i++) {\n" |
21465 " for (var obj of objs) {\n" | 21466 " for (var obj of objs) {\n" |
21466 " fooify(obj);\n" | 21467 " fooify(obj);\n" |
21467 " }\n" | 21468 " }\n" |
21468 "}\n"; | 21469 "}\n"; |
21469 | 21470 |
21470 void StubCacheHelper(bool primary) { | 21471 void TestStubCache(bool primary) { |
21471 i::FLAG_native_code_counters = true; | 21472 i::FLAG_native_code_counters = true; |
21472 if (primary) { | 21473 if (primary) { |
21473 i::FLAG_test_primary_stub_cache = true; | 21474 i::FLAG_test_primary_stub_cache = true; |
21474 } else { | 21475 } else { |
21475 i::FLAG_test_secondary_stub_cache = true; | 21476 i::FLAG_test_secondary_stub_cache = true; |
21476 } | 21477 } |
21477 i::FLAG_crankshaft = false; | 21478 i::FLAG_crankshaft = false; |
21478 i::FLAG_turbo = false; | 21479 i::FLAG_turbo = false; |
21479 v8::Isolate::CreateParams create_params; | 21480 v8::Isolate::CreateParams create_params; |
21480 create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); | 21481 create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); |
21481 create_params.counter_lookup_callback = LookupCounter; | 21482 create_params.counter_lookup_callback = LookupCounter; |
21482 v8::Isolate* isolate = v8::Isolate::New(create_params); | 21483 v8::Isolate* isolate = v8::Isolate::New(create_params); |
21483 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | |
21484 | 21484 |
21485 if (!i_isolate->snapshot_available()) { | 21485 { |
21486 // The test is valid only for no-snapshot mode. | |
21487 v8::Isolate::Scope isolate_scope(isolate); | 21486 v8::Isolate::Scope isolate_scope(isolate); |
21488 LocalContext env(isolate); | 21487 LocalContext env(isolate); |
21489 v8::HandleScope scope(isolate); | 21488 v8::HandleScope scope(isolate); |
21490 | 21489 |
| 21490 { |
| 21491 // Enforce recompilation of all code stubs that access megamorphic stub |
| 21492 // cache to respect enabled native code counters and stub cache test mode |
| 21493 // flags. |
| 21494 i::CodeStub::Major code_stub_keys[] = { |
| 21495 i::CodeStub::LoadIC, i::CodeStub::LoadICTrampoline, |
| 21496 i::CodeStub::LoadICTF, i::CodeStub::LoadICTrampolineTF, |
| 21497 i::CodeStub::KeyedLoadIC, i::CodeStub::KeyedLoadICTrampoline, |
| 21498 i::CodeStub::StoreIC, i::CodeStub::StoreICTrampoline, |
| 21499 i::CodeStub::KeyedStoreIC, i::CodeStub::KeyedStoreICTrampoline, |
| 21500 }; |
| 21501 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 21502 i::UnseededNumberDictionary* dict = i_isolate->heap()->code_stubs(); |
| 21503 for (size_t i = 0; i < arraysize(code_stub_keys); i++) { |
| 21504 dict->DeleteKey(code_stub_keys[i]); |
| 21505 } |
| 21506 } |
| 21507 |
21491 int initial_probes = probes_counter; | 21508 int initial_probes = probes_counter; |
21492 int initial_misses = misses_counter; | 21509 int initial_misses = misses_counter; |
21493 int initial_updates = updates_counter; | 21510 int initial_updates = updates_counter; |
21494 CompileRun(kMegamorphicTestProgram); | 21511 CompileRun(kMegamorphicTestProgram); |
21495 int probes = probes_counter - initial_probes; | 21512 int probes = probes_counter - initial_probes; |
21496 int misses = misses_counter - initial_misses; | 21513 int misses = misses_counter - initial_misses; |
21497 int updates = updates_counter - initial_updates; | 21514 int updates = updates_counter - initial_updates; |
21498 const int kClassesCount = 6; | 21515 const int kClassesCount = 50; |
| 21516 const int kIterationsCount = 1000; |
| 21517 CHECK_LE(kClassesCount, updates); |
21499 // Check that updates and misses counts are bounded. | 21518 // Check that updates and misses counts are bounded. |
21500 CHECK_LE(kClassesCount, updates); | 21519 // If there are too many updates then most likely the stub cache does not |
21501 CHECK_LT(updates, kClassesCount * 3); | 21520 // work properly. |
| 21521 CHECK_LE(updates, kClassesCount * 2); |
21502 CHECK_LE(1, misses); | 21522 CHECK_LE(1, misses); |
21503 CHECK_LT(misses, kClassesCount * 2); | 21523 CHECK_LE(misses, kClassesCount * 2); |
21504 // 2 is for PREMONOMORPHIC and MONOMORPHIC states, | 21524 // 2 is for PREMONOMORPHIC and MONOMORPHIC states, |
21505 // 4 is for POLYMORPHIC states, | 21525 // 4 is for POLYMORPHIC states, |
21506 // and all the others probes are for MEGAMORPHIC state. | 21526 // and all the others probes are for MEGAMORPHIC state. |
21507 CHECK_EQ(10000 * kClassesCount - 2 - 4, probes); | 21527 CHECK_EQ(kIterationsCount * kClassesCount - 2 - 4, probes); |
21508 } | 21528 } |
21509 isolate->Dispose(); | 21529 isolate->Dispose(); |
21510 } | 21530 } |
21511 | 21531 |
21512 } // namespace | 21532 } // namespace |
21513 | 21533 |
21514 UNINITIALIZED_TEST(PrimaryStubCache) { StubCacheHelper(true); } | 21534 UNINITIALIZED_TEST(PrimaryStubCache) { |
| 21535 i::FLAG_tf_load_ic_stub = false; |
| 21536 TestStubCache(true); |
| 21537 } |
21515 | 21538 |
21516 UNINITIALIZED_TEST(SecondaryStubCache) { StubCacheHelper(false); } | 21539 UNINITIALIZED_TEST(SecondaryStubCache) { |
| 21540 i::FLAG_tf_load_ic_stub = false; |
| 21541 TestStubCache(false); |
| 21542 } |
| 21543 |
| 21544 UNINITIALIZED_TEST(PrimaryStubCacheTF) { |
| 21545 i::FLAG_tf_load_ic_stub = true; |
| 21546 TestStubCache(true); |
| 21547 } |
| 21548 |
| 21549 UNINITIALIZED_TEST(SecondaryStubCacheTF) { |
| 21550 i::FLAG_tf_load_ic_stub = true; |
| 21551 TestStubCache(false); |
| 21552 } |
21517 | 21553 |
21518 #endif // ENABLE_DISASSEMBLER | 21554 #endif // ENABLE_DISASSEMBLER |
21519 | 21555 |
21520 #ifdef DEBUG | 21556 #ifdef DEBUG |
21521 static int cow_arrays_created_runtime = 0; | 21557 static int cow_arrays_created_runtime = 0; |
21522 | 21558 |
21523 | 21559 |
21524 static int* LookupCounterCOWArrays(const char* name) { | 21560 static int* LookupCounterCOWArrays(const char* name) { |
21525 if (strcmp(name, "c:V8.COWArraysCreatedRuntime") == 0) { | 21561 if (strcmp(name, "c:V8.COWArraysCreatedRuntime") == 0) { |
21526 return &cow_arrays_created_runtime; | 21562 return &cow_arrays_created_runtime; |
(...skipping 3885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
25412 | 25448 |
25413 // Put the function into context1 and call it. Since the access check | 25449 // Put the function into context1 and call it. Since the access check |
25414 // callback always returns true, the call succeeds even though the tokens | 25450 // callback always returns true, the call succeeds even though the tokens |
25415 // are different. | 25451 // are different. |
25416 context1->Enter(); | 25452 context1->Enter(); |
25417 context1->Global()->Set(context1, v8_str("fun"), fun).FromJust(); | 25453 context1->Global()->Set(context1, v8_str("fun"), fun).FromJust(); |
25418 v8::Local<v8::Value> x_value = CompileRun("fun('x')"); | 25454 v8::Local<v8::Value> x_value = CompileRun("fun('x')"); |
25419 CHECK_EQ(42, x_value->Int32Value(context1).FromJust()); | 25455 CHECK_EQ(42, x_value->Int32Value(context1).FromJust()); |
25420 context1->Exit(); | 25456 context1->Exit(); |
25421 } | 25457 } |
OLD | NEW |