Index: src/ia32/stub-cache-ia32.cc |
=================================================================== |
--- src/ia32/stub-cache-ia32.cc (revision 5044) |
+++ src/ia32/stub-cache-ia32.cc (working copy) |
@@ -111,7 +111,7 @@ |
Register receiver, |
String* name, |
Register r0, |
- Register extra) { |
+ Register r1) { |
ASSERT(name->IsSymbol()); |
__ IncrementCounter(&Counters::negative_lookups, 1); |
__ IncrementCounter(&Counters::negative_lookups_miss, 1); |
@@ -160,10 +160,7 @@ |
for (int i = 0; i < kProbes; i++) { |
// r0 points to properties hash. |
// Compute the masked index: (hash + i + i * i) & mask. |
- if (extra.is(no_reg)) { |
- __ push(receiver); |
- } |
- Register index = extra.is(no_reg) ? receiver : extra; |
+ Register index = r1; |
// Capacity is smi 2^n. |
__ mov(index, FieldOperand(properties, kCapacityOffset)); |
__ dec(index); |
@@ -175,27 +172,18 @@ |
ASSERT(StringDictionary::kEntrySize == 3); |
__ lea(index, Operand(index, index, times_2, 0)); // index *= 3. |
- Register entity_name = extra.is(no_reg) ? properties : extra; |
+ Register entity_name = r1; |
// Having undefined at this place means the name is not contained. |
ASSERT_EQ(kSmiTagSize, 1); |
__ mov(entity_name, Operand(properties, index, times_half_pointer_size, |
kElementsStartOffset - kHeapObjectTag)); |
__ cmp(entity_name, Factory::undefined_value()); |
- if (extra.is(no_reg)) { |
- // 'receiver' shares a register with 'entity_name'. |
- __ pop(receiver); |
- } |
if (i != kProbes - 1) { |
__ j(equal, &done, taken); |
// Stop if found the property. |
__ cmp(entity_name, Handle<String>(name)); |
__ j(equal, miss_label, not_taken); |
- |
- if (extra.is(no_reg)) { |
- // Restore the properties if their register was occupied by the name. |
- __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
- } |
} else { |
// Give up probing if still not found the undefined value. |
__ j(not_equal, miss_label, not_taken); |
@@ -527,6 +515,7 @@ |
Register receiver, |
Register scratch1, |
Register scratch2, |
+ Register scratch3, |
Label* miss) { |
ASSERT(holder->HasNamedInterceptor()); |
ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); |
@@ -543,6 +532,7 @@ |
receiver, |
scratch1, |
scratch2, |
+ scratch3, |
holder, |
lookup, |
name, |
@@ -554,6 +544,7 @@ |
receiver, |
scratch1, |
scratch2, |
+ scratch3, |
name, |
holder, |
miss); |
@@ -566,6 +557,7 @@ |
Register receiver, |
Register scratch1, |
Register scratch2, |
+ Register scratch3, |
JSObject* interceptor_holder, |
LookupResult* lookup, |
String* name, |
@@ -605,7 +597,7 @@ |
Register holder = |
stub_compiler_->CheckPrototypes(object, receiver, |
interceptor_holder, scratch1, |
- scratch2, name, depth1, miss); |
+ scratch2, scratch3, name, depth1, miss); |
// Invoke an interceptor and if it provides a value, |
// branch to |regular_invoke|. |
@@ -621,7 +613,7 @@ |
if (interceptor_holder != lookup->holder()) { |
stub_compiler_->CheckPrototypes(interceptor_holder, receiver, |
lookup->holder(), scratch1, |
- scratch2, name, depth2, miss); |
+ scratch2, scratch3, name, depth2, miss); |
} else { |
// CheckPrototypes has a side effect of fetching a 'holder' |
// for API (object which is instanceof for the signature). It's |
@@ -657,12 +649,13 @@ |
Register receiver, |
Register scratch1, |
Register scratch2, |
+ Register scratch3, |
String* name, |
JSObject* interceptor_holder, |
Label* miss_label) { |
Register holder = |
stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, |
- scratch1, scratch2, name, |
+ scratch1, scratch2, scratch3, name, |
miss_label); |
__ EnterInternalFrame(); |
@@ -864,14 +857,15 @@ |
Register object_reg, |
JSObject* holder, |
Register holder_reg, |
- Register scratch, |
+ Register scratch1, |
+ Register scratch2, |
String* name, |
int save_at_depth, |
- Label* miss, |
- Register extra) { |
+ Label* miss) { |
// Make sure there's no overlap between holder and object registers. |
- ASSERT(!scratch.is(object_reg) && !scratch.is(holder_reg)); |
- ASSERT(!extra.is(object_reg) && !extra.is(holder_reg) && !extra.is(scratch)); |
+ ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
+ ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
+ && !scratch2.is(scratch1)); |
// Keep track of the current object in register reg. |
Register reg = object_reg; |
JSObject* current = object; |
@@ -911,31 +905,31 @@ |
miss, |
reg, |
name, |
- scratch, |
- extra); |
- __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); |
+ scratch1, |
+ scratch2); |
+ __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
reg = holder_reg; // from now the object is in holder_reg |
- __ mov(reg, FieldOperand(scratch, Map::kPrototypeOffset)); |
+ __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
} else if (Heap::InNewSpace(prototype)) { |
// Get the map of the current object. |
- __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); |
- __ cmp(Operand(scratch), Immediate(Handle<Map>(current->map()))); |
+ __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
+ __ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map()))); |
// Branch on the result of the map check. |
__ j(not_equal, miss, not_taken); |
// Check access rights to the global object. This has to happen |
// after the map check so that we know that the object is |
// actually a global object. |
if (current->IsJSGlobalProxy()) { |
- __ CheckAccessGlobalProxy(reg, scratch, miss); |
+ __ CheckAccessGlobalProxy(reg, scratch1, miss); |
// Restore scratch register to be the map of the object. |
// We load the prototype from the map in the scratch register. |
- __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); |
+ __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
} |
// The prototype is in new space; we cannot store a reference |
// to it in the code. Load it from the map. |
reg = holder_reg; // from now the object is in holder_reg |
- __ mov(reg, FieldOperand(scratch, Map::kPrototypeOffset)); |
+ __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
} else { |
// Check the map of the current object. |
__ cmp(FieldOperand(reg, HeapObject::kMapOffset), |
@@ -946,7 +940,7 @@ |
// after the map check so that we know that the object is |
// actually a global object. |
if (current->IsJSGlobalProxy()) { |
- __ CheckAccessGlobalProxy(reg, scratch, miss); |
+ __ CheckAccessGlobalProxy(reg, scratch1, miss); |
} |
// The prototype is in old space; load it directly. |
reg = holder_reg; // from now the object is in holder_reg |
@@ -973,7 +967,7 @@ |
// Perform security check for access to the global object. |
ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
if (holder->IsJSGlobalProxy()) { |
- __ CheckAccessGlobalProxy(reg, scratch, miss); |
+ __ CheckAccessGlobalProxy(reg, scratch1, miss); |
}; |
// If we've skipped any global objects, it's not enough to verify |
@@ -983,7 +977,7 @@ |
object, |
holder, |
name, |
- scratch, |
+ scratch1, |
miss); |
if (result->IsFailure()) set_failure(Failure::cast(result)); |
@@ -997,6 +991,7 @@ |
Register receiver, |
Register scratch1, |
Register scratch2, |
+ Register scratch3, |
int index, |
String* name, |
Label* miss) { |
@@ -1007,7 +1002,7 @@ |
// Check the prototype chain. |
Register reg = |
CheckPrototypes(object, receiver, holder, |
- scratch1, scratch2, name, miss); |
+ scratch1, scratch2, scratch3, name, miss); |
// Get the value from the properties. |
GenerateFastPropertyLoad(masm(), eax, reg, holder, index); |
@@ -1021,6 +1016,7 @@ |
Register name_reg, |
Register scratch1, |
Register scratch2, |
+ Register scratch3, |
AccessorInfo* callback, |
String* name, |
Label* miss, |
@@ -1032,7 +1028,7 @@ |
// Check that the maps haven't changed. |
Register reg = |
CheckPrototypes(object, receiver, holder, |
- scratch1, scratch2, name, miss); |
+ scratch1, scratch2, scratch3, name, miss); |
Handle<AccessorInfo> callback_handle(callback); |
@@ -1096,6 +1092,7 @@ |
Register receiver, |
Register scratch1, |
Register scratch2, |
+ Register scratch3, |
Object* value, |
String* name, |
Label* miss) { |
@@ -1106,7 +1103,7 @@ |
// Check that the maps haven't changed. |
Register reg = |
CheckPrototypes(object, receiver, holder, |
- scratch1, scratch2, name, miss); |
+ scratch1, scratch2, scratch3, name, miss); |
// Return the constant value. |
__ mov(eax, Handle<Object>(value)); |
@@ -1121,6 +1118,7 @@ |
Register name_reg, |
Register scratch1, |
Register scratch2, |
+ Register scratch3, |
String* name, |
Label* miss) { |
ASSERT(interceptor_holder->HasNamedInterceptor()); |
@@ -1149,7 +1147,8 @@ |
// property from further up the prototype chain if the call fails. |
// Check that the maps haven't changed. |
Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, |
- scratch1, scratch2, name, miss); |
+ scratch1, scratch2, scratch3, |
+ name, miss); |
ASSERT(holder_reg.is(receiver) || holder_reg.is(scratch1)); |
// Save necessary data before invoking an interceptor. |
@@ -1197,6 +1196,7 @@ |
lookup->holder(), |
scratch1, |
scratch2, |
+ scratch3, |
name, |
miss); |
} |
@@ -1237,7 +1237,7 @@ |
// Check that the maps haven't changed. |
Register holder_reg = |
CheckPrototypes(object, receiver, interceptor_holder, |
- scratch1, scratch2, name, miss); |
+ scratch1, scratch2, scratch3, name, miss); |
__ pop(scratch2); // save old return address |
PushInterceptorArguments(masm(), receiver, holder_reg, |
name_reg, interceptor_holder); |
@@ -1312,8 +1312,8 @@ |
__ j(zero, &miss, not_taken); |
// Do the right check and compute the holder register. |
- Register reg = CheckPrototypes(object, edx, holder, ebx, eax, |
- name, &miss, edi); |
+ Register reg = CheckPrototypes(object, edx, holder, ebx, eax, edi, |
+ name, &miss); |
GenerateFastPropertyLoad(masm(), edi, reg, holder, index); |
@@ -1375,7 +1375,7 @@ |
CheckPrototypes(JSObject::cast(object), edx, |
holder, ebx, |
- eax, name, &miss, edi); |
+ eax, edi, name, &miss); |
if (argc == 0) { |
// Noop, return the length. |
@@ -1521,7 +1521,7 @@ |
__ j(zero, &miss); |
CheckPrototypes(JSObject::cast(object), edx, |
holder, ebx, |
- eax, name, &miss, edi); |
+ eax, edi, name, &miss); |
// Get the elements array of the object. |
__ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); |
@@ -1596,7 +1596,7 @@ |
Context::STRING_FUNCTION_INDEX, |
eax); |
CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, |
- ebx, edx, name, &miss, edi); |
+ ebx, edx, edi, name, &miss); |
Register receiver = ebx; |
Register index = edi; |
@@ -1661,7 +1661,7 @@ |
Context::STRING_FUNCTION_INDEX, |
eax); |
CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, |
- ebx, edx, name, &miss, edi); |
+ ebx, edx, edi, name, &miss); |
Register receiver = eax; |
Register index = edi; |
@@ -1766,7 +1766,7 @@ |
// Check that the maps haven't changed. |
CheckPrototypes(JSObject::cast(object), edx, holder, |
- ebx, eax, name, depth, &miss, edi); |
+ ebx, eax, edi, name, depth, &miss); |
// Patch the receiver on the stack with the global proxy if |
// necessary. |
@@ -1789,7 +1789,7 @@ |
GenerateDirectLoadGlobalFunctionPrototype( |
masm(), Context::STRING_FUNCTION_INDEX, eax); |
CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, |
- ebx, edx, name, &miss, edi); |
+ ebx, edx, edi, name, &miss); |
} |
break; |
@@ -1809,7 +1809,7 @@ |
GenerateDirectLoadGlobalFunctionPrototype( |
masm(), Context::NUMBER_FUNCTION_INDEX, eax); |
CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, |
- ebx, edx, name, &miss, edi); |
+ ebx, edx, edi, name, &miss); |
} |
break; |
} |
@@ -1830,7 +1830,7 @@ |
GenerateDirectLoadGlobalFunctionPrototype( |
masm(), Context::BOOLEAN_FUNCTION_INDEX, eax); |
CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, |
- ebx, edx, name, &miss, edi); |
+ ebx, edx, edi, name, &miss); |
} |
break; |
} |
@@ -1890,6 +1890,7 @@ |
edx, |
ebx, |
edi, |
+ eax, |
&miss); |
// Restore receiver. |
@@ -1952,7 +1953,7 @@ |
} |
// Check that the maps haven't changed. |
- CheckPrototypes(object, edx, holder, ebx, eax, name, &miss, edi); |
+ CheckPrototypes(object, edx, holder, ebx, eax, edi, name, &miss); |
// Get the value from the cell. |
__ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); |
@@ -2228,7 +2229,7 @@ |
// Check the maps of the full prototype chain. Also check that |
// global property cells up to (but not including) the last object |
// in the prototype chain are empty. |
- CheckPrototypes(object, eax, last, ebx, edx, name, &miss); |
+ CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss); |
// If the last object in the prototype chain is a global object, |
// check that the global property cell is empty. |
@@ -2265,7 +2266,7 @@ |
// ----------------------------------- |
Label miss; |
- GenerateLoadField(object, holder, eax, ebx, edx, index, name, &miss); |
+ GenerateLoadField(object, holder, eax, ebx, edx, edi, index, name, &miss); |
__ bind(&miss); |
GenerateLoadMiss(masm(), Code::LOAD_IC); |
@@ -2286,7 +2287,7 @@ |
Label miss; |
Failure* failure = Failure::InternalError(); |
- bool success = GenerateLoadCallback(object, holder, eax, ecx, ebx, edx, |
+ bool success = GenerateLoadCallback(object, holder, eax, ecx, ebx, edx, edi, |
callback, name, &miss, &failure); |
if (!success) return failure; |
@@ -2309,7 +2310,7 @@ |
// ----------------------------------- |
Label miss; |
- GenerateLoadConstant(object, holder, eax, ebx, edx, value, name, &miss); |
+ GenerateLoadConstant(object, holder, eax, ebx, edx, edi, value, name, &miss); |
__ bind(&miss); |
GenerateLoadMiss(masm(), Code::LOAD_IC); |
@@ -2340,6 +2341,7 @@ |
ecx, |
edx, |
ebx, |
+ edi, |
name, |
&miss); |
@@ -2372,7 +2374,7 @@ |
} |
// Check that the maps haven't changed. |
- CheckPrototypes(object, eax, holder, ebx, edx, name, &miss, edi); |
+ CheckPrototypes(object, eax, holder, ebx, edx, edi, name, &miss); |
// Get the value from the cell. |
__ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); |
@@ -2417,7 +2419,7 @@ |
__ cmp(Operand(eax), Immediate(Handle<String>(name))); |
__ j(not_equal, &miss, not_taken); |
- GenerateLoadField(receiver, holder, edx, ebx, ecx, index, name, &miss); |
+ GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); |
__ bind(&miss); |
__ DecrementCounter(&Counters::keyed_load_field, 1); |
@@ -2446,7 +2448,7 @@ |
__ j(not_equal, &miss, not_taken); |
Failure* failure = Failure::InternalError(); |
- bool success = GenerateLoadCallback(receiver, holder, edx, eax, ebx, ecx, |
+ bool success = GenerateLoadCallback(receiver, holder, edx, eax, ebx, ecx, edi, |
callback, name, &miss, &failure); |
if (!success) return failure; |
@@ -2476,7 +2478,7 @@ |
__ cmp(Operand(eax), Immediate(Handle<String>(name))); |
__ j(not_equal, &miss, not_taken); |
- GenerateLoadConstant(receiver, holder, edx, ebx, ecx, |
+ GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi, |
value, name, &miss); |
__ bind(&miss); |
__ DecrementCounter(&Counters::keyed_load_constant_function, 1); |
@@ -2512,6 +2514,7 @@ |
eax, |
ecx, |
ebx, |
+ edi, |
name, |
&miss); |
__ bind(&miss); |