Index: src/arm/stub-cache-arm.cc |
=================================================================== |
--- src/arm/stub-cache-arm.cc (revision 2423) |
+++ src/arm/stub-cache-arm.cc (working copy) |
@@ -171,110 +171,6 @@ |
} |
-void StubCompiler::GenerateLoadField(MacroAssembler* masm, |
- JSObject* object, |
- JSObject* holder, |
- Register receiver, |
- Register scratch1, |
- Register scratch2, |
- int index, |
- Label* miss_label) { |
- // Check that the receiver isn't a smi. |
- __ tst(receiver, Operand(kSmiTagMask)); |
- __ b(eq, miss_label); |
- |
- // Check that the maps haven't changed. |
- Register reg = |
- masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); |
- GenerateFastPropertyLoad(masm, r0, reg, holder, index); |
- __ Ret(); |
-} |
- |
- |
-void StubCompiler::GenerateLoadConstant(MacroAssembler* masm, |
- JSObject* object, |
- JSObject* holder, |
- Register receiver, |
- Register scratch1, |
- Register scratch2, |
- Object* value, |
- Label* miss_label) { |
- // Check that the receiver isn't a smi. |
- __ tst(receiver, Operand(kSmiTagMask)); |
- __ b(eq, miss_label); |
- |
- // Check that the maps haven't changed. |
- Register reg = |
- masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); |
- |
- // Return the constant value. |
- __ mov(r0, Operand(Handle<Object>(value))); |
- __ Ret(); |
-} |
- |
- |
-void StubCompiler::GenerateLoadCallback(MacroAssembler* masm, |
- JSObject* object, |
- JSObject* holder, |
- Register receiver, |
- Register name, |
- Register scratch1, |
- Register scratch2, |
- AccessorInfo* callback, |
- Label* miss_label) { |
- // Check that the receiver isn't a smi. |
- __ tst(receiver, Operand(kSmiTagMask)); |
- __ b(eq, miss_label); |
- |
- // Check that the maps haven't changed. |
- Register reg = |
- masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); |
- |
- // Push the arguments on the JS stack of the caller. |
- __ push(receiver); // receiver |
- __ mov(ip, Operand(Handle<AccessorInfo>(callback))); // callback data |
- __ push(ip); |
- __ push(name); // name |
- __ push(reg); // holder |
- |
- // Do tail-call to the runtime system. |
- ExternalReference load_callback_property = |
- ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); |
- __ TailCallRuntime(load_callback_property, 4); |
-} |
- |
- |
-void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm, |
- JSObject* object, |
- JSObject* holder, |
- Smi* lookup_hint, |
- Register receiver, |
- Register name, |
- Register scratch1, |
- Register scratch2, |
- Label* miss_label) { |
- // Check that the receiver isn't a smi. |
- __ tst(receiver, Operand(kSmiTagMask)); |
- __ b(eq, miss_label); |
- |
- // Check that the maps haven't changed. |
- Register reg = |
- masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); |
- |
- // Push the arguments on the JS stack of the caller. |
- __ push(receiver); // receiver |
- __ push(reg); // holder |
- __ push(name); // name |
- __ mov(scratch1, Operand(lookup_hint)); |
- __ push(scratch1); |
- |
- // Do tail-call to the runtime system. |
- ExternalReference load_ic_property = |
- ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); |
- __ TailCallRuntime(load_ic_property, 4); |
-} |
- |
- |
void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, |
Register receiver, |
Register scratch, |
@@ -462,6 +358,147 @@ |
#define __ ACCESS_MASM(masm()) |
+Register StubCompiler::CheckPrototypes(JSObject* object, |
antonm
2009/07/10 09:28:43
maybe it should go to macro-assembler?
|
+ Register object_reg, |
+ JSObject* holder, |
+ Register holder_reg, |
+ Register scratch, |
+ String* name, |
+ Label* miss) { |
+ // Check that the maps haven't changed. |
+ Register result = |
+ masm()->CheckMaps(object, object_reg, holder, holder_reg, scratch, miss); |
+ |
+ // If we've skipped any global objects, it's not enough to verify |
+ // that their maps haven't changed. |
+ while (object != holder) { |
+ if (object->IsGlobalObject()) { |
antonm
2009/07/10 09:28:43
just curious, I guess there might be only single g
|
+ GlobalObject* global = GlobalObject::cast(object); |
+ Object* probe = global->EnsurePropertyCell(name); |
+ if (probe->IsFailure()) { |
+ set_failure(Failure::cast(probe)); |
+ return result; |
+ } |
+ JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); |
antonm
2009/07/10 09:28:43
for my education: why it must be the hole?
|
+ ASSERT(cell->value()->IsTheHole()); |
+ __ mov(scratch, Operand(Handle<Object>(cell))); |
antonm
2009/07/10 09:28:43
cell always live not in new space, correct?
|
+ __ ldr(scratch, |
+ FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); |
+ __ cmp(scratch, Operand(Factory::the_hole_value())); |
+ __ b(ne, miss); |
+ } |
+ object = JSObject::cast(object->GetPrototype()); |
antonm
2009/07/10 09:28:43
just for my education: it's always safe to assume
|
+ } |
+ |
+ // Return the register containin the holder. |
+ return result; |
+} |
+ |
+ |
+void StubCompiler::GenerateLoadField(JSObject* object, |
antonm
2009/07/10 09:28:43
cosmetic issue: is the move of methods needed---if
|
+ JSObject* holder, |
+ Register receiver, |
+ Register scratch1, |
+ Register scratch2, |
+ int index, |
+ String* name, |
+ Label* miss) { |
+ // Check that the receiver isn't a smi. |
+ __ tst(receiver, Operand(kSmiTagMask)); |
+ __ b(eq, miss); |
+ |
+ // Check that the maps haven't changed. |
+ Register reg = |
+ CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); |
+ GenerateFastPropertyLoad(masm(), r0, reg, holder, index); |
+ __ Ret(); |
+} |
+ |
+ |
+void StubCompiler::GenerateLoadConstant(JSObject* object, |
+ JSObject* holder, |
+ Register receiver, |
+ Register scratch1, |
+ Register scratch2, |
+ Object* value, |
+ String* name, |
+ Label* miss) { |
+ // Check that the receiver isn't a smi. |
+ __ tst(receiver, Operand(kSmiTagMask)); |
+ __ b(eq, miss); |
+ |
+ // Check that the maps haven't changed. |
+ Register reg = |
+ CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); |
+ |
+ // Return the constant value. |
+ __ mov(r0, Operand(Handle<Object>(value))); |
+ __ Ret(); |
+} |
+ |
+ |
+void StubCompiler::GenerateLoadCallback(JSObject* object, |
+ JSObject* holder, |
+ Register receiver, |
+ Register name_reg, |
+ Register scratch1, |
+ Register scratch2, |
+ AccessorInfo* callback, |
+ String* name, |
+ Label* miss) { |
+ // Check that the receiver isn't a smi. |
+ __ tst(receiver, Operand(kSmiTagMask)); |
+ __ b(eq, miss); |
+ |
+ // Check that the maps haven't changed. |
+ Register reg = |
+ CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); |
+ |
+ // Push the arguments on the JS stack of the caller. |
+ __ push(receiver); // receiver |
+ __ mov(ip, Operand(Handle<AccessorInfo>(callback))); // callback data |
+ __ push(ip); |
+ __ push(name_reg); // name |
+ __ push(reg); // holder |
+ |
+ // Do tail-call to the runtime system. |
+ ExternalReference load_callback_property = |
+ ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); |
+ __ TailCallRuntime(load_callback_property, 4); |
+} |
+ |
+ |
+void StubCompiler::GenerateLoadInterceptor(JSObject* object, |
+ JSObject* holder, |
+ Smi* lookup_hint, |
+ Register receiver, |
+ Register name_reg, |
+ Register scratch1, |
+ Register scratch2, |
+ String* name, |
+ Label* miss) { |
+ // Check that the receiver isn't a smi. |
+ __ tst(receiver, Operand(kSmiTagMask)); |
+ __ b(eq, miss); |
+ |
+ // Check that the maps haven't changed. |
+ Register reg = |
+ CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); |
+ |
+ // Push the arguments on the JS stack of the caller. |
+ __ push(receiver); // receiver |
+ __ push(reg); // holder |
+ __ push(name_reg); // name |
+ __ mov(scratch1, Operand(lookup_hint)); |
+ __ push(scratch1); |
+ |
+ // Do tail-call to the runtime system. |
+ ExternalReference load_ic_property = |
+ ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); |
+ __ TailCallRuntime(load_ic_property, 4); |
+} |
+ |
+ |
Object* StubCompiler::CompileLazyCompile(Code::Flags flags) { |
// ----------- S t a t e ------------- |
// -- r1: function |
@@ -513,7 +550,7 @@ |
// Do the right check and compute the holder register. |
Register reg = |
- masm()->CheckMaps(JSObject::cast(object), r0, holder, r3, r2, &miss); |
+ CheckPrototypes(JSObject::cast(object), r0, holder, r3, r2, name, &miss); |
GenerateFastPropertyLoad(masm(), r1, reg, holder, index); |
// Check that the function really is a function. |
@@ -546,6 +583,7 @@ |
Object* CallStubCompiler::CompileCallConstant(Object* object, |
JSObject* holder, |
JSFunction* function, |
+ String* name, |
CheckType check) { |
// ----------- S t a t e ------------- |
// -- lr: return address |
@@ -569,7 +607,7 @@ |
switch (check) { |
case RECEIVER_MAP_CHECK: |
// Check that the maps haven't changed. |
- __ CheckMaps(JSObject::cast(object), r1, holder, r3, r2, &miss); |
+ CheckPrototypes(JSObject::cast(object), r1, holder, r3, r2, name, &miss); |
// Patch the receiver on the stack with the global proxy if |
// necessary. |
@@ -587,8 +625,8 @@ |
GenerateLoadGlobalFunctionPrototype(masm(), |
Context::STRING_FUNCTION_INDEX, |
r2); |
- __ CheckMaps(JSObject::cast(object->GetPrototype()), |
- r2, holder, r3, r1, &miss); |
+ CheckPrototypes(JSObject::cast(object->GetPrototype()), r2, holder, r3, |
+ r1, name, &miss); |
break; |
case NUMBER_CHECK: { |
@@ -603,8 +641,8 @@ |
GenerateLoadGlobalFunctionPrototype(masm(), |
Context::NUMBER_FUNCTION_INDEX, |
r2); |
- __ CheckMaps(JSObject::cast(object->GetPrototype()), |
- r2, holder, r3, r1, &miss); |
+ CheckPrototypes(JSObject::cast(object->GetPrototype()), r2, holder, r3, |
+ r1, name, &miss); |
break; |
} |
@@ -620,13 +658,13 @@ |
GenerateLoadGlobalFunctionPrototype(masm(), |
Context::BOOLEAN_FUNCTION_INDEX, |
r2); |
- __ CheckMaps(JSObject::cast(object->GetPrototype()), |
- r2, holder, r3, r1, &miss); |
+ CheckPrototypes(JSObject::cast(object->GetPrototype()), r2, holder, r3, |
+ r1, name, &miss); |
break; |
} |
case JSARRAY_HAS_FAST_ELEMENTS_CHECK: |
- __ CheckMaps(JSObject::cast(object), r1, holder, r3, r2, &miss); |
+ CheckPrototypes(JSObject::cast(object), r1, holder, r3, r2, name, &miss); |
// Make sure object->elements()->map() != Heap::hash_table_map() |
// Get the elements array of the object. |
__ ldr(r3, FieldMemOperand(r1, JSObject::kElementsOffset)); |
@@ -712,7 +750,7 @@ |
} |
// Check that the maps haven't changed. |
- masm()->CheckMaps(object, r0, holder, r3, r2, &miss); |
+ CheckPrototypes(object, r0, holder, r3, r2, name, &miss); |
// Get the value from the cell. |
__ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); |
@@ -941,7 +979,7 @@ |
__ ldr(r0, MemOperand(sp, 0)); |
- GenerateLoadField(masm(), object, holder, r0, r3, r1, index, &miss); |
+ GenerateLoadField(object, holder, r0, r3, r1, index, name, &miss); |
__ bind(&miss); |
GenerateLoadMiss(masm(), Code::LOAD_IC); |
@@ -962,7 +1000,7 @@ |
Label miss; |
__ ldr(r0, MemOperand(sp, 0)); |
- GenerateLoadCallback(masm(), object, holder, r0, r2, r3, r1, callback, &miss); |
+ GenerateLoadCallback(object, holder, r0, r2, r3, r1, callback, name, &miss); |
__ bind(&miss); |
GenerateLoadMiss(masm(), Code::LOAD_IC); |
@@ -984,7 +1022,7 @@ |
__ ldr(r0, MemOperand(sp, 0)); |
- GenerateLoadConstant(masm(), object, holder, r0, r3, r1, value, &miss); |
+ GenerateLoadConstant(object, holder, r0, r3, r1, value, name, &miss); |
__ bind(&miss); |
GenerateLoadMiss(masm(), Code::LOAD_IC); |
@@ -1005,14 +1043,14 @@ |
__ ldr(r0, MemOperand(sp, 0)); |
- GenerateLoadInterceptor(masm(), |
- object, |
+ GenerateLoadInterceptor(object, |
holder, |
holder->InterceptorPropertyLookupHint(name), |
r0, |
r2, |
r3, |
r1, |
+ name, |
&miss); |
__ bind(&miss); |
GenerateLoadMiss(masm(), Code::LOAD_IC); |
@@ -1048,7 +1086,7 @@ |
} |
// Check that the map of the global has not changed. |
- masm()->CheckMaps(object, r1, holder, r3, r0, &miss); |
+ CheckPrototypes(object, r1, holder, r3, r0, name, &miss); |
// Get the value from the cell. |
__ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); |
@@ -1091,7 +1129,7 @@ |
__ cmp(r2, Operand(Handle<String>(name))); |
__ b(ne, &miss); |
- GenerateLoadField(masm(), receiver, holder, r0, r3, r1, index, &miss); |
+ GenerateLoadField(receiver, holder, r0, r3, r1, index, name, &miss); |
__ bind(&miss); |
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
@@ -1116,8 +1154,7 @@ |
__ cmp(r2, Operand(Handle<String>(name))); |
__ b(ne, &miss); |
- GenerateLoadCallback(masm(), receiver, holder, r0, r2, r3, |
- r1, callback, &miss); |
+ GenerateLoadCallback(receiver, holder, r0, r2, r3, r1, callback, name, &miss); |
__ bind(&miss); |
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
@@ -1143,7 +1180,7 @@ |
__ cmp(r2, Operand(Handle<String>(name))); |
__ b(ne, &miss); |
- GenerateLoadConstant(masm(), receiver, holder, r0, r3, r1, value, &miss); |
+ GenerateLoadConstant(receiver, holder, r0, r3, r1, value, name, &miss); |
__ bind(&miss); |
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
@@ -1169,14 +1206,14 @@ |
__ cmp(r2, Operand(Handle<String>(name))); |
__ b(ne, &miss); |
- GenerateLoadInterceptor(masm(), |
- receiver, |
+ GenerateLoadInterceptor(receiver, |
holder, |
Smi::FromInt(JSObject::kLookupInHolder), |
r0, |
r2, |
r3, |
r1, |
+ name, |
&miss); |
__ bind(&miss); |
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |