Commit e508f1d4 authored by verwaest@chromium.org's avatar verwaest@chromium.org

Cleanup in stub-cache.cc; remove unused ArrayLength store ICs.

BUG=
R=ishell@chromium.org

Review URL: https://codereview.chromium.org/430783002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22805 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent aa45ec52
...@@ -293,15 +293,132 @@ void PropertyHandlerCompiler::GenerateCheckPropertyCell( ...@@ -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( void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup(
MacroAssembler* masm, Handle<JSObject> holder, Register holder_reg, Register holder_reg, Handle<Name> name, Label* miss) {
Handle<Name> name, Label* miss) { if (holder()->IsJSGlobalObject()) {
if (holder->IsJSGlobalObject()) { GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(holder()),
GenerateCheckPropertyCell( name, scratch1(), miss);
masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); } else if (!holder()->HasFastProperties()) {
} else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1(),
GenerateDictionaryNegativeLookup( scratch2());
masm, miss, holder_reg, name, scratch1(), scratch2());
} }
} }
...@@ -311,10 +428,9 @@ void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup( ...@@ -311,10 +428,9 @@ void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup(
// may be clobbered. Upon branch to miss_label, the receiver and name // may be clobbered. Upon branch to miss_label, the receiver and name
// registers have their original values. // registers have their original values.
void NamedStoreHandlerCompiler::GenerateStoreTransition( void NamedStoreHandlerCompiler::GenerateStoreTransition(
MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition, Handle<Map> transition, Handle<Name> name, Register receiver_reg,
Handle<Name> name, Register receiver_reg, Register storage_reg, Register storage_reg, Register value_reg, Register scratch1,
Register value_reg, Register scratch1, Register scratch2, Register scratch3, Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
Label* miss_label, Label* slow) {
// r0 : value // r0 : value
Label exit; Label exit;
...@@ -325,7 +441,7 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -325,7 +441,7 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
ASSERT(!representation.IsNone()); ASSERT(!representation.IsNone());
if (details.type() == CONSTANT) { if (details.type() == CONSTANT) {
Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
__ Move(scratch1, constant); __ Move(scratch1, constant);
__ cmp(value_reg, scratch1); __ cmp(value_reg, scratch1);
__ b(ne, miss_label); __ b(ne, miss_label);
...@@ -383,9 +499,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -383,9 +499,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
__ Push(r2, r0); __ Push(r2, r0);
__ TailCallExternalReference( __ TailCallExternalReference(
ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
masm->isolate()), isolate()),
3, 3, 1);
1);
return; return;
} }
...@@ -483,15 +598,15 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -483,15 +598,15 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
// may be clobbered. Upon branch to miss_label, the receiver and name // may be clobbered. Upon branch to miss_label, the receiver and name
// registers have their original values. // registers have their original values.
void NamedStoreHandlerCompiler::GenerateStoreField( void NamedStoreHandlerCompiler::GenerateStoreField(
MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, Handle<JSObject> object, LookupResult* lookup, Register receiver_reg,
Register receiver_reg, Register name_reg, Register value_reg, Register name_reg, Register value_reg, Register scratch1, Register scratch2,
Register scratch1, Register scratch2, Label* miss_label) { Label* miss_label) {
// r0 : value // r0 : value
Label exit; Label exit;
// Stub never generated for non-global objects that require access // Stub never generated for objects that require access checks.
// checks. ASSERT(!object->IsAccessCheckNeeded());
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); ASSERT(!object->IsJSGlobalProxy());
FieldIndex index = lookup->GetFieldIndex(); FieldIndex index = lookup->GetFieldIndex();
...@@ -603,134 +718,6 @@ void NamedStoreHandlerCompiler::GenerateStoreField( ...@@ -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 PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1, Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss, Register scratch2, Handle<Name> name, Label* miss,
...@@ -856,7 +843,7 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { ...@@ -856,7 +843,7 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
if (!miss->is_unused()) { if (!miss->is_unused()) {
Label success; Label success;
__ b(&success); __ b(&success);
GenerateRestoreName(masm(), miss, name); GenerateRestoreName(miss, name);
TailCallBuiltin(masm(), MissBuiltin(kind())); TailCallBuiltin(masm(), MissBuiltin(kind()));
__ bind(&success); __ bind(&success);
} }
...@@ -1305,17 +1292,6 @@ Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, ...@@ -1305,17 +1292,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( Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
MapHandleList* receiver_maps, CodeHandleList* handler_stubs, MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
MapHandleList* transitioned_maps) { MapHandleList* transitioned_maps) {
......
...@@ -247,15 +247,135 @@ void PropertyHandlerCompiler::GenerateCheckPropertyCell( ...@@ -247,15 +247,135 @@ 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, receiver, 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,
bool is_store, int argc, Register* values) {
ASSERT(!AreAliased(receiver, scratch));
MacroAssembler::PushPopQueue queue(masm);
queue.Queue(receiver);
// Write the arguments to the stack frame.
for (int i = 0; i < argc; i++) {
Register arg = values[argc - 1 - i];
ASSERT(!AreAliased(receiver, scratch, arg));
queue.Queue(arg);
}
queue.PushQueued();
ASSERT(optimization.is_simple_api_call());
// Abi for CallApiFunctionStub.
Register callee = x0;
Register call_data = x4;
Register holder = x2;
Register api_function_address = x1;
// Put holder in place.
CallOptimization::HolderLookup holder_lookup;
Handle<JSObject> api_holder =
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
switch (holder_lookup) {
case CallOptimization::kHolderIsReceiver:
__ Mov(holder, receiver);
break;
case CallOptimization::kHolderFound:
__ LoadObject(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.
__ LoadObject(callee, function);
bool call_data_undefined = false;
// Put call_data in place.
if (isolate->heap()->InNewSpace(*call_data_obj)) {
__ LoadObject(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 {
__ LoadObject(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 ref = ExternalReference(
&fun, ExternalReference::DIRECT_API_CALL, masm->isolate());
__ Mov(api_function_address, 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( void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup(
MacroAssembler* masm, Handle<JSObject> holder, Register holder_reg, Register holder_reg, Handle<Name> name, Label* miss) {
Handle<Name> name, Label* miss) { if (holder()->IsJSGlobalObject()) {
if (holder->IsJSGlobalObject()) { GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(holder()),
GenerateCheckPropertyCell( name, scratch1(), miss);
masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); } else if (!holder()->HasFastProperties()) {
} else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1(),
GenerateDictionaryNegativeLookup( scratch2());
masm, miss, holder_reg, name, scratch1(), scratch2());
} }
} }
...@@ -265,10 +385,9 @@ void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup( ...@@ -265,10 +385,9 @@ void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup(
// may be clobbered. Upon branch to miss_label, the receiver and name registers // may be clobbered. Upon branch to miss_label, the receiver and name registers
// have their original values. // have their original values.
void NamedStoreHandlerCompiler::GenerateStoreTransition( void NamedStoreHandlerCompiler::GenerateStoreTransition(
MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition, Handle<Map> transition, Handle<Name> name, Register receiver_reg,
Handle<Name> name, Register receiver_reg, Register storage_reg, Register storage_reg, Register value_reg, Register scratch1,
Register value_reg, Register scratch1, Register scratch2, Register scratch3, Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
Label* miss_label, Label* slow) {
Label exit; Label exit;
ASSERT(!AreAliased(receiver_reg, storage_reg, value_reg, ASSERT(!AreAliased(receiver_reg, storage_reg, value_reg,
...@@ -284,7 +403,7 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -284,7 +403,7 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
ASSERT(!representation.IsNone()); ASSERT(!representation.IsNone());
if (details.type() == CONSTANT) { if (details.type() == CONSTANT) {
Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
__ LoadObject(scratch1, constant); __ LoadObject(scratch1, constant);
__ Cmp(value_reg, scratch1); __ Cmp(value_reg, scratch1);
__ B(ne, miss_label); __ B(ne, miss_label);
...@@ -309,7 +428,7 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -309,7 +428,7 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
__ Bind(&do_store); __ Bind(&do_store);
} }
} else if (representation.IsDouble()) { } else if (representation.IsDouble()) {
UseScratchRegisterScope temps(masm); UseScratchRegisterScope temps(masm());
DoubleRegister temp_double = temps.AcquireD(); DoubleRegister temp_double = temps.AcquireD();
__ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag); __ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag);
...@@ -337,9 +456,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -337,9 +456,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
__ Push(receiver_reg, scratch1, value_reg); __ Push(receiver_reg, scratch1, value_reg);
__ TailCallExternalReference( __ TailCallExternalReference(
ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
masm->isolate()), isolate()),
3, 3, 1);
1);
return; return;
} }
...@@ -430,15 +548,15 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -430,15 +548,15 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
// be clobbered. Upon branch to miss_label, the receiver and name registers have // be clobbered. Upon branch to miss_label, the receiver and name registers have
// their original values. // their original values.
void NamedStoreHandlerCompiler::GenerateStoreField( void NamedStoreHandlerCompiler::GenerateStoreField(
MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, Handle<JSObject> object, LookupResult* lookup, Register receiver_reg,
Register receiver_reg, Register name_reg, Register value_reg, Register name_reg, Register value_reg, Register scratch1, Register scratch2,
Register scratch1, Register scratch2, Label* miss_label) { Label* miss_label) {
// x0 : value // x0 : value
Label exit; Label exit;
// Stub never generated for non-global objects that require access // Stub never generated for objects that require access checks.
// checks. ASSERT(!object->IsAccessCheckNeeded());
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); ASSERT(!object->IsJSGlobalProxy());
FieldIndex index = lookup->GetFieldIndex(); FieldIndex index = lookup->GetFieldIndex();
...@@ -465,7 +583,7 @@ void NamedStoreHandlerCompiler::GenerateStoreField( ...@@ -465,7 +583,7 @@ void NamedStoreHandlerCompiler::GenerateStoreField(
__ Bind(&do_store); __ Bind(&do_store);
} }
} else if (representation.IsDouble()) { } else if (representation.IsDouble()) {
UseScratchRegisterScope temps(masm); UseScratchRegisterScope temps(masm());
DoubleRegister temp_double = temps.AcquireD(); DoubleRegister temp_double = temps.AcquireD();
__ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag); __ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag);
...@@ -552,135 +670,6 @@ void NamedStoreHandlerCompiler::GenerateStoreField( ...@@ -552,135 +670,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, receiver, 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,
bool is_store, int argc, Register* values) {
ASSERT(!AreAliased(receiver, scratch));
MacroAssembler::PushPopQueue queue(masm);
queue.Queue(receiver);
// Write the arguments to the stack frame.
for (int i = 0; i < argc; i++) {
Register arg = values[argc-1-i];
ASSERT(!AreAliased(receiver, scratch, arg));
queue.Queue(arg);
}
queue.PushQueued();
ASSERT(optimization.is_simple_api_call());
// Abi for CallApiFunctionStub.
Register callee = x0;
Register call_data = x4;
Register holder = x2;
Register api_function_address = x1;
// Put holder in place.
CallOptimization::HolderLookup holder_lookup;
Handle<JSObject> api_holder =
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
switch (holder_lookup) {
case CallOptimization::kHolderIsReceiver:
__ Mov(holder, receiver);
break;
case CallOptimization::kHolderFound:
__ LoadObject(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.
__ LoadObject(callee, function);
bool call_data_undefined = false;
// Put call_data in place.
if (isolate->heap()->InNewSpace(*call_data_obj)) {
__ LoadObject(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 {
__ LoadObject(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 ref = ExternalReference(&fun,
ExternalReference::DIRECT_API_CALL,
masm->isolate());
__ Mov(api_function_address, 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 PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1, Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss, Register scratch2, Handle<Name> name, Label* miss,
...@@ -809,7 +798,7 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { ...@@ -809,7 +798,7 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
Label success; Label success;
__ B(&success); __ B(&success);
GenerateRestoreName(masm(), miss, name); GenerateRestoreName(miss, name);
TailCallBuiltin(masm(), MissBuiltin(kind())); TailCallBuiltin(masm(), MissBuiltin(kind()));
__ Bind(&success); __ Bind(&success);
...@@ -1277,17 +1266,6 @@ Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, ...@@ -1277,17 +1266,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( Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
MapHandleList* receiver_maps, CodeHandleList* handler_stubs, MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
MapHandleList* transitioned_maps) { MapHandleList* transitioned_maps) {
......
...@@ -370,16 +370,6 @@ void PropertyHandlerCompiler::GenerateFastApiCall( ...@@ -370,16 +370,6 @@ void PropertyHandlerCompiler::GenerateFastApiCall(
} }
void NamedStoreHandlerCompiler::GenerateRestoreName(MacroAssembler* masm,
Label* label,
Handle<Name> name) {
if (!label->is_unused()) {
__ bind(label);
__ mov(this->name(), Immediate(name));
}
}
// Generate code to check that a global property cell is empty. Create // Generate code to check that a global property cell is empty. Create
// the property cell at compilation time if no cell exists for the // the property cell at compilation time if no cell exists for the
// property. // property.
...@@ -401,15 +391,33 @@ void PropertyHandlerCompiler::GenerateCheckPropertyCell( ...@@ -401,15 +391,33 @@ void PropertyHandlerCompiler::GenerateCheckPropertyCell(
} }
void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
Handle<Code> code) {
__ jmp(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(), Immediate(name));
}
}
void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup( void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup(
MacroAssembler* masm, Handle<JSObject> holder, Register holder_reg, Register holder_reg, Handle<Name> name, Label* miss) {
Handle<Name> name, Label* miss) { if (holder()->IsJSGlobalObject()) {
if (holder->IsJSGlobalObject()) { GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(holder()),
GenerateCheckPropertyCell( name, scratch1(), miss);
masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); } else if (!holder()->HasFastProperties()) {
} else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1(),
GenerateDictionaryNegativeLookup( scratch2());
masm, miss, holder_reg, name, scratch1(), scratch2());
} }
} }
...@@ -417,10 +425,9 @@ void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup( ...@@ -417,10 +425,9 @@ void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup(
// Receiver_reg is preserved on jumps to miss_label, but may be destroyed if // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
// store is successful. // store is successful.
void NamedStoreHandlerCompiler::GenerateStoreTransition( void NamedStoreHandlerCompiler::GenerateStoreTransition(
MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition, Handle<Map> transition, Handle<Name> name, Register receiver_reg,
Handle<Name> name, Register receiver_reg, Register storage_reg, Register storage_reg, Register value_reg, Register scratch1,
Register value_reg, Register scratch1, Register scratch2, Register unused, Register scratch2, Register unused, Label* miss_label, Label* slow) {
Label* miss_label, Label* slow) {
int descriptor = transition->LastAdded(); int descriptor = transition->LastAdded();
DescriptorArray* descriptors = transition->instance_descriptors(); DescriptorArray* descriptors = transition->instance_descriptors();
PropertyDetails details = descriptors->GetDetails(descriptor); PropertyDetails details = descriptors->GetDetails(descriptor);
...@@ -428,7 +435,7 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -428,7 +435,7 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
ASSERT(!representation.IsNone()); ASSERT(!representation.IsNone());
if (details.type() == CONSTANT) { if (details.type() == CONSTANT) {
Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
__ CmpObject(value_reg, constant); __ CmpObject(value_reg, constant);
__ j(not_equal, miss_label); __ j(not_equal, miss_label);
} else if (representation.IsSmi()) { } else if (representation.IsSmi()) {
...@@ -461,8 +468,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -461,8 +468,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
__ jmp(&do_store); __ jmp(&do_store);
__ bind(&heap_number); __ bind(&heap_number);
__ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
miss_label, DONT_DO_SMI_CHECK); DONT_DO_SMI_CHECK);
__ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
__ bind(&do_store); __ bind(&do_store);
...@@ -484,9 +491,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -484,9 +491,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
__ push(scratch1); __ push(scratch1);
__ TailCallExternalReference( __ TailCallExternalReference(
ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
masm->isolate()), isolate()),
3, 3, 1);
1);
return; return;
} }
...@@ -577,12 +583,12 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -577,12 +583,12 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
// Both name_reg and receiver_reg are preserved on jumps to miss_label, // Both name_reg and receiver_reg are preserved on jumps to miss_label,
// but may be destroyed if store is successful. // but may be destroyed if store is successful.
void NamedStoreHandlerCompiler::GenerateStoreField( void NamedStoreHandlerCompiler::GenerateStoreField(
MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, Handle<JSObject> object, LookupResult* lookup, Register receiver_reg,
Register receiver_reg, Register name_reg, Register value_reg, Register name_reg, Register value_reg, Register scratch1, Register scratch2,
Register scratch1, Register scratch2, Label* miss_label) { Label* miss_label) {
// Stub never generated for non-global objects that require access // Stub never generated for objects that require access checks.
// checks. ASSERT(!object->IsAccessCheckNeeded());
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); ASSERT(!object->IsJSGlobalProxy());
FieldIndex index = lookup->GetFieldIndex(); FieldIndex index = lookup->GetFieldIndex();
...@@ -624,8 +630,8 @@ void NamedStoreHandlerCompiler::GenerateStoreField( ...@@ -624,8 +630,8 @@ void NamedStoreHandlerCompiler::GenerateStoreField(
__ SmiTag(value_reg); __ SmiTag(value_reg);
__ jmp(&do_store); __ jmp(&do_store);
__ bind(&heap_number); __ bind(&heap_number);
__ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
miss_label, DONT_DO_SMI_CHECK); DONT_DO_SMI_CHECK);
__ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
__ bind(&do_store); __ bind(&do_store);
__ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0);
...@@ -681,16 +687,6 @@ void NamedStoreHandlerCompiler::GenerateStoreField( ...@@ -681,16 +687,6 @@ void NamedStoreHandlerCompiler::GenerateStoreField(
} }
void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
Handle<Code> code) {
__ jmp(code, RelocInfo::CODE_TARGET);
}
#undef __
#define __ ACCESS_MASM(masm())
Register PropertyHandlerCompiler::CheckPrototypes( Register PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1, Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss, Register scratch2, Handle<Name> name, Label* miss,
...@@ -816,7 +812,7 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { ...@@ -816,7 +812,7 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
if (!miss->is_unused()) { if (!miss->is_unused()) {
Label success; Label success;
__ jmp(&success); __ jmp(&success);
GenerateRestoreName(masm(), miss, name); GenerateRestoreName(miss, name);
TailCallBuiltin(masm(), MissBuiltin(kind())); TailCallBuiltin(masm(), MissBuiltin(kind()));
__ bind(&success); __ bind(&success);
} }
...@@ -1129,20 +1125,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( ...@@ -1129,20 +1125,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
} }
void NamedStoreHandlerCompiler::GenerateStoreArrayLength() {
// Prepare tail call to StoreIC_ArrayLength.
__ pop(scratch1()); // remove the return address
__ push(receiver());
__ push(value());
__ push(scratch1()); // restore return address
ExternalReference ref =
ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength),
masm()->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic( Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
MapHandleList* receiver_maps, CodeHandleList* handler_stubs, MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
MapHandleList* transitioned_maps) { MapHandleList* transitioned_maps) {
......
...@@ -1435,7 +1435,7 @@ Handle<Code> StoreIC::CompileStoreHandler(LookupResult* lookup, ...@@ -1435,7 +1435,7 @@ Handle<Code> StoreIC::CompileStoreHandler(LookupResult* lookup,
PropertyDetails details = lookup->GetPropertyDetails(); PropertyDetails details = lookup->GetPropertyDetails();
if (details.type() != CALLBACKS && details.attributes() == NONE) { if (details.type() != CALLBACKS && details.attributes() == NONE) {
return compiler.CompileStoreTransition(lookup, transition, name); return compiler.CompileStoreTransition(transition, name);
} }
} else { } else {
switch (lookup->type()) { switch (lookup->type()) {
...@@ -2067,30 +2067,6 @@ RUNTIME_FUNCTION(StoreIC_MissFromStubFailure) { ...@@ -2067,30 +2067,6 @@ RUNTIME_FUNCTION(StoreIC_MissFromStubFailure) {
} }
RUNTIME_FUNCTION(StoreIC_ArrayLength) {
TimerEventScope<TimerEventIcMiss> timer(isolate);
HandleScope scope(isolate);
ASSERT(args.length() == 2);
Handle<JSArray> receiver = args.at<JSArray>(0);
Handle<Object> len = args.at<Object>(1);
// The generated code should filter out non-Smis before we get here.
ASSERT(len->IsSmi());
#ifdef DEBUG
// The length property has to be a writable callback property.
LookupResult debug_lookup(isolate);
receiver->LookupOwn(isolate->factory()->length_string(), &debug_lookup);
ASSERT(debug_lookup.IsPropertyCallbacks() && !debug_lookup.IsReadOnly());
#endif
RETURN_FAILURE_ON_EXCEPTION(
isolate, JSArray::SetElementsLength(receiver, len));
return *len;
}
// Extend storage is called in a store inline cache when // Extend storage is called in a store inline cache when
// it is necessary to extend the properties array of a // it is necessary to extend the properties array of a
// JSObject. // JSObject.
......
...@@ -22,7 +22,6 @@ const int kMaxKeyedPolymorphism = 4; ...@@ -22,7 +22,6 @@ const int kMaxKeyedPolymorphism = 4;
ICU(CallIC_Miss) \ ICU(CallIC_Miss) \
ICU(CallIC_Customization_Miss) \ ICU(CallIC_Customization_Miss) \
ICU(StoreIC_Miss) \ ICU(StoreIC_Miss) \
ICU(StoreIC_ArrayLength) \
ICU(StoreIC_Slow) \ ICU(StoreIC_Slow) \
ICU(SharedStoreIC_ExtendStorage) \ ICU(SharedStoreIC_ExtendStorage) \
ICU(KeyedStoreIC_Miss) \ ICU(KeyedStoreIC_Miss) \
......
...@@ -34,12 +34,12 @@ void StubCache::Initialize() { ...@@ -34,12 +34,12 @@ void StubCache::Initialize() {
static Code::Flags CommonStubCacheChecks(Name* name, Map* map, static Code::Flags CommonStubCacheChecks(Name* name, Map* map,
Code::Flags flags, Heap* heap) { Code::Flags flags) {
flags = Code::RemoveTypeAndHolderFromFlags(flags); flags = Code::RemoveTypeAndHolderFromFlags(flags);
// Validate that the name does not move on scavenge, and that we // Validate that the name does not move on scavenge, and that we
// can use identity checks instead of structural equality checks. // can use identity checks instead of structural equality checks.
ASSERT(!heap->InNewSpace(name)); ASSERT(!name->GetHeap()->InNewSpace(name));
ASSERT(name->IsUniqueName()); ASSERT(name->IsUniqueName());
// The state bits are not important to the hash function because the stub // The state bits are not important to the hash function because the stub
...@@ -57,8 +57,7 @@ static Code::Flags CommonStubCacheChecks(Name* name, Map* map, ...@@ -57,8 +57,7 @@ static Code::Flags CommonStubCacheChecks(Name* name, Map* map,
Code* StubCache::Set(Name* name, Map* map, Code* code) { Code* StubCache::Set(Name* name, Map* map, Code* code) {
Code::Flags flags = Code::Flags flags = CommonStubCacheChecks(name, map, code->flags());
CommonStubCacheChecks(name, map, code->flags(), isolate()->heap());
// Compute the primary entry. // Compute the primary entry.
int primary_offset = PrimaryOffset(name, flags, map); int primary_offset = PrimaryOffset(name, flags, map);
...@@ -87,7 +86,7 @@ Code* StubCache::Set(Name* name, Map* map, Code* code) { ...@@ -87,7 +86,7 @@ Code* StubCache::Set(Name* name, Map* map, Code* code) {
Code* StubCache::Get(Name* name, Map* map, Code::Flags flags) { Code* StubCache::Get(Name* name, Map* map, Code::Flags flags) {
flags = CommonStubCacheChecks(name, map, flags, isolate()->heap()); flags = CommonStubCacheChecks(name, map, flags);
int primary_offset = PrimaryOffset(name, flags, map); int primary_offset = PrimaryOffset(name, flags, map);
Entry* primary = entry(primary_, primary_offset); Entry* primary = entry(primary_, primary_offset);
if (primary->key == name && primary->map == map) { if (primary->key == name && primary->map == map) {
...@@ -108,9 +107,8 @@ Handle<Code> PropertyICCompiler::Find(Handle<Name> name, ...@@ -108,9 +107,8 @@ Handle<Code> PropertyICCompiler::Find(Handle<Name> name,
CacheHolderFlag cache_holder) { CacheHolderFlag cache_holder) {
Code::Flags flags = Code::ComputeMonomorphicFlags( Code::Flags flags = Code::ComputeMonomorphicFlags(
kind, extra_state, cache_holder); kind, extra_state, cache_holder);
Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), Object* probe = stub_holder->FindInCodeCache(*name, flags);
name->GetIsolate()); if (probe->IsCode()) return handle(Code::cast(probe));
if (probe->IsCode()) return Handle<Code>::cast(probe);
return Handle<Code>::null(); return Handle<Code>::null();
} }
...@@ -121,10 +119,8 @@ Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name, ...@@ -121,10 +119,8 @@ Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name,
CacheHolderFlag cache_holder, CacheHolderFlag cache_holder,
Code::StubType type) { Code::StubType type) {
Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder); Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder);
Object* probe = stub_holder->FindInCodeCache(*name, flags);
Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), if (probe->IsCode()) return handle(Code::cast(probe));
name->GetIsolate());
if (probe->IsCode()) return Handle<Code>::cast(probe);
return Handle<Code>::null(); return Handle<Code>::null();
} }
...@@ -957,7 +953,7 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter( ...@@ -957,7 +953,7 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter(
// TODO(verwaest): Cleanup. holder() is actually the receiver. // TODO(verwaest): Cleanup. holder() is actually the receiver.
Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
LookupResult* lookup, Handle<Map> transition, Handle<Name> name) { Handle<Map> transition, Handle<Name> name) {
Label miss, slow; Label miss, slow;
// Ensure no transitions to deprecated maps are followed. // Ensure no transitions to deprecated maps are followed.
...@@ -982,23 +978,17 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( ...@@ -982,23 +978,17 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
// prototype chain) is in slow mode, we need to do a negative lookup on the // prototype chain) is in slow mode, we need to do a negative lookup on the
// holder. // holder.
if (is_nonexistent) { if (is_nonexistent) {
GenerateNegativeHolderLookup(masm(), holder(), holder_reg, name, &miss); GenerateNegativeHolderLookup(holder_reg, name, &miss);
} }
GenerateStoreTransition(masm(), GenerateStoreTransition(transition, name, receiver(), this->name(), value(),
lookup, scratch1(), scratch2(), scratch3(), &miss, &slow);
transition,
name,
receiver(), this->name(), value(),
scratch1(), scratch2(), scratch3(),
&miss,
&slow);
// Handle store cache miss. // Handle store cache miss.
GenerateRestoreName(masm(), &miss, name); GenerateRestoreName(&miss, name);
TailCallBuiltin(masm(), MissBuiltin(kind())); TailCallBuiltin(masm(), MissBuiltin(kind()));
GenerateRestoreName(masm(), &slow, name); GenerateRestoreName(&slow, name);
TailCallBuiltin(masm(), SlowBuiltin(kind())); TailCallBuiltin(masm(), SlowBuiltin(kind()));
return GetCode(kind(), Code::FAST, name); return GetCode(kind(), Code::FAST, name);
} }
...@@ -1011,8 +1001,8 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupResult* lookup, ...@@ -1011,8 +1001,8 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupResult* lookup,
FrontendHeader(receiver(), name, &miss); FrontendHeader(receiver(), name, &miss);
// Generate store field code. // Generate store field code.
GenerateStoreField(masm(), holder(), lookup, receiver(), this->name(), GenerateStoreField(holder(), lookup, receiver(), this->name(), value(),
value(), scratch1(), scratch2(), &miss); scratch1(), scratch2(), &miss);
// Handle store cache miss. // Handle store cache miss.
__ bind(&miss); __ bind(&miss);
...@@ -1021,27 +1011,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupResult* lookup, ...@@ -1021,27 +1011,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupResult* lookup,
} }
Handle<Code> NamedStoreHandlerCompiler::CompileStoreArrayLength(
LookupResult* lookup, Handle<Name> name) {
// This accepts as a receiver anything JSArray::SetElementsLength accepts
// (currently anything except for external arrays which means anything with
// elements of FixedArray type). Value must be a number, but only smis are
// accepted as the most common case.
Label miss;
// Check that value is a smi.
__ JumpIfNotSmi(value(), &miss);
// Generate tail call to StoreIC_ArrayLength.
GenerateStoreArrayLength();
// Handle miss case.
__ bind(&miss);
TailCallBuiltin(masm(), MissBuiltin(kind()));
return GetCode(kind(), Code::FAST, name);
}
Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter( Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter(
Handle<JSObject> object, Handle<Name> name, Handle<JSFunction> setter) { Handle<JSObject> object, Handle<Name> name, Handle<JSFunction> setter) {
Frontend(receiver(), name); Frontend(receiver(), name);
......
...@@ -561,26 +561,17 @@ class NamedStoreHandlerCompiler : public PropertyHandlerCompiler { ...@@ -561,26 +561,17 @@ class NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
virtual ~NamedStoreHandlerCompiler() {} virtual ~NamedStoreHandlerCompiler() {}
Handle<Code> CompileStoreTransition(LookupResult* lookup, Handle<Code> CompileStoreTransition(Handle<Map> transition,
Handle<Map> transition,
Handle<Name> name); Handle<Name> name);
Handle<Code> CompileStoreField(LookupResult* lookup, Handle<Name> name); Handle<Code> CompileStoreField(LookupResult* lookup, Handle<Name> name);
Handle<Code> CompileStoreArrayLength(LookupResult* lookup, Handle<Name> name);
Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name, Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name,
Handle<ExecutableAccessorInfo> callback); Handle<ExecutableAccessorInfo> callback);
Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name, Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name,
const CallOptimization& call_optimization); const CallOptimization& call_optimization);
Handle<Code> CompileStoreViaSetter(Handle<JSObject> object, Handle<Name> name, Handle<Code> CompileStoreViaSetter(Handle<JSObject> object, Handle<Name> name,
Handle<JSFunction> setter); Handle<JSFunction> setter);
Handle<Code> CompileStoreInterceptor(Handle<Name> name); Handle<Code> CompileStoreInterceptor(Handle<Name> name);
static void GenerateStoreViaSetter(MacroAssembler* masm, static void GenerateStoreViaSetter(MacroAssembler* masm,
Handle<HeapType> type, Register receiver, Handle<HeapType> type, Register receiver,
Handle<JSFunction> setter); Handle<JSFunction> setter);
...@@ -595,40 +586,22 @@ class NamedStoreHandlerCompiler : public PropertyHandlerCompiler { ...@@ -595,40 +586,22 @@ class NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
Label* miss); Label* miss);
virtual void FrontendFooter(Handle<Name> name, Label* miss); virtual void FrontendFooter(Handle<Name> name, Label* miss);
void GenerateRestoreName(MacroAssembler* masm, Label* label, void GenerateRestoreName(Label* label, Handle<Name> name);
Handle<Name> name);
private: private:
void GenerateStoreArrayLength(); void GenerateNegativeHolderLookup(Register holder_reg, Handle<Name> name,
void GenerateNegativeHolderLookup(MacroAssembler* masm,
Handle<JSObject> holder,
Register holder_reg,
Handle<Name> name,
Label* miss); Label* miss);
void GenerateStoreTransition(MacroAssembler* masm, void GenerateStoreTransition(Handle<Map> transition, Handle<Name> name,
LookupResult* lookup, Register receiver_reg, Register name_reg,
Handle<Map> transition, Register value_reg, Register scratch1,
Handle<Name> name, Register scratch2, Register scratch3,
Register receiver_reg, Label* miss_label, Label* slow);
Register name_reg,
Register value_reg, void GenerateStoreField(Handle<JSObject> object, LookupResult* lookup,
Register scratch1, Register receiver_reg, Register name_reg,
Register scratch2, Register value_reg, Register scratch1,
Register scratch3, Register scratch2, Label* miss_label);
Label* miss_label,
Label* slow);
void GenerateStoreField(MacroAssembler* masm,
Handle<JSObject> object,
LookupResult* lookup,
Register receiver_reg,
Register name_reg,
Register value_reg,
Register scratch1,
Register scratch2,
Label* miss_label);
static Builtins::Name SlowBuiltin(Code::Kind kind) { static Builtins::Name SlowBuiltin(Code::Kind kind) {
switch (kind) { switch (kind) {
......
...@@ -335,16 +335,6 @@ void PropertyHandlerCompiler::GenerateFastApiCall( ...@@ -335,16 +335,6 @@ void PropertyHandlerCompiler::GenerateFastApiCall(
} }
void NamedStoreHandlerCompiler::GenerateRestoreName(MacroAssembler* masm,
Label* label,
Handle<Name> name) {
if (!label->is_unused()) {
__ bind(label);
__ Move(this->name(), name);
}
}
void PropertyHandlerCompiler::GenerateCheckPropertyCell( void PropertyHandlerCompiler::GenerateCheckPropertyCell(
MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
Register scratch, Label* miss) { Register scratch, Label* miss) {
...@@ -358,15 +348,33 @@ void PropertyHandlerCompiler::GenerateCheckPropertyCell( ...@@ -358,15 +348,33 @@ void PropertyHandlerCompiler::GenerateCheckPropertyCell(
} }
void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
Handle<Code> code) {
__ jmp(code, RelocInfo::CODE_TARGET);
}
#undef __
#define __ ACCESS_MASM((masm()))
void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
Handle<Name> name) {
if (!label->is_unused()) {
__ bind(label);
__ Move(this->name(), name);
}
}
void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup( void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup(
MacroAssembler* masm, Handle<JSObject> holder, Register holder_reg, Register holder_reg, Handle<Name> name, Label* miss) {
Handle<Name> name, Label* miss) { if (holder()->IsJSGlobalObject()) {
if (holder->IsJSGlobalObject()) { GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(holder()),
GenerateCheckPropertyCell( name, scratch1(), miss);
masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); } else if (!holder()->HasFastProperties()) {
} else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1(),
GenerateDictionaryNegativeLookup( scratch2());
masm, miss, holder_reg, name, scratch1(), scratch2());
} }
} }
...@@ -374,10 +382,9 @@ void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup( ...@@ -374,10 +382,9 @@ void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup(
// Receiver_reg is preserved on jumps to miss_label, but may be destroyed if // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
// store is successful. // store is successful.
void NamedStoreHandlerCompiler::GenerateStoreTransition( void NamedStoreHandlerCompiler::GenerateStoreTransition(
MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition, Handle<Map> transition, Handle<Name> name, Register receiver_reg,
Handle<Name> name, Register receiver_reg, Register storage_reg, Register storage_reg, Register value_reg, Register scratch1,
Register value_reg, Register scratch1, Register scratch2, Register unused, Register scratch2, Register unused, Label* miss_label, Label* slow) {
Label* miss_label, Label* slow) {
int descriptor = transition->LastAdded(); int descriptor = transition->LastAdded();
DescriptorArray* descriptors = transition->instance_descriptors(); DescriptorArray* descriptors = transition->instance_descriptors();
PropertyDetails details = descriptors->GetDetails(descriptor); PropertyDetails details = descriptors->GetDetails(descriptor);
...@@ -385,7 +392,7 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -385,7 +392,7 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
ASSERT(!representation.IsNone()); ASSERT(!representation.IsNone());
if (details.type() == CONSTANT) { if (details.type() == CONSTANT) {
Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
__ Cmp(value_reg, constant); __ Cmp(value_reg, constant);
__ j(not_equal, miss_label); __ j(not_equal, miss_label);
} else if (representation.IsSmi()) { } else if (representation.IsSmi()) {
...@@ -417,8 +424,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -417,8 +424,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
__ jmp(&do_store); __ jmp(&do_store);
__ bind(&heap_number); __ bind(&heap_number);
__ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
miss_label, DONT_DO_SMI_CHECK); DONT_DO_SMI_CHECK);
__ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
__ bind(&do_store); __ bind(&do_store);
...@@ -440,9 +447,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -440,9 +447,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
__ PushReturnAddressFrom(scratch1); __ PushReturnAddressFrom(scratch1);
__ TailCallExternalReference( __ TailCallExternalReference(
ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
masm->isolate()), isolate()),
3, 3, 1);
1);
return; return;
} }
...@@ -525,12 +531,12 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( ...@@ -525,12 +531,12 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
// Both name_reg and receiver_reg are preserved on jumps to miss_label, // Both name_reg and receiver_reg are preserved on jumps to miss_label,
// but may be destroyed if store is successful. // but may be destroyed if store is successful.
void NamedStoreHandlerCompiler::GenerateStoreField( void NamedStoreHandlerCompiler::GenerateStoreField(
MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, Handle<JSObject> object, LookupResult* lookup, Register receiver_reg,
Register receiver_reg, Register name_reg, Register value_reg, Register name_reg, Register value_reg, Register scratch1, Register scratch2,
Register scratch1, Register scratch2, Label* miss_label) { Label* miss_label) {
// Stub never generated for non-global objects that require access // Stub never generated for objects that require access checks.
// checks. ASSERT(!object->IsAccessCheckNeeded());
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); ASSERT(!object->IsJSGlobalProxy());
FieldIndex index = lookup->GetFieldIndex(); FieldIndex index = lookup->GetFieldIndex();
...@@ -573,8 +579,8 @@ void NamedStoreHandlerCompiler::GenerateStoreField( ...@@ -573,8 +579,8 @@ void NamedStoreHandlerCompiler::GenerateStoreField(
__ jmp(&do_store); __ jmp(&do_store);
__ bind(&heap_number); __ bind(&heap_number);
__ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
miss_label, DONT_DO_SMI_CHECK); DONT_DO_SMI_CHECK);
__ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
__ bind(&do_store); __ bind(&do_store);
__ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0);
...@@ -621,16 +627,6 @@ void NamedStoreHandlerCompiler::GenerateStoreField( ...@@ -621,16 +627,6 @@ void NamedStoreHandlerCompiler::GenerateStoreField(
} }
void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
Handle<Code> code) {
__ jmp(code, RelocInfo::CODE_TARGET);
}
#undef __
#define __ ACCESS_MASM((masm()))
Register PropertyHandlerCompiler::CheckPrototypes( Register PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1, Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss, Register scratch2, Handle<Name> name, Label* miss,
...@@ -757,7 +753,7 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { ...@@ -757,7 +753,7 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
if (!miss->is_unused()) { if (!miss->is_unused()) {
Label success; Label success;
__ jmp(&success); __ jmp(&success);
GenerateRestoreName(masm(), miss, name); GenerateRestoreName(miss, name);
TailCallBuiltin(masm(), MissBuiltin(kind())); TailCallBuiltin(masm(), MissBuiltin(kind()));
__ bind(&success); __ bind(&success);
} }
...@@ -1052,20 +1048,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( ...@@ -1052,20 +1048,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
} }
void NamedStoreHandlerCompiler::GenerateStoreArrayLength() {
// Prepare tail call to StoreIC_ArrayLength.
__ PopReturnAddressTo(scratch1());
__ Push(receiver());
__ Push(value());
__ PushReturnAddressFrom(scratch1());
ExternalReference ref =
ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength),
masm()->isolate());
__ TailCallExternalReference(ref, 2, 1);
}
Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic( Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
MapHandleList* receiver_maps, CodeHandleList* handler_stubs, MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
MapHandleList* transitioned_maps) { MapHandleList* transitioned_maps) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment