Index: runtime/vm/flow_graph_compiler_x64.cc |
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc |
index bdcc3b4d1119eb5d514176cecf5dde82df83903b..def75aa46cf2ef1f6386380f0c21994b414ff86d 100644 |
--- a/runtime/vm/flow_graph_compiler_x64.cc |
+++ b/runtime/vm/flow_graph_compiler_x64.cc |
@@ -1328,9 +1328,28 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall( |
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); |
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(), |
MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor)); |
- |
__ Comment("MegamorphicCall"); |
+ // Load receiver into RDI. |
__ movq(RDI, Address(RSP, (argument_count - 1) * kWordSize)); |
+ Label done; |
+ if (name.raw() == Symbols::hashCode().raw()) { |
+ Label try_onebytestring, megamorphic_call; |
+ __ Comment("Inlined get:hashCode for Smi and OneByteString"); |
+ __ testq(RDI, Immediate(kSmiTagMask)); |
+ __ j(NOT_ZERO, &try_onebytestring, Assembler::kNearJump); // Non-smi value. |
+ __ movq(RAX, RDI); |
+ __ jmp(&done, Assembler::kNearJump); |
+ |
+ __ Bind(&try_onebytestring); |
+ __ CompareClassId(RDI, kOneByteStringCid); |
+ __ j(NOT_EQUAL, &megamorphic_call, Assembler::kNearJump); |
+ __ movq(RAX, FieldAddress(RDI, String::hash_offset())); |
+ __ cmpq(RAX, Immediate(0)); |
+ __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
+ |
+ __ Bind(&megamorphic_call); |
+ __ Comment("Slow case: megamorphic call"); |
+ } |
__ LoadObject(RBX, cache); |
if (FLAG_use_megamorphic_stub) { |
__ Call(*StubCode::MegamorphicLookup_entry()); |
@@ -1339,6 +1358,7 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall( |
} |
__ call(RCX); |
+ __ Bind(&done); |
RecordSafepoint(locs, slow_path_argument_count); |
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); |
if (FLAG_precompiled_mode) { |