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,
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,
Variable* var_index, Label* if_keyisunique,
Label* if_bailout) {
......@@ -2157,8 +2185,10 @@ void CodeStubAssembler::TryProbeStubCacheTable(
#ifdef DEBUG
if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
Goto(if_miss);
return;
} else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
Goto(if_miss);
return;
}
#endif
// The {table_offset} holds the entry offset times four (due to masking
......@@ -2202,10 +2232,13 @@ void CodeStubAssembler::TryProbeStubCache(
StubCache* stub_cache, Code::Flags flags, compiler::Node* receiver,
compiler::Node* name, Label* if_handler, Variable* var_handler,
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.
GotoIf(WordIsSmi(receiver), if_miss);
GotoIf(WordIsSmi(receiver), &miss);
Node* receiver_map = LoadMap(receiver);
......@@ -2220,8 +2253,13 @@ void CodeStubAssembler::TryProbeStubCache(
Node* secondary_offset =
StubCacheSecondaryOffset(name, flags, primary_offset);
TryProbeStubCacheTable(stub_cache, kSecondary, secondary_offset, name,
flags, receiver_map, if_handler, var_handler,
if_miss);
flags, receiver_map, if_handler, var_handler, &miss);
}
Bind(&miss);
{
IncrementCounter(counters->megamorphic_stub_cache_misses(), 1);
Goto(if_miss);
}
}
......
......@@ -257,6 +257,10 @@ class CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* BitFieldDecode(compiler::Node* word32, uint32_t shift,
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.
void TryToName(compiler::Node* key, Label* if_keyisindex, Variable* var_index,
Label* if_keyisunique, Label* if_bailout);
......
......@@ -21481,14 +21481,18 @@ TEST(ScopedMicrotasks) {
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
static int probes_counter = 0;
static int misses_counter = 0;
static int updates_counter = 0;
namespace {
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) {
return &probes_counter;
} else if (strcmp(name, "c:V8.MegamorphicStubCacheMisses") == 0) {
......@@ -21499,24 +21503,28 @@ static int* LookupCounter(const char* name) {
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 =
"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
void StubCacheHelper(bool primary) {
i::FLAG_native_code_counters = true;
if (primary) {
i::FLAG_test_primary_stub_cache = true;
......@@ -21524,9 +21532,18 @@ static void StubCacheHelper(bool primary) {
i::FLAG_test_secondary_stub_cache = true;
}
i::FLAG_crankshaft = false;
LocalContext env;
env->GetIsolate()->SetCounterFunction(LookupCounter);
v8::HandleScope scope(env->GetIsolate());
i::FLAG_turbo = false;
v8::Isolate::CreateParams create_params;
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_misses = misses_counter;
int initial_updates = updates_counter;
......@@ -21534,26 +21551,27 @@ static void StubCacheHelper(bool primary) {
int probes = probes_counter - initial_probes;
int misses = misses_counter - initial_misses;
int updates = updates_counter - initial_updates;
CHECK_LT(updates, 10);
CHECK_LT(misses, 10);
// TODO(verwaest): Update this test to overflow the degree of polymorphism
// before megamorphism. The number of probes will only work once we teach the
// serializer to embed references to counters in the stubs, given that the
// megamorphic_stub_cache_probes is updated in a snapshot-generated stub.
CHECK_GE(probes, 0);
#endif
const int kClassesCount = 6;
// Check that updates and misses counts are bounded.
CHECK_LE(kClassesCount, updates);
CHECK_LT(updates, kClassesCount * 3);
CHECK_LE(1, misses);
CHECK_LT(misses, kClassesCount * 2);
// 2 is for PREMONOMORPHIC and MONOMORPHIC states,
// 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) {
StubCacheHelper(true);
}
UNINITIALIZED_TEST(PrimaryStubCache) { StubCacheHelper(true); }
TEST(PrimaryStubCache) {
StubCacheHelper(false);
}
UNINITIALIZED_TEST(SecondaryStubCache) { StubCacheHelper(false); }
#endif // ENABLE_DISASSEMBLER && !V8_USE_EXTERNAL_STARTUP_DATA
#ifdef DEBUG
static int cow_arrays_created_runtime = 0;
......
......@@ -1328,7 +1328,7 @@ TEST(TryProbeStubCache) {
}
// Generate some number of handlers.
for (int i = 0; i < StubCache::kSecondaryTableSize; i++) {
for (int i = 0; i < 30; i++) {
Code::Kind code_kind;
switch (rand_gen.NextInt(4)) {
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