| Index: src/code-stub-assembler.cc
|
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
|
| index 3aa27ecbd301a476d7de3df6c5e44d367efd1a17..f403a4aedb2d4fab545b7cd8d2990415dc9d0fa5 100644
|
| --- a/src/code-stub-assembler.cc
|
| +++ b/src/code-stub-assembler.cc
|
| @@ -2730,6 +2730,7 @@
|
| }
|
|
|
| compiler::Node* CodeStubAssembler::StubCachePrimaryOffset(compiler::Node* name,
|
| + Code::Flags flags,
|
| compiler::Node* map) {
|
| // See v8::internal::StubCache::PrimaryOffset().
|
| STATIC_ASSERT(StubCache::kCacheIndexShift == Name::kHashShift);
|
| @@ -2743,18 +2744,28 @@
|
| // risk of collision even if the heap is spread over an area larger than
|
| // 4Gb (and not at all if it isn't).
|
| Node* hash = Int32Add(hash_field, map);
|
| - // Base the offset on a simple combination of name and map.
|
| + // We always set the in_loop bit to zero when generating the lookup code
|
| + // so do it here too so the hash codes match.
|
| + uint32_t iflags =
|
| + (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
|
| + // Base the offset on a simple combination of name, flags, and map.
|
| + hash = Word32Xor(hash, Int32Constant(iflags));
|
| uint32_t mask = (StubCache::kPrimaryTableSize - 1)
|
| << StubCache::kCacheIndexShift;
|
| return Word32And(hash, Int32Constant(mask));
|
| }
|
|
|
| compiler::Node* CodeStubAssembler::StubCacheSecondaryOffset(
|
| - compiler::Node* name, compiler::Node* seed) {
|
| + compiler::Node* name, Code::Flags flags, compiler::Node* seed) {
|
| // See v8::internal::StubCache::SecondaryOffset().
|
|
|
| // Use the seed from the primary cache in the secondary cache.
|
| Node* hash = Int32Sub(seed, name);
|
| + // We always set the in_loop bit to zero when generating the lookup code
|
| + // so do it here too so the hash codes match.
|
| + uint32_t iflags =
|
| + (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
|
| + hash = Int32Add(hash, Int32Constant(iflags));
|
| int32_t mask = (StubCache::kSecondaryTableSize - 1)
|
| << StubCache::kCacheIndexShift;
|
| return Word32And(hash, Int32Constant(mask));
|
| @@ -2767,8 +2778,9 @@
|
|
|
| void CodeStubAssembler::TryProbeStubCacheTable(
|
| StubCache* stub_cache, StubCacheTable table_id,
|
| - compiler::Node* entry_offset, compiler::Node* name, compiler::Node* map,
|
| - Label* if_handler, Variable* var_handler, Label* if_miss) {
|
| + compiler::Node* entry_offset, compiler::Node* name, Code::Flags flags,
|
| + compiler::Node* map, Label* if_handler, Variable* var_handler,
|
| + Label* if_miss) {
|
| StubCache::Table table = static_cast<StubCache::Table>(table_id);
|
| #ifdef DEBUG
|
| if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
|
| @@ -2798,19 +2810,18 @@
|
| Int32Add(entry_offset, Int32Constant(kPointerSize * 2)));
|
| GotoIf(WordNotEqual(map, entry_map), if_miss);
|
|
|
| + // Check that the flags match what we're looking for.
|
| DCHECK_EQ(kPointerSize, stub_cache->value_reference(table).address() -
|
| stub_cache->key_reference(table).address());
|
| Node* code = Load(MachineType::Pointer(), key_base,
|
| Int32Add(entry_offset, Int32Constant(kPointerSize)));
|
|
|
| - // Check that the flags match what we're looking for.
|
| - Code::Flags flags = Code::RemoveHolderFromFlags(
|
| - Code::ComputeHandlerFlags(stub_cache->ic_kind()));
|
| Node* code_flags =
|
| LoadObjectField(code, Code::kFlagsOffset, MachineType::Uint32());
|
| - Assert(Word32Equal(
|
| - Int32Constant(flags),
|
| - Word32And(code_flags, Int32Constant(~Code::kFlagsNotUsedInLookup))));
|
| + GotoIf(Word32NotEqual(Int32Constant(flags),
|
| + Word32And(code_flags,
|
| + Int32Constant(~Code::kFlagsNotUsedInLookup))),
|
| + if_miss);
|
|
|
| // We found the handler.
|
| var_handler->Bind(code);
|
| @@ -2820,6 +2831,9 @@
|
| void CodeStubAssembler::TryProbeStubCache(
|
| StubCache* stub_cache, compiler::Node* receiver, compiler::Node* name,
|
| Label* if_handler, Variable* var_handler, Label* if_miss) {
|
| + Code::Flags flags = Code::RemoveHolderFromFlags(
|
| + Code::ComputeHandlerFlags(stub_cache->ic_kind()));
|
| +
|
| Label try_secondary(this), miss(this);
|
|
|
| Counters* counters = isolate()->counters();
|
| @@ -2831,16 +2845,17 @@
|
| Node* receiver_map = LoadMap(receiver);
|
|
|
| // Probe the primary table.
|
| - Node* primary_offset = StubCachePrimaryOffset(name, receiver_map);
|
| - TryProbeStubCacheTable(stub_cache, kPrimary, primary_offset, name,
|
| + Node* primary_offset = StubCachePrimaryOffset(name, flags, receiver_map);
|
| + TryProbeStubCacheTable(stub_cache, kPrimary, primary_offset, name, flags,
|
| receiver_map, if_handler, var_handler, &try_secondary);
|
|
|
| Bind(&try_secondary);
|
| {
|
| // Probe the secondary table.
|
| - Node* secondary_offset = StubCacheSecondaryOffset(name, primary_offset);
|
| + Node* secondary_offset =
|
| + StubCacheSecondaryOffset(name, flags, primary_offset);
|
| TryProbeStubCacheTable(stub_cache, kSecondary, secondary_offset, name,
|
| - receiver_map, if_handler, var_handler, &miss);
|
| + flags, receiver_map, if_handler, var_handler, &miss);
|
| }
|
|
|
| Bind(&miss);
|
|
|