[stubs] Port LoadFunctionPrototypeStub to CSA
BUG=v8:5269 Review-Url: https://codereview.chromium.org/2686723004 Cr-Commit-Position: refs/heads/master@{#43074}
This commit is contained in:
parent
a9b2edc1f2
commit
81239354c3
@ -1153,22 +1153,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
__ ldm(ia_w, sp, kCalleeSaved | pc.bit());
|
||||
}
|
||||
|
||||
|
||||
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
|
||||
Label miss;
|
||||
Register receiver = LoadDescriptor::ReceiverRegister();
|
||||
// Ensure that the vector and slot registers won't be clobbered before
|
||||
// calling the miss handler.
|
||||
DCHECK(!AreAliased(r4, r5, LoadWithVectorDescriptor::VectorRegister(),
|
||||
LoadWithVectorDescriptor::SlotRegister()));
|
||||
|
||||
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r4,
|
||||
r5, &miss);
|
||||
__ bind(&miss);
|
||||
PropertyAccessCompiler::TailCallBuiltin(
|
||||
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
|
||||
}
|
||||
|
||||
void RegExpExecStub::Generate(MacroAssembler* masm) {
|
||||
// Just jump directly to runtime if native RegExp is not selected at compile
|
||||
// time or if regexp entry in generated code is turned off runtime switch or
|
||||
|
@ -2423,33 +2423,6 @@ void MacroAssembler::GetMapConstructor(Register result, Register map,
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss) {
|
||||
// Get the prototype or initial map from the function.
|
||||
ldr(result,
|
||||
FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
|
||||
// If the prototype or initial map is the hole, don't return it and
|
||||
// simply miss the cache instead. This will allow us to allocate a
|
||||
// prototype object on-demand in the runtime system.
|
||||
LoadRoot(ip, Heap::kTheHoleValueRootIndex);
|
||||
cmp(result, ip);
|
||||
b(eq, miss);
|
||||
|
||||
// If the function does not have an initial map, we're done.
|
||||
Label done;
|
||||
CompareObjectType(result, scratch, scratch, MAP_TYPE);
|
||||
b(ne, &done);
|
||||
|
||||
// Get the prototype from the initial map.
|
||||
ldr(result, FieldMemOperand(result, Map::kPrototypeOffset));
|
||||
|
||||
// All done.
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::CallStub(CodeStub* stub,
|
||||
TypeFeedbackId ast_id,
|
||||
Condition cond) {
|
||||
|
@ -835,14 +835,6 @@ class MacroAssembler: public Assembler {
|
||||
void GetMapConstructor(Register result, Register map, Register temp,
|
||||
Register temp2);
|
||||
|
||||
// Try to get function prototype of a function and puts the value in
|
||||
// the result register. Checks that the function really is a
|
||||
// function and jumps to the miss label if the fast checks fail. The
|
||||
// function register will be untouched; the other registers may be
|
||||
// clobbered.
|
||||
void TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss);
|
||||
|
||||
// Compare object type for heap object. heap_object contains a non-Smi
|
||||
// whose object type should be compared with the given type. This both
|
||||
// sets the flags and leaves the object type in the type_reg register.
|
||||
|
@ -1268,23 +1268,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
|
||||
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
|
||||
Label miss;
|
||||
Register receiver = LoadDescriptor::ReceiverRegister();
|
||||
// Ensure that the vector and slot registers won't be clobbered before
|
||||
// calling the miss handler.
|
||||
DCHECK(!AreAliased(x10, x11, LoadWithVectorDescriptor::VectorRegister(),
|
||||
LoadWithVectorDescriptor::SlotRegister()));
|
||||
|
||||
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, x10,
|
||||
x11, &miss);
|
||||
|
||||
__ Bind(&miss);
|
||||
PropertyAccessCompiler::TailCallBuiltin(
|
||||
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
|
||||
}
|
||||
|
||||
void RegExpExecStub::Generate(MacroAssembler* masm) {
|
||||
#ifdef V8_INTERPRETED_REGEXP
|
||||
__ TailCallRuntime(Runtime::kRegExpExec);
|
||||
|
@ -3400,32 +3400,6 @@ void MacroAssembler::GetMapConstructor(Register result, Register map,
|
||||
Bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss) {
|
||||
DCHECK(!AreAliased(function, result, scratch));
|
||||
|
||||
// Get the prototype or initial map from the function.
|
||||
Ldr(result,
|
||||
FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
|
||||
// If the prototype or initial map is the hole, don't return it and simply
|
||||
// miss the cache instead. This will allow us to allocate a prototype object
|
||||
// on-demand in the runtime system.
|
||||
JumpIfRoot(result, Heap::kTheHoleValueRootIndex, miss);
|
||||
|
||||
// If the function does not have an initial map, we're done.
|
||||
Label done;
|
||||
JumpIfNotObjectType(result, scratch, scratch, MAP_TYPE, &done);
|
||||
|
||||
// Get the prototype from the initial map.
|
||||
Ldr(result, FieldMemOperand(result, Map::kPrototypeOffset));
|
||||
|
||||
// All done.
|
||||
Bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::PushRoot(Heap::RootListIndex index) {
|
||||
UseScratchRegisterScope temps(this);
|
||||
Register temp = temps.AcquireX();
|
||||
|
@ -1372,9 +1372,6 @@ class MacroAssembler : public Assembler {
|
||||
void GetMapConstructor(Register result, Register map, Register temp,
|
||||
Register temp2);
|
||||
|
||||
void TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss);
|
||||
|
||||
// Compare object type for heap object. heap_object contains a non-Smi
|
||||
// whose object type should be compared with the given type. This both
|
||||
// sets the flags and leaves the object type in the type_reg register.
|
||||
|
@ -125,6 +125,35 @@ void Builtins::Generate_LoadIC_Getter_ForDeopt(MacroAssembler* masm) {
|
||||
NamedLoadHandlerCompiler::GenerateLoadViaGetterForDeopt(masm);
|
||||
}
|
||||
|
||||
TF_BUILTIN(LoadIC_FunctionPrototype, CodeStubAssembler) {
|
||||
typedef LoadWithVectorDescriptor Descriptor;
|
||||
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
Node* name = Parameter(Descriptor::kName);
|
||||
Node* slot = Parameter(Descriptor::kSlot);
|
||||
Node* vector = Parameter(Descriptor::kVector);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
|
||||
Label miss(this);
|
||||
|
||||
Node* proto_or_map =
|
||||
LoadObjectField(receiver, JSFunction::kPrototypeOrInitialMapOffset);
|
||||
GotoIf(IsTheHole(proto_or_map), &miss);
|
||||
|
||||
Variable var_result(this, MachineRepresentation::kTagged, proto_or_map);
|
||||
Label done(this, &var_result);
|
||||
GotoUnless(IsMap(proto_or_map), &done);
|
||||
|
||||
var_result.Bind(LoadMapPrototype(proto_or_map));
|
||||
Goto(&done);
|
||||
|
||||
Bind(&done);
|
||||
Return(var_result.value());
|
||||
|
||||
Bind(&miss);
|
||||
TailCallRuntime(Runtime::kLoadIC_Miss, context, receiver, name, slot, vector);
|
||||
}
|
||||
|
||||
TF_BUILTIN(LoadIC_Miss, CodeStubAssembler) {
|
||||
typedef LoadWithVectorDescriptor Descriptor;
|
||||
|
||||
|
@ -243,6 +243,7 @@ class Isolate;
|
||||
TFS(LoadGlobalIC_Slow, HANDLER, Code::LOAD_GLOBAL_IC, LoadGlobalWithVector, \
|
||||
1) \
|
||||
TFS(LoadField, BUILTIN, kNoExtraICState, LoadField, 1) \
|
||||
TFS(LoadIC_FunctionPrototype, HANDLER, Code::LOAD_IC, LoadWithVector, 1) \
|
||||
ASH(LoadIC_Getter_ForDeopt, BUILTIN, kNoExtraICState) \
|
||||
TFS(LoadIC_Miss, BUILTIN, kNoExtraICState, LoadWithVector, 1) \
|
||||
TFS(LoadIC_Normal, HANDLER, Code::LOAD_IC, LoadWithVector, 1) \
|
||||
|
@ -38,7 +38,6 @@ class Node;
|
||||
V(CEntry) \
|
||||
V(CompareIC) \
|
||||
V(DoubleToI) \
|
||||
V(FunctionPrototype) \
|
||||
V(InternalArrayConstructor) \
|
||||
V(JSEntry) \
|
||||
V(MathPow) \
|
||||
@ -872,26 +871,6 @@ class CallICStub : public TurboFanCodeStub {
|
||||
DEFINE_TURBOFAN_CODE_STUB(CallIC, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
|
||||
// TODO(verwaest): Translate to hydrogen code stub.
|
||||
class FunctionPrototypeStub : public PlatformCodeStub {
|
||||
public:
|
||||
explicit FunctionPrototypeStub(Isolate* isolate)
|
||||
: PlatformCodeStub(isolate) {}
|
||||
|
||||
Code::Kind GetCodeKind() const override { return Code::HANDLER; }
|
||||
ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
|
||||
|
||||
// TODO(mvstanton): only the receiver register is accessed. When this is
|
||||
// translated to a hydrogen code stub, a new CallInterfaceDescriptor
|
||||
// should be created that just uses that register for more efficient code.
|
||||
CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
|
||||
return LoadWithVectorDescriptor(isolate());
|
||||
}
|
||||
|
||||
DEFINE_PLATFORM_CODE_STUB(FunctionPrototype, PlatformCodeStub);
|
||||
};
|
||||
|
||||
class KeyedLoadSloppyArgumentsStub : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit KeyedLoadSloppyArgumentsStub(Isolate* isolate)
|
||||
|
@ -462,23 +462,6 @@ void MathPowStub::Generate(MacroAssembler* masm) {
|
||||
__ ret(0);
|
||||
}
|
||||
|
||||
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
|
||||
Label miss;
|
||||
Register receiver = LoadDescriptor::ReceiverRegister();
|
||||
// With careful management, we won't have to save slot and vector on
|
||||
// the stack. Simply handle the possibly missing case first.
|
||||
// TODO(mvstanton): this code can be more efficient.
|
||||
__ cmp(FieldOperand(receiver, JSFunction::kPrototypeOrInitialMapOffset),
|
||||
Immediate(isolate()->factory()->the_hole_value()));
|
||||
__ j(equal, &miss);
|
||||
__ TryGetFunctionPrototype(receiver, eax, ebx, &miss);
|
||||
__ ret(0);
|
||||
|
||||
__ bind(&miss);
|
||||
PropertyAccessCompiler::TailCallBuiltin(
|
||||
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
|
||||
}
|
||||
|
||||
void RegExpExecStub::Generate(MacroAssembler* masm) {
|
||||
// Just jump directly to runtime if native RegExp is not selected at compile
|
||||
// time or if regexp entry in generated code is turned off runtime switch or
|
||||
|
@ -1690,32 +1690,6 @@ void MacroAssembler::GetMapConstructor(Register result, Register map,
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss) {
|
||||
// Get the prototype or initial map from the function.
|
||||
mov(result,
|
||||
FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
|
||||
// If the prototype or initial map is the hole, don't return it and
|
||||
// simply miss the cache instead. This will allow us to allocate a
|
||||
// prototype object on-demand in the runtime system.
|
||||
cmp(result, Immediate(isolate()->factory()->the_hole_value()));
|
||||
j(equal, miss);
|
||||
|
||||
// If the function does not have an initial map, we're done.
|
||||
Label done;
|
||||
CmpObjectType(result, MAP_TYPE, scratch);
|
||||
j(not_equal, &done, Label::kNear);
|
||||
|
||||
// Get the prototype from the initial map.
|
||||
mov(result, FieldOperand(result, Map::kPrototypeOffset));
|
||||
|
||||
// All done.
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) {
|
||||
DCHECK(AllowThisStubCall(stub)); // Calls are not allowed in some stubs.
|
||||
call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
|
||||
|
@ -648,14 +648,6 @@ class MacroAssembler: public Assembler {
|
||||
// |temp| holds |result|'s map when done.
|
||||
void GetMapConstructor(Register result, Register map, Register temp);
|
||||
|
||||
// Try to get function prototype of a function and puts the value in
|
||||
// the result register. Checks that the function really is a
|
||||
// function and jumps to the miss label if the fast checks fail. The
|
||||
// function register will be untouched; the other registers may be
|
||||
// clobbered.
|
||||
void TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Runtime calls
|
||||
|
||||
|
@ -181,15 +181,6 @@ void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
|
||||
__ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
|
||||
}
|
||||
|
||||
void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
|
||||
MacroAssembler* masm, Register receiver, Register scratch1,
|
||||
Register scratch2, Label* miss_label) {
|
||||
__ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
|
||||
__ mov(r0, scratch1);
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
|
||||
// Generate code to check that a global property cell is empty. Create
|
||||
// the property cell at compilation time if no cell exists for the
|
||||
// property.
|
||||
|
@ -83,19 +83,6 @@ void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
|
||||
__ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
|
||||
}
|
||||
|
||||
void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
|
||||
MacroAssembler* masm, Register receiver, Register scratch1,
|
||||
Register scratch2, Label* miss_label) {
|
||||
__ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
|
||||
// TryGetFunctionPrototype can't put the result directly in x0 because the
|
||||
// 3 inputs registers can't alias and we call this function from
|
||||
// LoadIC::GenerateFunctionPrototype, where receiver is x0. So we explicitly
|
||||
// move the result in x0.
|
||||
__ Mov(x0, scratch1);
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
|
||||
// Generate code to check that a global property cell is empty. Create
|
||||
// the property cell at compilation time if no cell exists for the
|
||||
// property.
|
||||
|
@ -158,12 +158,6 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
|
||||
no_reg);
|
||||
}
|
||||
|
||||
static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
|
||||
Register receiver,
|
||||
Register scratch1,
|
||||
Register scratch2,
|
||||
Label* miss_label);
|
||||
|
||||
// These constants describe the structure of the interceptor arguments on the
|
||||
// stack. The arguments are pushed by the (platform-specific)
|
||||
// PushInterceptorArguments and read by LoadPropertyWithInterceptorOnly and
|
||||
|
@ -122,15 +122,6 @@ void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
|
||||
__ DecrementCounter(counters->negative_lookups_miss(), 1);
|
||||
}
|
||||
|
||||
void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
|
||||
MacroAssembler* masm, Register receiver, Register scratch1,
|
||||
Register scratch2, Label* miss_label) {
|
||||
// TODO(mvstanton): This isn't used on ia32. Move all the other
|
||||
// platform implementations into a code stub so this method can be removed.
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
// Generate call to api function.
|
||||
// This function uses push() to generate smaller, faster code than
|
||||
// the version above. It is an optimization that should will be removed
|
||||
|
@ -1333,8 +1333,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
|
||||
->has_non_instance_prototype()) {
|
||||
Handle<Code> stub;
|
||||
TRACE_HANDLER_STATS(isolate(), LoadIC_FunctionPrototypeStub);
|
||||
FunctionPrototypeStub function_prototype_stub(isolate());
|
||||
return function_prototype_stub.GetCode();
|
||||
return isolate()->builtins()->LoadIC_FunctionPrototype();
|
||||
}
|
||||
|
||||
Handle<Map> map = receiver_map();
|
||||
|
@ -173,15 +173,6 @@ void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
|
||||
__ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
|
||||
}
|
||||
|
||||
void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
|
||||
MacroAssembler* masm, Register receiver, Register scratch1,
|
||||
Register scratch2, Label* miss_label) {
|
||||
__ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
|
||||
__ Ret(USE_DELAY_SLOT);
|
||||
__ mov(v0, scratch1);
|
||||
}
|
||||
|
||||
|
||||
// Generate code to check that a global property cell is empty. Create
|
||||
// the property cell at compilation time if no cell exists for the
|
||||
// property.
|
||||
|
@ -173,15 +173,6 @@ void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
|
||||
__ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
|
||||
}
|
||||
|
||||
void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
|
||||
MacroAssembler* masm, Register receiver, Register scratch1,
|
||||
Register scratch2, Label* miss_label) {
|
||||
__ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
|
||||
__ Ret(USE_DELAY_SLOT);
|
||||
__ mov(v0, scratch1);
|
||||
}
|
||||
|
||||
|
||||
// Generate code to check that a global property cell is empty. Create
|
||||
// the property cell at compilation time if no cell exists for the
|
||||
// property.
|
||||
|
@ -176,15 +176,6 @@ void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
|
||||
__ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
|
||||
}
|
||||
|
||||
void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
|
||||
MacroAssembler* masm, Register receiver, Register scratch1,
|
||||
Register scratch2, Label* miss_label) {
|
||||
__ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
|
||||
__ mr(r3, scratch1);
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
|
||||
// Generate code to check that a global property cell is empty. Create
|
||||
// the property cell at compilation time if no cell exists for the
|
||||
// property.
|
||||
|
@ -169,14 +169,6 @@ void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
|
||||
__ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
|
||||
}
|
||||
|
||||
void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
|
||||
MacroAssembler* masm, Register receiver, Register scratch1,
|
||||
Register scratch2, Label* miss_label) {
|
||||
__ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
|
||||
__ LoadRR(r2, scratch1);
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
// Generate code to check that a global property cell is empty. Create
|
||||
// the property cell at compilation time if no cell exists for the
|
||||
// property.
|
||||
|
@ -83,14 +83,6 @@ void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
|
||||
__ DecrementCounter(counters->negative_lookups_miss(), 1);
|
||||
}
|
||||
|
||||
void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
|
||||
MacroAssembler* masm, Register receiver, Register result, Register scratch,
|
||||
Label* miss_label) {
|
||||
__ TryGetFunctionPrototype(receiver, result, miss_label);
|
||||
if (!result.is(rax)) __ movp(rax, result);
|
||||
__ ret(0);
|
||||
}
|
||||
|
||||
static void CompileCallLoadPropertyWithInterceptor(
|
||||
MacroAssembler* masm, Register receiver, Register holder, Register name,
|
||||
Handle<JSObject> holder_obj, Runtime::FunctionId id) {
|
||||
|
@ -122,15 +122,6 @@ void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
|
||||
__ DecrementCounter(counters->negative_lookups_miss(), 1);
|
||||
}
|
||||
|
||||
void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
|
||||
MacroAssembler* masm, Register receiver, Register scratch1,
|
||||
Register scratch2, Label* miss_label) {
|
||||
// TODO(mvstanton): This isn't used on ia32. Move all the other
|
||||
// platform implementations into a code stub so this method can be removed.
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
// Generate call to api function.
|
||||
// This function uses push() to generate smaller, faster code than
|
||||
// the version above. It is an optimization that should will be removed
|
||||
|
@ -1277,21 +1277,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
__ Jump(ra);
|
||||
}
|
||||
|
||||
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
|
||||
Label miss;
|
||||
Register receiver = LoadDescriptor::ReceiverRegister();
|
||||
// Ensure that the vector and slot registers won't be clobbered before
|
||||
// calling the miss handler.
|
||||
DCHECK(!AreAliased(t0, t1, LoadWithVectorDescriptor::VectorRegister(),
|
||||
LoadWithVectorDescriptor::SlotRegister()));
|
||||
|
||||
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, t0,
|
||||
t1, &miss);
|
||||
__ bind(&miss);
|
||||
PropertyAccessCompiler::TailCallBuiltin(
|
||||
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
|
||||
}
|
||||
|
||||
void RegExpExecStub::Generate(MacroAssembler* masm) {
|
||||
// Just jump directly to runtime if native RegExp is not selected at compile
|
||||
// time or if regexp entry in generated code is turned off runtime switch or
|
||||
|
@ -4746,32 +4746,6 @@ void MacroAssembler::GetMapConstructor(Register result, Register map,
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss) {
|
||||
// Get the prototype or initial map from the function.
|
||||
lw(result,
|
||||
FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
|
||||
// If the prototype or initial map is the hole, don't return it and
|
||||
// simply miss the cache instead. This will allow us to allocate a
|
||||
// prototype object on-demand in the runtime system.
|
||||
LoadRoot(t8, Heap::kTheHoleValueRootIndex);
|
||||
Branch(miss, eq, result, Operand(t8));
|
||||
|
||||
// If the function does not have an initial map, we're done.
|
||||
Label done;
|
||||
GetObjectType(result, scratch, scratch);
|
||||
Branch(&done, ne, scratch, Operand(MAP_TYPE));
|
||||
|
||||
// Get the prototype from the initial map.
|
||||
lw(result, FieldMemOperand(result, Map::kPrototypeOffset));
|
||||
|
||||
// All done.
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::GetObjectType(Register object,
|
||||
Register map,
|
||||
Register type_reg) {
|
||||
|
@ -1110,14 +1110,6 @@ class MacroAssembler: public Assembler {
|
||||
void GetMapConstructor(Register result, Register map, Register temp,
|
||||
Register temp2);
|
||||
|
||||
// Try to get function prototype of a function and puts the value in
|
||||
// the result register. Checks that the function really is a
|
||||
// function and jumps to the miss label if the fast checks fail. The
|
||||
// function register will be untouched; the other registers may be
|
||||
// clobbered.
|
||||
void TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss);
|
||||
|
||||
void GetObjectType(Register function,
|
||||
Register map,
|
||||
Register type_reg);
|
||||
|
@ -1272,22 +1272,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
__ Jump(ra);
|
||||
}
|
||||
|
||||
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
|
||||
Label miss;
|
||||
Register receiver = LoadDescriptor::ReceiverRegister();
|
||||
// Ensure that the vector and slot registers won't be clobbered before
|
||||
// calling the miss handler.
|
||||
DCHECK(!AreAliased(a4, a5, LoadWithVectorDescriptor::VectorRegister(),
|
||||
LoadWithVectorDescriptor::SlotRegister()));
|
||||
|
||||
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, a4,
|
||||
a5, &miss);
|
||||
__ bind(&miss);
|
||||
PropertyAccessCompiler::TailCallBuiltin(
|
||||
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
|
||||
}
|
||||
|
||||
|
||||
void RegExpExecStub::Generate(MacroAssembler* masm) {
|
||||
// Just jump directly to runtime if native RegExp is not selected at compile
|
||||
// time or if regexp entry in generated code is turned off runtime switch or
|
||||
|
@ -4937,32 +4937,6 @@ void MacroAssembler::GetMapConstructor(Register result, Register map,
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss) {
|
||||
// Get the prototype or initial map from the function.
|
||||
ld(result,
|
||||
FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
|
||||
// If the prototype or initial map is the hole, don't return it and
|
||||
// simply miss the cache instead. This will allow us to allocate a
|
||||
// prototype object on-demand in the runtime system.
|
||||
LoadRoot(t8, Heap::kTheHoleValueRootIndex);
|
||||
Branch(miss, eq, result, Operand(t8));
|
||||
|
||||
// If the function does not have an initial map, we're done.
|
||||
Label done;
|
||||
GetObjectType(result, scratch, scratch);
|
||||
Branch(&done, ne, scratch, Operand(MAP_TYPE));
|
||||
|
||||
// Get the prototype from the initial map.
|
||||
ld(result, FieldMemOperand(result, Map::kPrototypeOffset));
|
||||
|
||||
// All done.
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::GetObjectType(Register object,
|
||||
Register map,
|
||||
Register type_reg) {
|
||||
|
@ -1164,14 +1164,6 @@ class MacroAssembler: public Assembler {
|
||||
void GetMapConstructor(Register result, Register map, Register temp,
|
||||
Register temp2);
|
||||
|
||||
// Try to get function prototype of a function and puts the value in
|
||||
// the result register. Checks that the function really is a
|
||||
// function and jumps to the miss label if the fast checks fail. The
|
||||
// function register will be untouched; the other registers may be
|
||||
// clobbered.
|
||||
void TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss);
|
||||
|
||||
void GetObjectType(Register function,
|
||||
Register map,
|
||||
Register type_reg);
|
||||
|
@ -1220,22 +1220,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
__ blr();
|
||||
}
|
||||
|
||||
|
||||
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
|
||||
Label miss;
|
||||
Register receiver = LoadDescriptor::ReceiverRegister();
|
||||
// Ensure that the vector and slot registers won't be clobbered before
|
||||
// calling the miss handler.
|
||||
DCHECK(!AreAliased(r7, r8, LoadWithVectorDescriptor::VectorRegister(),
|
||||
LoadWithVectorDescriptor::SlotRegister()));
|
||||
|
||||
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r7,
|
||||
r8, &miss);
|
||||
__ bind(&miss);
|
||||
PropertyAccessCompiler::TailCallBuiltin(
|
||||
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
|
||||
}
|
||||
|
||||
void RegExpExecStub::Generate(MacroAssembler* masm) {
|
||||
// Just jump directly to runtime if native RegExp is not selected at compile
|
||||
// time or if regexp entry in generated code is turned off runtime switch or
|
||||
|
@ -2147,33 +2147,6 @@ void MacroAssembler::GetMapConstructor(Register result, Register map,
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss) {
|
||||
// Get the prototype or initial map from the function.
|
||||
LoadP(result,
|
||||
FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
|
||||
// If the prototype or initial map is the hole, don't return it and
|
||||
// simply miss the cache instead. This will allow us to allocate a
|
||||
// prototype object on-demand in the runtime system.
|
||||
LoadRoot(r0, Heap::kTheHoleValueRootIndex);
|
||||
cmp(result, r0);
|
||||
beq(miss);
|
||||
|
||||
// If the function does not have an initial map, we're done.
|
||||
Label done;
|
||||
CompareObjectType(result, scratch, scratch, MAP_TYPE);
|
||||
bne(&done);
|
||||
|
||||
// Get the prototype from the initial map.
|
||||
LoadP(result, FieldMemOperand(result, Map::kPrototypeOffset));
|
||||
|
||||
// All done.
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id,
|
||||
Condition cond) {
|
||||
DCHECK(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.
|
||||
|
@ -752,14 +752,6 @@ class MacroAssembler : public Assembler {
|
||||
void GetMapConstructor(Register result, Register map, Register temp,
|
||||
Register temp2);
|
||||
|
||||
// Try to get function prototype of a function and puts the value in
|
||||
// the result register. Checks that the function really is a
|
||||
// function and jumps to the miss label if the fast checks fail. The
|
||||
// function register will be untouched; the other registers may be
|
||||
// clobbered.
|
||||
void TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss);
|
||||
|
||||
// Compare object type for heap object. heap_object contains a non-Smi
|
||||
// whose object type should be compared with the given type. This both
|
||||
// sets the flags and leaves the object type in the type_reg register.
|
||||
|
@ -1219,21 +1219,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
__ b(r14);
|
||||
}
|
||||
|
||||
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
|
||||
Label miss;
|
||||
Register receiver = LoadDescriptor::ReceiverRegister();
|
||||
// Ensure that the vector and slot registers won't be clobbered before
|
||||
// calling the miss handler.
|
||||
DCHECK(!AreAliased(r6, r7, LoadWithVectorDescriptor::VectorRegister(),
|
||||
LoadWithVectorDescriptor::SlotRegister()));
|
||||
|
||||
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r6,
|
||||
r7, &miss);
|
||||
__ bind(&miss);
|
||||
PropertyAccessCompiler::TailCallBuiltin(
|
||||
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
|
||||
}
|
||||
|
||||
void RegExpExecStub::Generate(MacroAssembler* masm) {
|
||||
// Just jump directly to runtime if native RegExp is not selected at compile
|
||||
// time or if regexp entry in generated code is turned off runtime switch or
|
||||
|
@ -1966,30 +1966,6 @@ void MacroAssembler::GetMapConstructor(Register result, Register map,
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss) {
|
||||
// Get the prototype or initial map from the function.
|
||||
LoadP(result,
|
||||
FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
|
||||
// If the prototype or initial map is the hole, don't return it and
|
||||
// simply miss the cache instead. This will allow us to allocate a
|
||||
// prototype object on-demand in the runtime system.
|
||||
CompareRoot(result, Heap::kTheHoleValueRootIndex);
|
||||
beq(miss);
|
||||
|
||||
// If the function does not have an initial map, we're done.
|
||||
Label done;
|
||||
CompareObjectType(result, scratch, scratch, MAP_TYPE);
|
||||
bne(&done, Label::kNear);
|
||||
|
||||
// Get the prototype from the initial map.
|
||||
LoadP(result, FieldMemOperand(result, Map::kPrototypeOffset));
|
||||
|
||||
// All done.
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id,
|
||||
Condition cond) {
|
||||
DCHECK(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.
|
||||
|
@ -1061,14 +1061,6 @@ class MacroAssembler : public Assembler {
|
||||
void GetMapConstructor(Register result, Register map, Register temp,
|
||||
Register temp2);
|
||||
|
||||
// Try to get function prototype of a function and puts the value in
|
||||
// the result register. Checks that the function really is a
|
||||
// function and jumps to the miss label if the fast checks fail. The
|
||||
// function register will be untouched; the other registers may be
|
||||
// clobbered.
|
||||
void TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss);
|
||||
|
||||
// Compare object type for heap object. heap_object contains a non-Smi
|
||||
// whose object type should be compared with the given type. This both
|
||||
// sets the flags and leaves the object type in the type_reg register.
|
||||
|
@ -344,22 +344,6 @@ void MathPowStub::Generate(MacroAssembler* masm) {
|
||||
__ ret(0);
|
||||
}
|
||||
|
||||
|
||||
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
|
||||
Label miss;
|
||||
Register receiver = LoadDescriptor::ReceiverRegister();
|
||||
// Ensure that the vector and slot registers won't be clobbered before
|
||||
// calling the miss handler.
|
||||
DCHECK(!AreAliased(r8, r9, LoadWithVectorDescriptor::VectorRegister(),
|
||||
LoadDescriptor::SlotRegister()));
|
||||
|
||||
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8,
|
||||
r9, &miss);
|
||||
__ bind(&miss);
|
||||
PropertyAccessCompiler::TailCallBuiltin(
|
||||
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
|
||||
}
|
||||
|
||||
void RegExpExecStub::Generate(MacroAssembler* masm) {
|
||||
// Just jump directly to runtime if native RegExp is not selected at compile
|
||||
// time or if regexp entry in generated code is turned off runtime switch or
|
||||
|
@ -4029,32 +4029,6 @@ void MacroAssembler::GetMapConstructor(Register result, Register map,
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
|
||||
Label* miss) {
|
||||
// Get the prototype or initial map from the function.
|
||||
movp(result,
|
||||
FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
|
||||
// If the prototype or initial map is the hole, don't return it and
|
||||
// simply miss the cache instead. This will allow us to allocate a
|
||||
// prototype object on-demand in the runtime system.
|
||||
CompareRoot(result, Heap::kTheHoleValueRootIndex);
|
||||
j(equal, miss);
|
||||
|
||||
// If the function does not have an initial map, we're done.
|
||||
Label done;
|
||||
CmpObjectType(result, MAP_TYPE, kScratchRegister);
|
||||
j(not_equal, &done, Label::kNear);
|
||||
|
||||
// Get the prototype from the initial map.
|
||||
movp(result, FieldOperand(result, Map::kPrototypeOffset));
|
||||
|
||||
// All done.
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::SetCounter(StatsCounter* counter, int value) {
|
||||
if (FLAG_native_code_counters && counter->Enabled()) {
|
||||
Operand counter_operand = ExternalOperand(ExternalReference(counter));
|
||||
|
@ -1353,13 +1353,6 @@ class MacroAssembler: public Assembler {
|
||||
// |temp| holds |result|'s map when done.
|
||||
void GetMapConstructor(Register result, Register map, Register temp);
|
||||
|
||||
// Try to get function prototype of a function and puts the value in
|
||||
// the result register. Checks that the function really is a
|
||||
// function and jumps to the miss label if the fast checks fail. The
|
||||
// function register will be untouched; the other register may be
|
||||
// clobbered.
|
||||
void TryGetFunctionPrototype(Register function, Register result, Label* miss);
|
||||
|
||||
// Find the function context up the context chain.
|
||||
void LoadContext(Register dst, int context_chain_length);
|
||||
|
||||
|
@ -281,24 +281,6 @@ void MathPowStub::Generate(MacroAssembler* masm) {
|
||||
__ ret(0);
|
||||
}
|
||||
|
||||
|
||||
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
|
||||
Label miss;
|
||||
Register receiver = LoadDescriptor::ReceiverRegister();
|
||||
// With careful management, we won't have to save slot and vector on
|
||||
// the stack. Simply handle the possibly missing case first.
|
||||
// TODO(mvstanton): this code can be more efficient.
|
||||
__ cmp(FieldOperand(receiver, JSFunction::kPrototypeOrInitialMapOffset),
|
||||
Immediate(isolate()->factory()->the_hole_value()));
|
||||
__ j(equal, &miss);
|
||||
__ TryGetFunctionPrototype(receiver, eax, ebx, &miss);
|
||||
__ ret(0);
|
||||
|
||||
__ bind(&miss);
|
||||
PropertyAccessCompiler::TailCallBuiltin(
|
||||
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
|
||||
}
|
||||
|
||||
void RegExpExecStub::Generate(MacroAssembler* masm) {
|
||||
// Just jump directly to runtime if native RegExp is not selected at compile
|
||||
// time or if regexp entry in generated code is turned off runtime switch or
|
||||
|
@ -1623,32 +1623,6 @@ void MacroAssembler::GetMapConstructor(Register result, Register map,
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss) {
|
||||
// Get the prototype or initial map from the function.
|
||||
mov(result,
|
||||
FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
|
||||
// If the prototype or initial map is the hole, don't return it and
|
||||
// simply miss the cache instead. This will allow us to allocate a
|
||||
// prototype object on-demand in the runtime system.
|
||||
cmp(result, Immediate(isolate()->factory()->the_hole_value()));
|
||||
j(equal, miss);
|
||||
|
||||
// If the function does not have an initial map, we're done.
|
||||
Label done;
|
||||
CmpObjectType(result, MAP_TYPE, scratch);
|
||||
j(not_equal, &done, Label::kNear);
|
||||
|
||||
// Get the prototype from the initial map.
|
||||
mov(result, FieldOperand(result, Map::kPrototypeOffset));
|
||||
|
||||
// All done.
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) {
|
||||
DCHECK(AllowThisStubCall(stub)); // Calls are not allowed in some stubs.
|
||||
call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
|
||||
|
@ -637,14 +637,6 @@ class MacroAssembler: public Assembler {
|
||||
// |temp| holds |result|'s map when done.
|
||||
void GetMapConstructor(Register result, Register map, Register temp);
|
||||
|
||||
// Try to get function prototype of a function and puts the value in
|
||||
// the result register. Checks that the function really is a
|
||||
// function and jumps to the miss label if the fast checks fail. The
|
||||
// function register will be untouched; the other registers may be
|
||||
// clobbered.
|
||||
void TryGetFunctionPrototype(Register function, Register result,
|
||||
Register scratch, Label* miss);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Runtime calls
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user