Index: src/mips/stub-cache-mips.cc |
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc |
index cf6ba81591eec7d0545455c80db1173b313c5b8a..19eb44e31900c941b84f56dfbe7c7d0aeb5e81f9 100644 |
--- a/src/mips/stub-cache-mips.cc |
+++ b/src/mips/stub-cache-mips.cc |
@@ -1234,6 +1234,43 @@ void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, |
} |
+void StubCompiler::GenerateDictionaryLoadCallback(Register receiver, |
+ Register name_reg, |
+ Register scratch1, |
+ Register scratch2, |
+ Register scratch3, |
+ Handle<AccessorInfo> callback, |
+ Handle<String> name, |
+ Label* miss) { |
+ Register dictionary = scratch1; |
+ Register index = scratch2; |
+ __ lw(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
+ |
+ // Probe the dictionary. |
+ Label probe_done; |
+ StringDictionaryLookupStub::GeneratePositiveLookup(masm(), |
+ miss, |
+ &probe_done, |
+ dictionary, |
+ name_reg, |
+ index, // Set if we hit. |
+ scratch3); |
+ __ bind(&probe_done); |
+ |
+ // If probing finds an entry in the dictionary, check that the value is the |
+ // callback. |
+ const int kElementsStartOffset = |
+ StringDictionary::kHeaderSize + |
+ StringDictionary::kElementsStartIndex * kPointerSize; |
+ const int kValueOffset = kElementsStartOffset + kPointerSize; |
+ __ Addu(scratch1, dictionary, Operand(kValueOffset - kHeapObjectTag)); |
+ __ sll(scratch3, index, kPointerSizeLog2); |
+ __ addu(scratch1, scratch1, scratch3); |
+ __ lw(scratch3, MemOperand(scratch1)); |
+ __ Branch(miss, ne, scratch3, Operand(callback)); |
+} |
+ |
+ |
void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, |
Handle<JSObject> holder, |
Register receiver, |
@@ -1251,6 +1288,11 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, |
Register reg = CheckPrototypes(object, receiver, holder, scratch1, |
scratch2, scratch3, name, miss); |
+ if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { |
+ GenerateDictionaryLoadCallback( |
+ receiver, name_reg, scratch1, scratch2, scratch3, callback, name, miss); |
+ } |
+ |
// Build AccessorInfo::args_ list on the stack and push property name below |
// the exit frame to make GC aware of them and store pointers to them. |
__ push(receiver); |