Index: src/arm/stub-cache-arm.cc |
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc |
index 24fc3e169366b54b75a4025415537e9500480724..8b242f7f045c1b6a7f68c487c3cd8fe749577009 100644 |
--- a/src/arm/stub-cache-arm.cc |
+++ b/src/arm/stub-cache-arm.cc |
@@ -293,15 +293,132 @@ void PropertyHandlerCompiler::GenerateCheckPropertyCell( |
} |
+static void PushInterceptorArguments(MacroAssembler* masm, Register receiver, |
+ Register holder, Register name, |
+ Handle<JSObject> holder_obj) { |
+ STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); |
+ STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1); |
+ STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2); |
+ STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3); |
+ STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4); |
+ __ push(name); |
+ Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); |
+ ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); |
+ Register scratch = name; |
+ __ mov(scratch, Operand(interceptor)); |
+ __ push(scratch); |
+ __ push(receiver); |
+ __ push(holder); |
+} |
+ |
+ |
+static void CompileCallLoadPropertyWithInterceptor( |
+ MacroAssembler* masm, Register receiver, Register holder, Register name, |
+ Handle<JSObject> holder_obj, IC::UtilityId id) { |
+ PushInterceptorArguments(masm, receiver, holder, name, holder_obj); |
+ __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()), |
+ NamedLoadHandlerCompiler::kInterceptorArgsLength); |
+} |
+ |
+ |
+// Generate call to api function. |
+void PropertyHandlerCompiler::GenerateFastApiCall( |
+ MacroAssembler* masm, const CallOptimization& optimization, |
+ Handle<Map> receiver_map, Register receiver, Register scratch_in, |
+ bool is_store, int argc, Register* values) { |
+ ASSERT(!receiver.is(scratch_in)); |
+ __ push(receiver); |
+ // Write the arguments to stack frame. |
+ for (int i = 0; i < argc; i++) { |
+ Register arg = values[argc - 1 - i]; |
+ ASSERT(!receiver.is(arg)); |
+ ASSERT(!scratch_in.is(arg)); |
+ __ push(arg); |
+ } |
+ ASSERT(optimization.is_simple_api_call()); |
+ |
+ // Abi for CallApiFunctionStub. |
+ Register callee = r0; |
+ Register call_data = r4; |
+ Register holder = r2; |
+ Register api_function_address = r1; |
+ |
+ // Put holder in place. |
+ CallOptimization::HolderLookup holder_lookup; |
+ Handle<JSObject> api_holder = |
+ optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup); |
+ switch (holder_lookup) { |
+ case CallOptimization::kHolderIsReceiver: |
+ __ Move(holder, receiver); |
+ break; |
+ case CallOptimization::kHolderFound: |
+ __ Move(holder, api_holder); |
+ break; |
+ case CallOptimization::kHolderNotFound: |
+ UNREACHABLE(); |
+ break; |
+ } |
+ |
+ Isolate* isolate = masm->isolate(); |
+ Handle<JSFunction> function = optimization.constant_function(); |
+ Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
+ Handle<Object> call_data_obj(api_call_info->data(), isolate); |
+ |
+ // Put callee in place. |
+ __ Move(callee, function); |
+ |
+ bool call_data_undefined = false; |
+ // Put call_data in place. |
+ if (isolate->heap()->InNewSpace(*call_data_obj)) { |
+ __ Move(call_data, api_call_info); |
+ __ ldr(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset)); |
+ } else if (call_data_obj->IsUndefined()) { |
+ call_data_undefined = true; |
+ __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); |
+ } else { |
+ __ Move(call_data, call_data_obj); |
+ } |
+ |
+ // Put api_function_address in place. |
+ Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
+ ApiFunction fun(function_address); |
+ ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; |
+ ExternalReference ref = ExternalReference(&fun, type, masm->isolate()); |
+ __ mov(api_function_address, Operand(ref)); |
+ |
+ // Jump to stub. |
+ CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); |
+ __ TailCallStub(&stub); |
+} |
+ |
+ |
+void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm, |
+ Handle<Code> code) { |
+ __ Jump(code, RelocInfo::CODE_TARGET); |
+} |
+ |
+ |
+#undef __ |
+#define __ ACCESS_MASM(masm()) |
+ |
+ |
+void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, |
+ Handle<Name> name) { |
+ if (!label->is_unused()) { |
+ __ bind(label); |
+ __ mov(this->name(), Operand(name)); |
+ } |
+} |
+ |
+ |
void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup( |
- MacroAssembler* masm, Handle<JSObject> holder, Register holder_reg, |
- Handle<Name> name, Label* miss) { |
- if (holder->IsJSGlobalObject()) { |
- GenerateCheckPropertyCell( |
- masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); |
- } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { |
- GenerateDictionaryNegativeLookup( |
- masm, miss, holder_reg, name, scratch1(), scratch2()); |
+ Register holder_reg, Handle<Name> name, Label* miss) { |
+ if (holder()->IsJSGlobalObject()) { |
+ GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(holder()), |
+ name, scratch1(), miss); |
+ } else if (!holder()->HasFastProperties()) { |
+ GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1(), |
+ scratch2()); |
} |
} |
@@ -311,10 +428,9 @@ void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup( |
// may be clobbered. Upon branch to miss_label, the receiver and name |
// registers have their original values. |
void NamedStoreHandlerCompiler::GenerateStoreTransition( |
- MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition, |
- Handle<Name> name, Register receiver_reg, Register storage_reg, |
- Register value_reg, Register scratch1, Register scratch2, Register scratch3, |
- Label* miss_label, Label* slow) { |
+ Handle<Map> transition, Handle<Name> name, Register receiver_reg, |
+ Register storage_reg, Register value_reg, Register scratch1, |
+ Register scratch2, Register scratch3, Label* miss_label, Label* slow) { |
// r0 : value |
Label exit; |
@@ -325,7 +441,7 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( |
ASSERT(!representation.IsNone()); |
if (details.type() == CONSTANT) { |
- Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); |
+ Handle<Object> constant(descriptors->GetValue(descriptor), isolate()); |
__ Move(scratch1, constant); |
__ cmp(value_reg, scratch1); |
__ b(ne, miss_label); |
@@ -383,9 +499,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( |
__ Push(r2, r0); |
__ TailCallExternalReference( |
ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), |
- masm->isolate()), |
- 3, |
- 1); |
+ isolate()), |
+ 3, 1); |
return; |
} |
@@ -483,15 +598,15 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( |
// may be clobbered. Upon branch to miss_label, the receiver and name |
// registers have their original values. |
void NamedStoreHandlerCompiler::GenerateStoreField( |
- MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, |
- Register receiver_reg, Register name_reg, Register value_reg, |
- Register scratch1, Register scratch2, Label* miss_label) { |
+ Handle<JSObject> object, LookupResult* lookup, Register receiver_reg, |
+ Register name_reg, Register value_reg, Register scratch1, Register scratch2, |
+ Label* miss_label) { |
// r0 : value |
Label exit; |
- // Stub never generated for non-global objects that require access |
- // checks. |
- ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
+ // Stub never generated for objects that require access checks. |
+ ASSERT(!object->IsAccessCheckNeeded()); |
+ ASSERT(!object->IsJSGlobalProxy()); |
FieldIndex index = lookup->GetFieldIndex(); |
@@ -603,134 +718,6 @@ void NamedStoreHandlerCompiler::GenerateStoreField( |
} |
-void NamedStoreHandlerCompiler::GenerateRestoreName(MacroAssembler* masm, |
- Label* label, |
- Handle<Name> name) { |
- if (!label->is_unused()) { |
- __ bind(label); |
- __ mov(this->name(), Operand(name)); |
- } |
-} |
- |
- |
-static void PushInterceptorArguments(MacroAssembler* masm, |
- Register receiver, |
- Register holder, |
- Register name, |
- Handle<JSObject> holder_obj) { |
- STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); |
- STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1); |
- STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2); |
- STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3); |
- STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4); |
- __ push(name); |
- Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); |
- ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); |
- Register scratch = name; |
- __ mov(scratch, Operand(interceptor)); |
- __ push(scratch); |
- __ push(receiver); |
- __ push(holder); |
-} |
- |
- |
-static void CompileCallLoadPropertyWithInterceptor( |
- MacroAssembler* masm, |
- Register receiver, |
- Register holder, |
- Register name, |
- Handle<JSObject> holder_obj, |
- IC::UtilityId id) { |
- PushInterceptorArguments(masm, receiver, holder, name, holder_obj); |
- __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()), |
- NamedLoadHandlerCompiler::kInterceptorArgsLength); |
-} |
- |
- |
-// Generate call to api function. |
-void PropertyHandlerCompiler::GenerateFastApiCall( |
- MacroAssembler* masm, const CallOptimization& optimization, |
- Handle<Map> receiver_map, Register receiver, Register scratch_in, |
- bool is_store, int argc, Register* values) { |
- ASSERT(!receiver.is(scratch_in)); |
- __ push(receiver); |
- // Write the arguments to stack frame. |
- for (int i = 0; i < argc; i++) { |
- Register arg = values[argc-1-i]; |
- ASSERT(!receiver.is(arg)); |
- ASSERT(!scratch_in.is(arg)); |
- __ push(arg); |
- } |
- ASSERT(optimization.is_simple_api_call()); |
- |
- // Abi for CallApiFunctionStub. |
- Register callee = r0; |
- Register call_data = r4; |
- Register holder = r2; |
- Register api_function_address = r1; |
- |
- // Put holder in place. |
- CallOptimization::HolderLookup holder_lookup; |
- Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( |
- receiver_map, |
- &holder_lookup); |
- switch (holder_lookup) { |
- case CallOptimization::kHolderIsReceiver: |
- __ Move(holder, receiver); |
- break; |
- case CallOptimization::kHolderFound: |
- __ Move(holder, api_holder); |
- break; |
- case CallOptimization::kHolderNotFound: |
- UNREACHABLE(); |
- break; |
- } |
- |
- Isolate* isolate = masm->isolate(); |
- Handle<JSFunction> function = optimization.constant_function(); |
- Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
- Handle<Object> call_data_obj(api_call_info->data(), isolate); |
- |
- // Put callee in place. |
- __ Move(callee, function); |
- |
- bool call_data_undefined = false; |
- // Put call_data in place. |
- if (isolate->heap()->InNewSpace(*call_data_obj)) { |
- __ Move(call_data, api_call_info); |
- __ ldr(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset)); |
- } else if (call_data_obj->IsUndefined()) { |
- call_data_undefined = true; |
- __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); |
- } else { |
- __ Move(call_data, call_data_obj); |
- } |
- |
- // Put api_function_address in place. |
- Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
- ApiFunction fun(function_address); |
- ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; |
- ExternalReference ref = ExternalReference(&fun, |
- type, |
- masm->isolate()); |
- __ mov(api_function_address, Operand(ref)); |
- |
- // Jump to stub. |
- CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); |
- __ TailCallStub(&stub); |
-} |
- |
- |
-void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm, |
- Handle<Code> code) { |
- __ Jump(code, RelocInfo::CODE_TARGET); |
-} |
- |
- |
-#undef __ |
-#define __ ACCESS_MASM(masm()) |
- |
- |
Register PropertyHandlerCompiler::CheckPrototypes( |
Register object_reg, Register holder_reg, Register scratch1, |
Register scratch2, Handle<Name> name, Label* miss, |
@@ -856,7 +843,7 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { |
if (!miss->is_unused()) { |
Label success; |
__ b(&success); |
- GenerateRestoreName(masm(), miss, name); |
+ GenerateRestoreName(miss, name); |
TailCallBuiltin(masm(), MissBuiltin(kind())); |
__ bind(&success); |
} |
@@ -1314,17 +1301,6 @@ Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, |
} |
-void NamedStoreHandlerCompiler::GenerateStoreArrayLength() { |
- // Prepare tail call to StoreIC_ArrayLength. |
- __ Push(receiver(), value()); |
- |
- ExternalReference ref = |
- ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength), |
- masm()->isolate()); |
- __ TailCallExternalReference(ref, 2, 1); |
-} |
- |
- |
Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic( |
MapHandleList* receiver_maps, CodeHandleList* handler_stubs, |
MapHandleList* transitioned_maps) { |