Commit bcf3da27 authored by ishell's avatar ishell Committed by Commit bot

[stubs] Fixed tests that prevented LoadICTF stubs from being enabled.

PrimaryStubCache and SecondaryStubCache: resurrected outdated tests (and enabled stub cache counters in the new LoadIC).
TryProbeStubCache: decreased number of code objects created.

Review-Url: https://codereview.chromium.org/2040193002
Cr-Commit-Position: refs/heads/master@{#36794}
parent 2b38d312
...@@ -1444,6 +1444,34 @@ Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift, ...@@ -1444,6 +1444,34 @@ Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift,
Int32Constant(shift)); Int32Constant(shift));
} }
void CodeStubAssembler::SetCounter(StatsCounter* counter, int value) {
if (FLAG_native_code_counters && counter->Enabled()) {
Node* counter_address = ExternalConstant(ExternalReference(counter));
StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address,
Int32Constant(value));
}
}
void CodeStubAssembler::IncrementCounter(StatsCounter* counter, int delta) {
DCHECK(delta > 0);
if (FLAG_native_code_counters && counter->Enabled()) {
Node* counter_address = ExternalConstant(ExternalReference(counter));
Node* value = Load(MachineType::Int32(), counter_address);
value = Int32Add(value, Int32Constant(delta));
StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, value);
}
}
void CodeStubAssembler::DecrementCounter(StatsCounter* counter, int delta) {
DCHECK(delta > 0);
if (FLAG_native_code_counters && counter->Enabled()) {
Node* counter_address = ExternalConstant(ExternalReference(counter));
Node* value = Load(MachineType::Int32(), counter_address);
value = Int32Sub(value, Int32Constant(delta));
StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, value);
}
}
void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex,
Variable* var_index, Label* if_keyisunique, Variable* var_index, Label* if_keyisunique,
Label* if_bailout) { Label* if_bailout) {
...@@ -2157,8 +2185,10 @@ void CodeStubAssembler::TryProbeStubCacheTable( ...@@ -2157,8 +2185,10 @@ void CodeStubAssembler::TryProbeStubCacheTable(
#ifdef DEBUG #ifdef DEBUG
if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
Goto(if_miss); Goto(if_miss);
return;
} else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
Goto(if_miss); Goto(if_miss);
return;
} }
#endif #endif
// The {table_offset} holds the entry offset times four (due to masking // The {table_offset} holds the entry offset times four (due to masking
...@@ -2202,10 +2232,13 @@ void CodeStubAssembler::TryProbeStubCache( ...@@ -2202,10 +2232,13 @@ void CodeStubAssembler::TryProbeStubCache(
StubCache* stub_cache, Code::Flags flags, compiler::Node* receiver, StubCache* stub_cache, Code::Flags flags, compiler::Node* receiver,
compiler::Node* name, Label* if_handler, Variable* var_handler, compiler::Node* name, Label* if_handler, Variable* var_handler,
Label* if_miss) { Label* if_miss) {
Label try_secondary(this); Label try_secondary(this), miss(this);
Counters* counters = isolate()->counters();
IncrementCounter(counters->megamorphic_stub_cache_probes(), 1);
// Check that the {receiver} isn't a smi. // Check that the {receiver} isn't a smi.
GotoIf(WordIsSmi(receiver), if_miss); GotoIf(WordIsSmi(receiver), &miss);
Node* receiver_map = LoadMap(receiver); Node* receiver_map = LoadMap(receiver);
...@@ -2220,8 +2253,13 @@ void CodeStubAssembler::TryProbeStubCache( ...@@ -2220,8 +2253,13 @@ void CodeStubAssembler::TryProbeStubCache(
Node* secondary_offset = Node* secondary_offset =
StubCacheSecondaryOffset(name, flags, primary_offset); StubCacheSecondaryOffset(name, flags, primary_offset);
TryProbeStubCacheTable(stub_cache, kSecondary, secondary_offset, name, TryProbeStubCacheTable(stub_cache, kSecondary, secondary_offset, name,
flags, receiver_map, if_handler, var_handler, flags, receiver_map, if_handler, var_handler, &miss);
if_miss); }
Bind(&miss);
{
IncrementCounter(counters->megamorphic_stub_cache_misses(), 1);
Goto(if_miss);
} }
} }
......
...@@ -257,6 +257,10 @@ class CodeStubAssembler : public compiler::CodeAssembler { ...@@ -257,6 +257,10 @@ class CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* BitFieldDecode(compiler::Node* word32, uint32_t shift, compiler::Node* BitFieldDecode(compiler::Node* word32, uint32_t shift,
uint32_t mask); uint32_t mask);
void SetCounter(StatsCounter* counter, int value);
void IncrementCounter(StatsCounter* counter, int delta);
void DecrementCounter(StatsCounter* counter, int delta);
// Various building blocks for stubs doing property lookups. // Various building blocks for stubs doing property lookups.
void TryToName(compiler::Node* key, Label* if_keyisindex, Variable* var_index, void TryToName(compiler::Node* key, Label* if_keyisindex, Variable* var_index,
Label* if_keyisunique, Label* if_bailout); Label* if_keyisunique, Label* if_bailout);
......
...@@ -21481,14 +21481,18 @@ TEST(ScopedMicrotasks) { ...@@ -21481,14 +21481,18 @@ TEST(ScopedMicrotasks) {
env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto); env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
} }
#if defined(ENABLE_DISASSEMBLER) && !defined(V8_USE_EXTERNAL_STARTUP_DATA)
// FLAG_test_primary_stub_cache and FLAG_test_secondary_stub_cache are read
// only when ENABLE_DISASSEMBLER is not defined.
// These tests are valid only for no-snapshot mode.
#ifdef ENABLE_DISASSEMBLER namespace {
static int probes_counter = 0;
static int misses_counter = 0;
static int updates_counter = 0;
int probes_counter = 0;
int misses_counter = 0;
int updates_counter = 0;
static int* LookupCounter(const char* name) { int* LookupCounter(const char* name) {
if (strcmp(name, "c:V8.MegamorphicStubCacheProbes") == 0) { if (strcmp(name, "c:V8.MegamorphicStubCacheProbes") == 0) {
return &probes_counter; return &probes_counter;
} else if (strcmp(name, "c:V8.MegamorphicStubCacheMisses") == 0) { } else if (strcmp(name, "c:V8.MegamorphicStubCacheMisses") == 0) {
...@@ -21499,24 +21503,28 @@ static int* LookupCounter(const char* name) { ...@@ -21499,24 +21503,28 @@ static int* LookupCounter(const char* name) {
return NULL; return NULL;
} }
const char* kMegamorphicTestProgram =
"function CreateClass(name) {\n"
" var src = \n"
" ` function ${name}() {};` +\n"
" ` ${name}.prototype.foo = function() {};` +\n"
" ` ${name};\\n`;\n"
" return (0, eval)(src);\n"
"}\n"
"function fooify(obj) { obj.foo(); };\n"
"var objs = [];\n"
"for (var i = 0; i < 6; i++) {\n"
" var Class = CreateClass('Class' + i);\n"
" var obj = new Class();\n"
" objs.push(obj);\n"
"}\n"
"for (var i = 0; i < 10000; i++) {\n"
" for (var obj of objs) {\n"
" fooify(obj);\n"
" }\n"
"}\n";
static const char* kMegamorphicTestProgram = void StubCacheHelper(bool primary) {
"function ClassA() { };"
"function ClassB() { };"
"ClassA.prototype.foo = function() { };"
"ClassB.prototype.foo = function() { };"
"function fooify(obj) { obj.foo(); };"
"var a = new ClassA();"
"var b = new ClassB();"
"for (var i = 0; i < 10000; i++) {"
" fooify(a);"
" fooify(b);"
"}";
#endif
static void StubCacheHelper(bool primary) {
#ifdef ENABLE_DISASSEMBLER
i::FLAG_native_code_counters = true; i::FLAG_native_code_counters = true;
if (primary) { if (primary) {
i::FLAG_test_primary_stub_cache = true; i::FLAG_test_primary_stub_cache = true;
...@@ -21524,9 +21532,18 @@ static void StubCacheHelper(bool primary) { ...@@ -21524,9 +21532,18 @@ static void StubCacheHelper(bool primary) {
i::FLAG_test_secondary_stub_cache = true; i::FLAG_test_secondary_stub_cache = true;
} }
i::FLAG_crankshaft = false; i::FLAG_crankshaft = false;
LocalContext env; i::FLAG_turbo = false;
env->GetIsolate()->SetCounterFunction(LookupCounter); v8::Isolate::CreateParams create_params;
v8::HandleScope scope(env->GetIsolate()); create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate = v8::Isolate::New(create_params);
isolate->SetCounterFunction(LookupCounter);
{
v8::Isolate::Scope isolate_scope(isolate);
LocalContext env(isolate);
v8::HandleScope scope(isolate);
int initial_probes = probes_counter; int initial_probes = probes_counter;
int initial_misses = misses_counter; int initial_misses = misses_counter;
int initial_updates = updates_counter; int initial_updates = updates_counter;
...@@ -21534,26 +21551,27 @@ static void StubCacheHelper(bool primary) { ...@@ -21534,26 +21551,27 @@ static void StubCacheHelper(bool primary) {
int probes = probes_counter - initial_probes; int probes = probes_counter - initial_probes;
int misses = misses_counter - initial_misses; int misses = misses_counter - initial_misses;
int updates = updates_counter - initial_updates; int updates = updates_counter - initial_updates;
CHECK_LT(updates, 10); const int kClassesCount = 6;
CHECK_LT(misses, 10); // Check that updates and misses counts are bounded.
// TODO(verwaest): Update this test to overflow the degree of polymorphism CHECK_LE(kClassesCount, updates);
// before megamorphism. The number of probes will only work once we teach the CHECK_LT(updates, kClassesCount * 3);
// serializer to embed references to counters in the stubs, given that the CHECK_LE(1, misses);
// megamorphic_stub_cache_probes is updated in a snapshot-generated stub. CHECK_LT(misses, kClassesCount * 2);
CHECK_GE(probes, 0); // 2 is for PREMONOMORPHIC and MONOMORPHIC states,
#endif // 4 is for POLYMORPHIC states,
// and all the others probes are for MEGAMORPHIC state.
CHECK_EQ(10000 * kClassesCount - 2 - 4, probes);
}
isolate->Dispose();
} }
} // namespace
TEST(SecondaryStubCache) { UNINITIALIZED_TEST(PrimaryStubCache) { StubCacheHelper(true); }
StubCacheHelper(true);
}
TEST(PrimaryStubCache) { UNINITIALIZED_TEST(SecondaryStubCache) { StubCacheHelper(false); }
StubCacheHelper(false);
}
#endif // ENABLE_DISASSEMBLER && !V8_USE_EXTERNAL_STARTUP_DATA
#ifdef DEBUG #ifdef DEBUG
static int cow_arrays_created_runtime = 0; static int cow_arrays_created_runtime = 0;
......
...@@ -1328,7 +1328,7 @@ TEST(TryProbeStubCache) { ...@@ -1328,7 +1328,7 @@ TEST(TryProbeStubCache) {
} }
// Generate some number of handlers. // Generate some number of handlers.
for (int i = 0; i < StubCache::kSecondaryTableSize; i++) { for (int i = 0; i < 30; i++) {
Code::Kind code_kind; Code::Kind code_kind;
switch (rand_gen.NextInt(4)) { switch (rand_gen.NextInt(4)) {
case 0: case 0:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment