Index: runtime/vm/flow_graph_compiler_ia32.cc |
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc |
index eac4f3cca211950ea23ba80ea9d8f40d41a10f85..8a7c349c5e7738afcff4fb83e9798d6a8106a10a 100644 |
--- a/runtime/vm/flow_graph_compiler_ia32.cc |
+++ b/runtime/vm/flow_graph_compiler_ia32.cc |
@@ -1300,7 +1300,27 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall( |
MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor)); |
__ Comment("MegamorphicCall"); |
+ // Load receiver into EBX. |
__ movl(EBX, Address(ESP, (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"); |
+ __ testl(EBX, Immediate(kSmiTagMask)); |
+ __ j(NOT_ZERO, &try_onebytestring, Assembler::kNearJump); // Non-smi value. |
+ __ movl(EAX, EBX); |
+ __ jmp(&done, Assembler::kNearJump); |
+ |
+ __ Bind(&try_onebytestring); |
+ __ CompareClassId(EBX, kOneByteStringCid, EAX); |
+ __ j(NOT_EQUAL, &megamorphic_call, Assembler::kNearJump); |
+ __ movl(EAX, FieldAddress(EBX, String::hash_offset())); |
+ __ cmpl(EAX, Immediate(0)); |
+ __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
+ |
+ __ Bind(&megamorphic_call); |
+ __ Comment("Slow case: megamorphic call"); |
+ } |
__ LoadObject(ECX, cache); |
if (FLAG_use_megamorphic_stub) { |
__ Call(*StubCode::MegamorphicLookup_entry()); |
@@ -1309,6 +1329,7 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall( |
} |
__ call(EBX); |
+ __ Bind(&done); |
AddCurrentDescriptor(RawPcDescriptors::kOther, |
Thread::kNoDeoptId, token_pos); |
RecordSafepoint(locs, slow_path_argument_count); |