Remove in-loop tracking for call ICs.
We passed this flag around in a lot of places and had differenc call ICs based on it, but never did any real specialization based on its value. R=fschneider@chromium.org BUG= TEST= Review URL: http://codereview.chromium.org/7869009 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9260 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
aa00dbdc40
commit
40cd59f238
@ -2028,9 +2028,8 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
|
||||
// Record source position for debugger.
|
||||
SetSourcePosition(expr->position());
|
||||
// Call the IC initialization code.
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode);
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
|
||||
__ Call(ic, mode, expr->id());
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
@ -2061,9 +2060,8 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
|
||||
// Record source position for debugger.
|
||||
SetSourcePosition(expr->position());
|
||||
// Call the IC initialization code.
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop);
|
||||
isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
|
||||
__ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key.
|
||||
__ Call(ic, RelocInfo::CODE_TARGET, expr->id());
|
||||
RecordJSReturnSite(expr);
|
||||
@ -2084,8 +2082,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
|
||||
}
|
||||
// Record source position for debugger.
|
||||
SetSourcePosition(expr->position());
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
CallFunctionStub stub(arg_count, in_loop, flags);
|
||||
CallFunctionStub stub(arg_count, flags);
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
@ -2184,8 +2181,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
|
||||
// Record source position for debugger.
|
||||
SetSourcePosition(expr->position());
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT);
|
||||
CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT);
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
@ -3553,9 +3549,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ mov(r2, Operand(expr->name()));
|
||||
RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arg_count,
|
||||
NOT_IN_LOOP,
|
||||
mode);
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
|
||||
__ Call(ic, mode, expr->id());
|
||||
// Restore context register.
|
||||
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
|
@ -393,7 +393,6 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
|
||||
|
||||
// Probe the stub cache.
|
||||
Code::Flags flags = Code::ComputeFlags(kind,
|
||||
NOT_IN_LOOP,
|
||||
MONOMORPHIC,
|
||||
extra_ic_state,
|
||||
NORMAL,
|
||||
@ -734,9 +733,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
|
||||
// -----------------------------------
|
||||
|
||||
// Probe the stub cache.
|
||||
Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC,
|
||||
NOT_IN_LOOP,
|
||||
MONOMORPHIC);
|
||||
Code::Flags flags =
|
||||
Code::ComputeFlags(Code::LOAD_IC, MONOMORPHIC);
|
||||
Isolate::Current()->stub_cache()->GenerateProbe(
|
||||
masm, flags, r0, r2, r3, r4, r5);
|
||||
|
||||
@ -1380,10 +1378,8 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
|
||||
// -----------------------------------
|
||||
|
||||
// Get the receiver from the stack and probe the stub cache.
|
||||
Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
|
||||
NOT_IN_LOOP,
|
||||
MONOMORPHIC,
|
||||
strict_mode);
|
||||
Code::Flags flags =
|
||||
Code::ComputeFlags(Code::STORE_IC, MONOMORPHIC, strict_mode);
|
||||
|
||||
Isolate::Current()->stub_cache()->GenerateProbe(
|
||||
masm, flags, r1, r2, r3, r4, r5);
|
||||
|
@ -3178,7 +3178,7 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
|
||||
|
||||
int arity = instr->arity();
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeKeyedCallInitialize(arity, NOT_IN_LOOP);
|
||||
isolate()->stub_cache()->ComputeKeyedCallInitialize(arity);
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
}
|
||||
@ -3190,7 +3190,7 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) {
|
||||
int arity = instr->arity();
|
||||
RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode);
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
|
||||
__ mov(r2, Operand(instr->name()));
|
||||
CallCode(ic, mode, instr);
|
||||
// Restore context register.
|
||||
@ -3202,7 +3202,7 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
|
||||
ASSERT(ToRegister(instr->result()).is(r0));
|
||||
|
||||
int arity = instr->arity();
|
||||
CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT);
|
||||
CallFunctionStub stub(arity, RECEIVER_MIGHT_BE_IMPLICIT);
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
__ Drop(1);
|
||||
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
@ -3215,7 +3215,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
|
||||
int arity = instr->arity();
|
||||
RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode);
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
|
||||
__ mov(r2, Operand(instr->name()));
|
||||
CallCode(ic, mode, instr);
|
||||
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
|
@ -1583,7 +1583,6 @@ void Builtins::InitBuiltinFunctionTable() {
|
||||
functions->s_name = #aname; \
|
||||
functions->name = k##aname; \
|
||||
functions->flags = Code::ComputeFlags(Code::kind, \
|
||||
NOT_IN_LOOP, \
|
||||
state, \
|
||||
extra); \
|
||||
functions->extra_args = NO_EXTRA_ARGUMENTS; \
|
||||
|
@ -114,7 +114,6 @@ Handle<Code> CodeStub::GetCode() {
|
||||
// Copy the generated code into a heap object.
|
||||
Code::Flags flags = Code::ComputeFlags(
|
||||
static_cast<Code::Kind>(GetCodeKind()),
|
||||
InLoop(),
|
||||
GetICState());
|
||||
Handle<Code> new_object = factory->NewCode(
|
||||
desc, flags, masm.CodeObject(), NeedsImmovableCode());
|
||||
@ -152,7 +151,6 @@ MaybeObject* CodeStub::TryGetCode() {
|
||||
// Try to copy the generated code into a heap object.
|
||||
Code::Flags flags = Code::ComputeFlags(
|
||||
static_cast<Code::Kind>(GetCodeKind()),
|
||||
InLoop(),
|
||||
GetICState());
|
||||
Object* new_object;
|
||||
{ MaybeObject* maybe_new_object =
|
||||
@ -316,17 +314,12 @@ void ArgumentsAccessStub::PrintName(StringStream* stream) {
|
||||
|
||||
|
||||
void CallFunctionStub::PrintName(StringStream* stream) {
|
||||
const char* in_loop_name = NULL; // Make g++ happy.
|
||||
switch (in_loop_) {
|
||||
case NOT_IN_LOOP: in_loop_name = ""; break;
|
||||
case IN_LOOP: in_loop_name = "_InLoop"; break;
|
||||
}
|
||||
const char* flags_name = NULL; // Make g++ happy.
|
||||
switch (flags_) {
|
||||
case NO_CALL_FUNCTION_FLAGS: flags_name = ""; break;
|
||||
case RECEIVER_MIGHT_BE_IMPLICIT: flags_name = "_Implicit"; break;
|
||||
}
|
||||
stream->Add("CallFunctionStub_Args%d%s%s", argc_, in_loop_name, flags_name);
|
||||
stream->Add("CallFunctionStub_Args%d%s", argc_, flags_name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -168,10 +168,6 @@ class CodeStub BASE_EMBEDDED {
|
||||
virtual Major MajorKey() = 0;
|
||||
virtual int MinorKey() = 0;
|
||||
|
||||
// The CallFunctionStub needs to override this so it can encode whether a
|
||||
// lazily generated function should be fully optimized or not.
|
||||
virtual InLoopFlag InLoop() { return NOT_IN_LOOP; }
|
||||
|
||||
// BinaryOpStub needs to override this.
|
||||
virtual int GetCodeKind();
|
||||
|
||||
@ -646,8 +642,8 @@ class RegExpConstructResultStub: public CodeStub {
|
||||
|
||||
class CallFunctionStub: public CodeStub {
|
||||
public:
|
||||
CallFunctionStub(int argc, InLoopFlag in_loop, CallFunctionFlags flags)
|
||||
: argc_(argc), in_loop_(in_loop), flags_(flags) { }
|
||||
CallFunctionStub(int argc, CallFunctionFlags flags)
|
||||
: argc_(argc), flags_(flags) { }
|
||||
|
||||
void Generate(MacroAssembler* masm);
|
||||
|
||||
@ -657,26 +653,20 @@ class CallFunctionStub: public CodeStub {
|
||||
|
||||
private:
|
||||
int argc_;
|
||||
InLoopFlag in_loop_;
|
||||
CallFunctionFlags flags_;
|
||||
|
||||
virtual void PrintName(StringStream* stream);
|
||||
|
||||
// Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
|
||||
class InLoopBits: public BitField<InLoopFlag, 0, 1> {};
|
||||
class FlagBits: public BitField<CallFunctionFlags, 1, 1> {};
|
||||
class ArgcBits: public BitField<int, 2, 32 - 2> {};
|
||||
class FlagBits: public BitField<CallFunctionFlags, 0, 1> {};
|
||||
class ArgcBits: public BitField<unsigned, 1, 32 - 1> {};
|
||||
|
||||
Major MajorKey() { return CallFunction; }
|
||||
int MinorKey() {
|
||||
// Encode the parameters in a unique 32 bit value.
|
||||
return InLoopBits::encode(in_loop_)
|
||||
| FlagBits::encode(flags_)
|
||||
| ArgcBits::encode(argc_);
|
||||
return FlagBits::encode(flags_) | ArgcBits::encode(argc_);
|
||||
}
|
||||
|
||||
InLoopFlag InLoop() { return in_loop_; }
|
||||
|
||||
bool ReceiverMightBeImplicit() {
|
||||
return (flags_ & RECEIVER_MIGHT_BE_IMPLICIT) != 0;
|
||||
}
|
||||
|
@ -247,9 +247,6 @@ static int DecodeIt(FILE* f,
|
||||
PropertyType type = code->type();
|
||||
out.AddFormatted(", %s", Code::PropertyType2String(type));
|
||||
}
|
||||
if (code->ic_in_loop() == IN_LOOP) {
|
||||
out.AddFormatted(", in_loop");
|
||||
}
|
||||
if (kind == Code::CALL_IC || kind == Code::KEYED_CALL_IC) {
|
||||
out.AddFormatted(", argc = %d", code->arguments_count());
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
|
||||
}
|
||||
unsigned table_offset = cgen.EmitStackCheckTable();
|
||||
|
||||
Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP);
|
||||
Code::Flags flags = Code::ComputeFlags(Code::FUNCTION);
|
||||
Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
|
||||
code->set_optimizable(info->IsOptimizable());
|
||||
cgen.PopulateDeoptimizationData(code);
|
||||
|
@ -921,16 +921,13 @@ bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
|
||||
}
|
||||
|
||||
|
||||
static bool CompileLazyFunction(Handle<JSFunction> function,
|
||||
ClearExceptionFlag flag,
|
||||
InLoopFlag in_loop_flag) {
|
||||
bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag) {
|
||||
bool result = true;
|
||||
if (function->shared()->is_compiled()) {
|
||||
function->ReplaceCode(function->shared()->code());
|
||||
function->shared()->set_code_age(0);
|
||||
} else {
|
||||
CompilationInfo info(function);
|
||||
if (in_loop_flag == IN_LOOP) info.MarkAsInLoop();
|
||||
result = CompileLazyHelper(&info, flag);
|
||||
ASSERT(!result || function->is_compiled());
|
||||
}
|
||||
@ -938,18 +935,6 @@ static bool CompileLazyFunction(Handle<JSFunction> function,
|
||||
}
|
||||
|
||||
|
||||
bool CompileLazy(Handle<JSFunction> function,
|
||||
ClearExceptionFlag flag) {
|
||||
return CompileLazyFunction(function, flag, NOT_IN_LOOP);
|
||||
}
|
||||
|
||||
|
||||
bool CompileLazyInLoop(Handle<JSFunction> function,
|
||||
ClearExceptionFlag flag) {
|
||||
return CompileLazyFunction(function, flag, IN_LOOP);
|
||||
}
|
||||
|
||||
|
||||
bool CompileOptimized(Handle<JSFunction> function,
|
||||
int osr_ast_id,
|
||||
ClearExceptionFlag flag) {
|
||||
|
@ -363,8 +363,6 @@ bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
|
||||
|
||||
bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag);
|
||||
|
||||
bool CompileLazyInLoop(Handle<JSFunction> function, ClearExceptionFlag flag);
|
||||
|
||||
bool CompileOptimized(Handle<JSFunction> function,
|
||||
int osr_ast_id,
|
||||
ClearExceptionFlag flag);
|
||||
|
@ -649,8 +649,7 @@ Handle<Code> HGraph::Compile(CompilationInfo* info) {
|
||||
PrintF("Crankshaft Compiler - ");
|
||||
}
|
||||
CodeGenerator::MakeCodePrologue(info);
|
||||
Code::Flags flags =
|
||||
Code::ComputeFlags(Code::OPTIMIZED_FUNCTION, NOT_IN_LOOP);
|
||||
Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION);
|
||||
Handle<Code> code =
|
||||
CodeGenerator::MakeCodeEpilogue(&assembler, flags, info);
|
||||
generator.FinishCode(code);
|
||||
|
@ -2013,9 +2013,8 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
|
||||
}
|
||||
// Record source position of the IC call.
|
||||
SetSourcePosition(expr->position());
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode);
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
|
||||
__ call(ic, mode, expr->id());
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
@ -2047,9 +2046,8 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
|
||||
}
|
||||
// Record source position of the IC call.
|
||||
SetSourcePosition(expr->position());
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(
|
||||
arg_count, in_loop);
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
|
||||
__ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
|
||||
__ call(ic, RelocInfo::CODE_TARGET, expr->id());
|
||||
RecordJSReturnSite(expr);
|
||||
@ -2071,8 +2069,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
|
||||
}
|
||||
// Record source position for debugger.
|
||||
SetSourcePosition(expr->position());
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
CallFunctionStub stub(arg_count, in_loop, flags);
|
||||
CallFunctionStub stub(arg_count, flags);
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
@ -2166,8 +2163,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
}
|
||||
// Record source position for debugger.
|
||||
SetSourcePosition(expr->position());
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT);
|
||||
CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT);
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
@ -3582,10 +3578,9 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
if (expr->is_jsruntime()) {
|
||||
// Call the JS runtime function via a call IC.
|
||||
__ Set(ecx, Immediate(expr->name()));
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
|
||||
Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
|
||||
arg_count, in_loop, mode);
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
|
||||
__ call(ic, mode, expr->id());
|
||||
// Restore context register.
|
||||
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
||||
|
@ -832,7 +832,6 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
|
||||
|
||||
// Probe the stub cache.
|
||||
Code::Flags flags = Code::ComputeFlags(kind,
|
||||
NOT_IN_LOOP,
|
||||
MONOMORPHIC,
|
||||
extra_ic_state,
|
||||
NORMAL,
|
||||
@ -1237,9 +1236,7 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
|
||||
// -----------------------------------
|
||||
|
||||
// Probe the stub cache.
|
||||
Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC,
|
||||
NOT_IN_LOOP,
|
||||
MONOMORPHIC);
|
||||
Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, MONOMORPHIC);
|
||||
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, eax, ecx, ebx,
|
||||
edx);
|
||||
|
||||
@ -1339,10 +1336,8 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
|
||||
// -- esp[0] : return address
|
||||
// -----------------------------------
|
||||
|
||||
Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
|
||||
NOT_IN_LOOP,
|
||||
MONOMORPHIC,
|
||||
strict_mode);
|
||||
Code::Flags flags =
|
||||
Code::ComputeFlags(Code::STORE_IC, MONOMORPHIC, strict_mode);
|
||||
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx,
|
||||
no_reg);
|
||||
|
||||
|
@ -2981,8 +2981,8 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
|
||||
ASSERT(ToRegister(instr->result()).is(eax));
|
||||
|
||||
int arity = instr->arity();
|
||||
Handle<Code> ic = isolate()->stub_cache()->
|
||||
ComputeKeyedCallInitialize(arity, NOT_IN_LOOP);
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeKeyedCallInitialize(arity);
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
||||
@ -2994,7 +2994,7 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) {
|
||||
int arity = instr->arity();
|
||||
RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode);
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
|
||||
__ mov(ecx, instr->name());
|
||||
CallCode(ic, mode, instr);
|
||||
}
|
||||
@ -3005,7 +3005,7 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
|
||||
ASSERT(ToRegister(instr->result()).is(eax));
|
||||
|
||||
int arity = instr->arity();
|
||||
CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT);
|
||||
CallFunctionStub stub(arity, RECEIVER_MIGHT_BE_IMPLICIT);
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
__ Drop(1);
|
||||
}
|
||||
@ -3018,7 +3018,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
|
||||
int arity = instr->arity();
|
||||
RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode);
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
|
||||
__ mov(ecx, instr->name());
|
||||
CallCode(ic, mode, instr);
|
||||
}
|
||||
|
48
src/ic.cc
48
src/ic.cc
@ -61,8 +61,7 @@ static char TransitionMarkFromState(IC::State state) {
|
||||
void IC::TraceIC(const char* type,
|
||||
Handle<Object> name,
|
||||
State old_state,
|
||||
Code* new_target,
|
||||
const char* extra_info) {
|
||||
Code* new_target) {
|
||||
if (FLAG_trace_ic) {
|
||||
State new_state = StateFrom(new_target,
|
||||
HEAP->undefined_value(),
|
||||
@ -94,10 +93,9 @@ void IC::TraceIC(const char* type,
|
||||
} else {
|
||||
PrintF("<unknown>");
|
||||
}
|
||||
PrintF(" (%c->%c)%s",
|
||||
PrintF(" (%c->%c)",
|
||||
TransitionMarkFromState(old_state),
|
||||
TransitionMarkFromState(new_state),
|
||||
extra_info);
|
||||
TransitionMarkFromState(new_state));
|
||||
name->Print();
|
||||
PrintF("]\n");
|
||||
}
|
||||
@ -326,7 +324,6 @@ void CallICBase::Clear(Address address, Code* target) {
|
||||
Code* code =
|
||||
Isolate::Current()->stub_cache()->FindCallInitialize(
|
||||
target->arguments_count(),
|
||||
target->ic_in_loop(),
|
||||
contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET,
|
||||
target->kind());
|
||||
SetTargetAtAddress(address, code);
|
||||
@ -604,13 +601,11 @@ MaybeObject* CallICBase::ComputeMonomorphicStub(
|
||||
Handle<Object> object,
|
||||
Handle<String> name) {
|
||||
int argc = target()->arguments_count();
|
||||
InLoopFlag in_loop = target()->ic_in_loop();
|
||||
MaybeObject* maybe_code = NULL;
|
||||
switch (lookup->type()) {
|
||||
case FIELD: {
|
||||
int index = lookup->GetFieldIndex();
|
||||
maybe_code = isolate()->stub_cache()->ComputeCallField(argc,
|
||||
in_loop,
|
||||
kind_,
|
||||
extra_ic_state,
|
||||
*name,
|
||||
@ -626,7 +621,6 @@ MaybeObject* CallICBase::ComputeMonomorphicStub(
|
||||
JSFunction* function = lookup->GetConstantFunction();
|
||||
maybe_code =
|
||||
isolate()->stub_cache()->ComputeCallConstant(argc,
|
||||
in_loop,
|
||||
kind_,
|
||||
extra_ic_state,
|
||||
*name,
|
||||
@ -646,7 +640,6 @@ MaybeObject* CallICBase::ComputeMonomorphicStub(
|
||||
if (!cell->value()->IsJSFunction()) return NULL;
|
||||
JSFunction* function = JSFunction::cast(cell->value());
|
||||
maybe_code = isolate()->stub_cache()->ComputeCallGlobal(argc,
|
||||
in_loop,
|
||||
kind_,
|
||||
extra_ic_state,
|
||||
*name,
|
||||
@ -661,7 +654,6 @@ MaybeObject* CallICBase::ComputeMonomorphicStub(
|
||||
// applicable.
|
||||
if (lookup->holder() != *receiver) return NULL;
|
||||
maybe_code = isolate()->stub_cache()->ComputeCallNormal(argc,
|
||||
in_loop,
|
||||
kind_,
|
||||
extra_ic_state,
|
||||
*name,
|
||||
@ -706,7 +698,6 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
|
||||
|
||||
// Compute the number of arguments.
|
||||
int argc = target()->arguments_count();
|
||||
InLoopFlag in_loop = target()->ic_in_loop();
|
||||
MaybeObject* maybe_code = NULL;
|
||||
bool had_proto_failure = false;
|
||||
if (state == UNINITIALIZED) {
|
||||
@ -715,7 +706,6 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
|
||||
// setting the monomorphic state.
|
||||
maybe_code =
|
||||
isolate()->stub_cache()->ComputeCallPreMonomorphic(argc,
|
||||
in_loop,
|
||||
kind_,
|
||||
extra_ic_state);
|
||||
} else if (state == MONOMORPHIC) {
|
||||
@ -739,7 +729,6 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
|
||||
} else {
|
||||
maybe_code =
|
||||
isolate()->stub_cache()->ComputeCallMegamorphic(argc,
|
||||
in_loop,
|
||||
kind_,
|
||||
extra_ic_state);
|
||||
}
|
||||
@ -776,7 +765,7 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
|
||||
#ifdef DEBUG
|
||||
if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE;
|
||||
TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC",
|
||||
name, state, target(), in_loop ? " (in-loop)" : "");
|
||||
name, state, target());
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -797,31 +786,28 @@ MaybeObject* KeyedCallIC::LoadFunction(State state,
|
||||
|
||||
if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) {
|
||||
int argc = target()->arguments_count();
|
||||
InLoopFlag in_loop = target()->ic_in_loop();
|
||||
Heap* heap = Handle<HeapObject>::cast(object)->GetHeap();
|
||||
Map* map = heap->non_strict_arguments_elements_map();
|
||||
if (object->IsJSObject() &&
|
||||
Handle<JSObject>::cast(object)->elements()->map() == map) {
|
||||
MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallArguments(
|
||||
argc, in_loop, Code::KEYED_CALL_IC);
|
||||
argc, Code::KEYED_CALL_IC);
|
||||
Object* code;
|
||||
if (maybe_code->ToObject(&code)) {
|
||||
set_target(Code::cast(code));
|
||||
#ifdef DEBUG
|
||||
TraceIC(
|
||||
"KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : "");
|
||||
TraceIC("KeyedCallIC", key, state, target());
|
||||
#endif
|
||||
}
|
||||
} else if (FLAG_use_ic && state != MEGAMORPHIC &&
|
||||
!object->IsAccessCheckNeeded()) {
|
||||
MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic(
|
||||
argc, in_loop, Code::KEYED_CALL_IC, Code::kNoExtraICState);
|
||||
argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
|
||||
Object* code;
|
||||
if (maybe_code->ToObject(&code)) {
|
||||
set_target(Code::cast(code));
|
||||
#ifdef DEBUG
|
||||
TraceIC(
|
||||
"KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : "");
|
||||
TraceIC("KeyedCallIC", key, state, target());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -1650,7 +1636,6 @@ MaybeObject* KeyedIC::ComputeStub(JSObject* receiver,
|
||||
|
||||
PolymorphicCodeCache* cache = isolate()->heap()->polymorphic_code_cache();
|
||||
Code::Flags flags = Code::ComputeFlags(this->kind(),
|
||||
NOT_IN_LOOP,
|
||||
MEGAMORPHIC,
|
||||
strict_mode);
|
||||
Object* maybe_cached_stub = cache->Lookup(&target_receiver_maps, flags);
|
||||
@ -1905,16 +1890,11 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
|
||||
//
|
||||
|
||||
static JSFunction* CompileFunction(Isolate* isolate,
|
||||
JSFunction* function,
|
||||
InLoopFlag in_loop) {
|
||||
JSFunction* function) {
|
||||
// Compile now with optimization.
|
||||
HandleScope scope(isolate);
|
||||
Handle<JSFunction> function_handle(function, isolate);
|
||||
if (in_loop == IN_LOOP) {
|
||||
CompileLazyInLoop(function_handle, CLEAR_EXCEPTION);
|
||||
} else {
|
||||
CompileLazy(function_handle, CLEAR_EXCEPTION);
|
||||
}
|
||||
CompileLazy(function_handle, CLEAR_EXCEPTION);
|
||||
return *function_handle;
|
||||
}
|
||||
|
||||
@ -1943,9 +1923,7 @@ RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
|
||||
if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) {
|
||||
return result;
|
||||
}
|
||||
return CompileFunction(isolate,
|
||||
JSFunction::cast(result),
|
||||
ic.target()->ic_in_loop());
|
||||
return CompileFunction(isolate, JSFunction::cast(result));
|
||||
}
|
||||
|
||||
|
||||
@ -1964,9 +1942,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) {
|
||||
if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) {
|
||||
return result;
|
||||
}
|
||||
return CompileFunction(isolate,
|
||||
JSFunction::cast(result),
|
||||
ic.target()->ic_in_loop());
|
||||
return CompileFunction(isolate, JSFunction::cast(result));
|
||||
}
|
||||
|
||||
|
||||
|
3
src/ic.h
3
src/ic.h
@ -149,8 +149,7 @@ class IC {
|
||||
void TraceIC(const char* type,
|
||||
Handle<Object> name,
|
||||
State old_state,
|
||||
Code* new_target,
|
||||
const char* extra_info = "");
|
||||
Code* new_target);
|
||||
#endif
|
||||
|
||||
Failure* TypeError(const char* type,
|
||||
|
@ -2881,11 +2881,6 @@ Code::Kind Code::kind() {
|
||||
}
|
||||
|
||||
|
||||
InLoopFlag Code::ic_in_loop() {
|
||||
return ExtractICInLoopFromFlags(flags());
|
||||
}
|
||||
|
||||
|
||||
InlineCacheState Code::ic_state() {
|
||||
InlineCacheState result = ExtractICStateFromFlags(flags());
|
||||
// Only allow uninitialized or debugger states for non-IC code
|
||||
@ -3109,7 +3104,6 @@ bool Code::is_inline_cache_stub() {
|
||||
|
||||
|
||||
Code::Flags Code::ComputeFlags(Kind kind,
|
||||
InLoopFlag in_loop,
|
||||
InlineCacheState ic_state,
|
||||
ExtraICState extra_ic_state,
|
||||
PropertyType type,
|
||||
@ -3118,16 +3112,15 @@ Code::Flags Code::ComputeFlags(Kind kind,
|
||||
// Extra IC state is only allowed for call IC stubs or for store IC
|
||||
// stubs.
|
||||
ASSERT(extra_ic_state == kNoExtraICState ||
|
||||
(kind == CALL_IC) ||
|
||||
(kind == STORE_IC) ||
|
||||
(kind == KEYED_STORE_IC));
|
||||
kind == CALL_IC ||
|
||||
kind == STORE_IC ||
|
||||
kind == KEYED_STORE_IC);
|
||||
// Compute the bit mask.
|
||||
int bits = KindField::encode(kind)
|
||||
| ICInLoopField::encode(in_loop)
|
||||
| ICStateField::encode(ic_state)
|
||||
| TypeField::encode(type)
|
||||
| ExtraICStateField::encode(extra_ic_state)
|
||||
| (argc << kFlagsArgumentsCountShift)
|
||||
| (argc << kArgumentsCountShift)
|
||||
| CacheHolderField::encode(holder);
|
||||
return static_cast<Flags>(bits);
|
||||
}
|
||||
@ -3137,10 +3130,8 @@ Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
|
||||
PropertyType type,
|
||||
ExtraICState extra_ic_state,
|
||||
InlineCacheHolderFlag holder,
|
||||
InLoopFlag in_loop,
|
||||
int argc) {
|
||||
return ComputeFlags(
|
||||
kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
|
||||
return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
|
||||
}
|
||||
|
||||
|
||||
@ -3159,18 +3150,13 @@ Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
|
||||
}
|
||||
|
||||
|
||||
InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
|
||||
return ICInLoopField::decode(flags);
|
||||
}
|
||||
|
||||
|
||||
PropertyType Code::ExtractTypeFromFlags(Flags flags) {
|
||||
return TypeField::decode(flags);
|
||||
}
|
||||
|
||||
|
||||
int Code::ExtractArgumentsCountFromFlags(Flags flags) {
|
||||
return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
|
||||
return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
|
||||
}
|
||||
|
||||
|
||||
|
@ -7161,7 +7161,6 @@ void Code::Disassemble(const char* name, FILE* out) {
|
||||
if (is_inline_cache_stub()) {
|
||||
PrintF(out, "ic_state = %s\n", ICState2String(ic_state()));
|
||||
PrintExtraICState(out, kind(), extra_ic_state());
|
||||
PrintF(out, "ic_in_loop = %d\n", ic_in_loop() == IN_LOOP);
|
||||
if (ic_state() == MONOMORPHIC) {
|
||||
PrintF(out, "type = %s\n", PropertyType2String(type()));
|
||||
}
|
||||
|
@ -3653,7 +3653,6 @@ class Code: public HeapObject {
|
||||
inline Kind kind();
|
||||
inline InlineCacheState ic_state(); // Only valid for IC stubs.
|
||||
inline ExtraICState extra_ic_state(); // Only valid for IC stubs.
|
||||
inline InLoopFlag ic_in_loop(); // Only valid for IC stubs.
|
||||
inline PropertyType type(); // Only valid for monomorphic IC stubs.
|
||||
inline int arguments_count(); // Only valid for call IC stubs.
|
||||
|
||||
@ -3746,7 +3745,6 @@ class Code: public HeapObject {
|
||||
// Flags operations.
|
||||
static inline Flags ComputeFlags(
|
||||
Kind kind,
|
||||
InLoopFlag in_loop = NOT_IN_LOOP,
|
||||
InlineCacheState ic_state = UNINITIALIZED,
|
||||
ExtraICState extra_ic_state = kNoExtraICState,
|
||||
PropertyType type = NORMAL,
|
||||
@ -3758,11 +3756,9 @@ class Code: public HeapObject {
|
||||
PropertyType type,
|
||||
ExtraICState extra_ic_state = kNoExtraICState,
|
||||
InlineCacheHolderFlag holder = OWN_MAP,
|
||||
InLoopFlag in_loop = NOT_IN_LOOP,
|
||||
int argc = -1);
|
||||
|
||||
static inline InlineCacheState ExtractICStateFromFlags(Flags flags);
|
||||
static inline InLoopFlag ExtractICInLoopFromFlags(Flags flags);
|
||||
static inline PropertyType ExtractTypeFromFlags(Flags flags);
|
||||
static inline Kind ExtractKindFromFlags(Flags flags);
|
||||
static inline InlineCacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
|
||||
@ -3894,18 +3890,17 @@ class Code: public HeapObject {
|
||||
|
||||
// Flags layout. BitField<type, shift, size>.
|
||||
class ICStateField: public BitField<InlineCacheState, 0, 3> {};
|
||||
class ICInLoopField: public BitField<InLoopFlag, 3, 1> {};
|
||||
class TypeField: public BitField<PropertyType, 4, 4> {};
|
||||
class KindField: public BitField<Kind, 8, 4> {};
|
||||
class CacheHolderField: public BitField<InlineCacheHolderFlag, 12, 1> {};
|
||||
class ExtraICStateField: public BitField<ExtraICState, 13, 2> {};
|
||||
class TypeField: public BitField<PropertyType, 3, 4> {};
|
||||
class KindField: public BitField<Kind, 7, 4> {};
|
||||
class CacheHolderField: public BitField<InlineCacheHolderFlag, 11, 1> {};
|
||||
class ExtraICStateField: public BitField<ExtraICState, 12, 2> {};
|
||||
|
||||
// Signed field cannot be encoded using the BitField class.
|
||||
static const int kFlagsArgumentsCountShift = 15;
|
||||
static const int kFlagsArgumentsCountMask = 0xffff8000;
|
||||
static const int kArgumentsCountShift = 14;
|
||||
static const int kArgumentsCountMask = ~((1 << kArgumentsCountShift) - 1);
|
||||
|
||||
static const int kFlagsNotUsedInLookup =
|
||||
ICInLoopField::kMask | TypeField::kMask | CacheHolderField::kMask;
|
||||
TypeField::kMask | CacheHolderField::kMask;
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(Code);
|
||||
|
@ -8139,15 +8139,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyCompile) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Compile the target function. Here we compile using CompileLazyInLoop in
|
||||
// order to get the optimized version. This helps code like delta-blue
|
||||
// that calls performance-critical routines through constructors. A
|
||||
// constructor call doesn't use a CallIC, it uses a LoadIC followed by a
|
||||
// direct call. Since the in-loop tracking takes place through CallICs
|
||||
// this means that things called through constructors are never known to
|
||||
// be in loops. We compile them as if they are in loops here just in case.
|
||||
// Compile the target function.
|
||||
ASSERT(!function->is_compiled());
|
||||
if (!CompileLazyInLoop(function, KEEP_EXCEPTION)) {
|
||||
if (!CompileLazy(function, KEEP_EXCEPTION)) {
|
||||
return Failure::Exception();
|
||||
}
|
||||
|
||||
|
@ -652,7 +652,6 @@ MaybeObject* StubCache::ComputeKeyedStoreField(String* name,
|
||||
(kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
|
||||
|
||||
MaybeObject* StubCache::ComputeCallConstant(int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind kind,
|
||||
Code::ExtraICState extra_ic_state,
|
||||
String* name,
|
||||
@ -678,7 +677,6 @@ MaybeObject* StubCache::ComputeCallConstant(int argc,
|
||||
CONSTANT_FUNCTION,
|
||||
extra_ic_state,
|
||||
cache_holder,
|
||||
in_loop,
|
||||
argc);
|
||||
Object* code = map_holder->map()->FindInCodeCache(name, flags);
|
||||
if (code->IsUndefined()) {
|
||||
@ -688,8 +686,7 @@ MaybeObject* StubCache::ComputeCallConstant(int argc,
|
||||
// caches.
|
||||
if (!function->is_compiled()) return Failure::InternalError();
|
||||
// Compile the stub - only create stubs for fully compiled functions.
|
||||
CallStubCompiler compiler(
|
||||
argc, in_loop, kind, extra_ic_state, cache_holder);
|
||||
CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder);
|
||||
{ MaybeObject* maybe_code =
|
||||
compiler.CompileCallConstant(object, holder, function, name, check);
|
||||
if (!maybe_code->ToObject(&code)) return maybe_code;
|
||||
@ -711,7 +708,6 @@ MaybeObject* StubCache::ComputeCallConstant(int argc,
|
||||
|
||||
|
||||
MaybeObject* StubCache::ComputeCallField(int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind kind,
|
||||
Code::ExtraICState extra_ic_state,
|
||||
String* name,
|
||||
@ -734,12 +730,10 @@ MaybeObject* StubCache::ComputeCallField(int argc,
|
||||
FIELD,
|
||||
extra_ic_state,
|
||||
cache_holder,
|
||||
in_loop,
|
||||
argc);
|
||||
Object* code = map_holder->map()->FindInCodeCache(name, flags);
|
||||
if (code->IsUndefined()) {
|
||||
CallStubCompiler compiler(
|
||||
argc, in_loop, kind, extra_ic_state, cache_holder);
|
||||
CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder);
|
||||
{ MaybeObject* maybe_code =
|
||||
compiler.CompileCallField(JSObject::cast(object),
|
||||
holder,
|
||||
@ -785,12 +779,10 @@ MaybeObject* StubCache::ComputeCallInterceptor(
|
||||
INTERCEPTOR,
|
||||
extra_ic_state,
|
||||
cache_holder,
|
||||
NOT_IN_LOOP,
|
||||
argc);
|
||||
Object* code = map_holder->map()->FindInCodeCache(name, flags);
|
||||
if (code->IsUndefined()) {
|
||||
CallStubCompiler compiler(
|
||||
argc, NOT_IN_LOOP, kind, extra_ic_state, cache_holder);
|
||||
CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder);
|
||||
{ MaybeObject* maybe_code =
|
||||
compiler.CompileCallInterceptor(JSObject::cast(object), holder, name);
|
||||
if (!maybe_code->ToObject(&code)) return maybe_code;
|
||||
@ -811,14 +803,12 @@ MaybeObject* StubCache::ComputeCallInterceptor(
|
||||
|
||||
|
||||
MaybeObject* StubCache::ComputeCallNormal(int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind kind,
|
||||
Code::ExtraICState extra_ic_state,
|
||||
String* name,
|
||||
JSObject* receiver) {
|
||||
Object* code;
|
||||
{ MaybeObject* maybe_code =
|
||||
ComputeCallNormal(argc, in_loop, kind, extra_ic_state);
|
||||
{ MaybeObject* maybe_code = ComputeCallNormal(argc, kind, extra_ic_state);
|
||||
if (!maybe_code->ToObject(&code)) return maybe_code;
|
||||
}
|
||||
return code;
|
||||
@ -826,7 +816,6 @@ MaybeObject* StubCache::ComputeCallNormal(int argc,
|
||||
|
||||
|
||||
MaybeObject* StubCache::ComputeCallGlobal(int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind kind,
|
||||
Code::ExtraICState extra_ic_state,
|
||||
String* name,
|
||||
@ -841,7 +830,6 @@ MaybeObject* StubCache::ComputeCallGlobal(int argc,
|
||||
NORMAL,
|
||||
extra_ic_state,
|
||||
cache_holder,
|
||||
in_loop,
|
||||
argc);
|
||||
Object* code = map_holder->map()->FindInCodeCache(name, flags);
|
||||
if (code->IsUndefined()) {
|
||||
@ -850,8 +838,7 @@ MaybeObject* StubCache::ComputeCallGlobal(int argc,
|
||||
// internal error which will make sure we do not update any
|
||||
// caches.
|
||||
if (!function->is_compiled()) return Failure::InternalError();
|
||||
CallStubCompiler compiler(
|
||||
argc, in_loop, kind, extra_ic_state, cache_holder);
|
||||
CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder);
|
||||
{ MaybeObject* maybe_code =
|
||||
compiler.CompileCallGlobal(receiver, holder, cell, function, name);
|
||||
if (!maybe_code->ToObject(&code)) return maybe_code;
|
||||
@ -920,14 +907,12 @@ static MaybeObject* FillCache(Isolate* isolate, MaybeObject* maybe_code) {
|
||||
|
||||
|
||||
Code* StubCache::FindCallInitialize(int argc,
|
||||
InLoopFlag in_loop,
|
||||
RelocInfo::Mode mode,
|
||||
Code::Kind kind) {
|
||||
Code::ExtraICState extra_state =
|
||||
CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
|
||||
CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
|
||||
Code::Flags flags = Code::ComputeFlags(kind,
|
||||
in_loop,
|
||||
UNINITIALIZED,
|
||||
extra_state,
|
||||
NORMAL,
|
||||
@ -941,14 +926,12 @@ Code* StubCache::FindCallInitialize(int argc,
|
||||
|
||||
|
||||
MaybeObject* StubCache::ComputeCallInitialize(int argc,
|
||||
InLoopFlag in_loop,
|
||||
RelocInfo::Mode mode,
|
||||
Code::Kind kind) {
|
||||
Code::ExtraICState extra_state =
|
||||
CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
|
||||
CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
|
||||
Code::Flags flags = Code::ComputeFlags(kind,
|
||||
in_loop,
|
||||
UNINITIALIZED,
|
||||
extra_state,
|
||||
NORMAL,
|
||||
@ -964,49 +947,26 @@ MaybeObject* StubCache::ComputeCallInitialize(int argc,
|
||||
|
||||
|
||||
Handle<Code> StubCache::ComputeCallInitialize(int argc,
|
||||
InLoopFlag in_loop,
|
||||
RelocInfo::Mode mode) {
|
||||
if (in_loop == IN_LOOP) {
|
||||
// Force the creation of the corresponding stub outside loops,
|
||||
// because it may be used when clearing the ICs later - it is
|
||||
// possible for a series of IC transitions to lose the in-loop
|
||||
// information, and the IC clearing code can't generate a stub
|
||||
// that it needs so we need to ensure it is generated already.
|
||||
ComputeCallInitialize(argc, NOT_IN_LOOP, mode);
|
||||
}
|
||||
CALL_HEAP_FUNCTION(isolate_,
|
||||
ComputeCallInitialize(argc, in_loop, mode, Code::CALL_IC),
|
||||
ComputeCallInitialize(argc, mode, Code::CALL_IC),
|
||||
Code);
|
||||
}
|
||||
|
||||
|
||||
Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc,
|
||||
InLoopFlag in_loop) {
|
||||
if (in_loop == IN_LOOP) {
|
||||
// Force the creation of the corresponding stub outside loops,
|
||||
// because it may be used when clearing the ICs later - it is
|
||||
// possible for a series of IC transitions to lose the in-loop
|
||||
// information, and the IC clearing code can't generate a stub
|
||||
// that it needs so we need to ensure it is generated already.
|
||||
ComputeKeyedCallInitialize(argc, NOT_IN_LOOP);
|
||||
}
|
||||
Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc) {
|
||||
CALL_HEAP_FUNCTION(
|
||||
isolate_,
|
||||
ComputeCallInitialize(argc,
|
||||
in_loop,
|
||||
RelocInfo::CODE_TARGET,
|
||||
Code::KEYED_CALL_IC),
|
||||
ComputeCallInitialize(argc, RelocInfo::CODE_TARGET, Code::KEYED_CALL_IC),
|
||||
Code);
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* StubCache::ComputeCallPreMonomorphic(
|
||||
int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind kind,
|
||||
Code::ExtraICState extra_ic_state) {
|
||||
Code::Flags flags = Code::ComputeFlags(kind,
|
||||
in_loop,
|
||||
PREMONOMORPHIC,
|
||||
extra_ic_state,
|
||||
NORMAL,
|
||||
@ -1022,11 +982,9 @@ MaybeObject* StubCache::ComputeCallPreMonomorphic(
|
||||
|
||||
|
||||
MaybeObject* StubCache::ComputeCallNormal(int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind kind,
|
||||
Code::ExtraICState extra_ic_state) {
|
||||
Code::Flags flags = Code::ComputeFlags(kind,
|
||||
in_loop,
|
||||
MONOMORPHIC,
|
||||
extra_ic_state,
|
||||
NORMAL,
|
||||
@ -1041,12 +999,9 @@ MaybeObject* StubCache::ComputeCallNormal(int argc,
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* StubCache::ComputeCallArguments(int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind kind) {
|
||||
MaybeObject* StubCache::ComputeCallArguments(int argc, Code::Kind kind) {
|
||||
ASSERT(kind == Code::KEYED_CALL_IC);
|
||||
Code::Flags flags = Code::ComputeFlags(kind,
|
||||
in_loop,
|
||||
MEGAMORPHIC,
|
||||
Code::kNoExtraICState,
|
||||
NORMAL,
|
||||
@ -1063,11 +1018,9 @@ MaybeObject* StubCache::ComputeCallArguments(int argc,
|
||||
|
||||
MaybeObject* StubCache::ComputeCallMegamorphic(
|
||||
int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind kind,
|
||||
Code::ExtraICState extra_ic_state) {
|
||||
Code::Flags flags = Code::ComputeFlags(kind,
|
||||
in_loop,
|
||||
MEGAMORPHIC,
|
||||
extra_ic_state,
|
||||
NORMAL,
|
||||
@ -1088,7 +1041,6 @@ MaybeObject* StubCache::ComputeCallMiss(int argc,
|
||||
// MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs
|
||||
// and monomorphic stubs are not mixed up together in the stub cache.
|
||||
Code::Flags flags = Code::ComputeFlags(kind,
|
||||
NOT_IN_LOOP,
|
||||
MONOMORPHIC_PROTOTYPE_FAILURE,
|
||||
extra_ic_state,
|
||||
NORMAL,
|
||||
@ -1111,7 +1063,6 @@ MaybeObject* StubCache::ComputeCallDebugBreak(
|
||||
// Extra IC state is irrelevant for debug break ICs. They jump to
|
||||
// the actual call ic to carry out the work.
|
||||
Code::Flags flags = Code::ComputeFlags(kind,
|
||||
NOT_IN_LOOP,
|
||||
DEBUG_BREAK,
|
||||
Code::kNoExtraICState,
|
||||
NORMAL,
|
||||
@ -1132,7 +1083,6 @@ MaybeObject* StubCache::ComputeCallDebugPrepareStepIn(
|
||||
// Extra IC state is irrelevant for debug break ICs. They jump to
|
||||
// the actual call ic to carry out the work.
|
||||
Code::Flags flags = Code::ComputeFlags(kind,
|
||||
NOT_IN_LOOP,
|
||||
DEBUG_PREPARE_STEP_IN,
|
||||
Code::kNoExtraICState,
|
||||
NORMAL,
|
||||
@ -1672,7 +1622,7 @@ MaybeObject* KeyedLoadStubCompiler::GetCode(PropertyType type,
|
||||
String* name,
|
||||
InlineCacheState state) {
|
||||
Code::Flags flags = Code::ComputeFlags(
|
||||
Code::KEYED_LOAD_IC, NOT_IN_LOOP, state, Code::kNoExtraICState, type);
|
||||
Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type);
|
||||
MaybeObject* result = GetCodeWithFlags(flags, name);
|
||||
if (!result->IsFailure()) {
|
||||
PROFILE(isolate(),
|
||||
@ -1688,8 +1638,8 @@ MaybeObject* KeyedLoadStubCompiler::GetCode(PropertyType type,
|
||||
|
||||
|
||||
MaybeObject* StoreStubCompiler::GetCode(PropertyType type, String* name) {
|
||||
Code::Flags flags = Code::ComputeMonomorphicFlags(
|
||||
Code::STORE_IC, type, strict_mode_);
|
||||
Code::Flags flags =
|
||||
Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_);
|
||||
MaybeObject* result = GetCodeWithFlags(flags, name);
|
||||
if (!result->IsFailure()) {
|
||||
PROFILE(isolate(),
|
||||
@ -1707,8 +1657,8 @@ MaybeObject* StoreStubCompiler::GetCode(PropertyType type, String* name) {
|
||||
MaybeObject* KeyedStoreStubCompiler::GetCode(PropertyType type,
|
||||
String* name,
|
||||
InlineCacheState state) {
|
||||
Code::Flags flags = Code::ComputeFlags(
|
||||
Code::KEYED_STORE_IC, NOT_IN_LOOP, state, strict_mode_, type);
|
||||
Code::Flags flags =
|
||||
Code::ComputeFlags(Code::KEYED_STORE_IC, state, strict_mode_, type);
|
||||
MaybeObject* result = GetCodeWithFlags(flags, name);
|
||||
if (!result->IsFailure()) {
|
||||
PROFILE(isolate(),
|
||||
@ -1730,12 +1680,10 @@ void KeyedStoreStubCompiler::GenerateStoreDictionaryElement(
|
||||
|
||||
|
||||
CallStubCompiler::CallStubCompiler(int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind kind,
|
||||
Code::ExtraICState extra_ic_state,
|
||||
InlineCacheHolderFlag cache_holder)
|
||||
: arguments_(argc),
|
||||
in_loop_(in_loop),
|
||||
kind_(kind),
|
||||
extra_ic_state_(extra_ic_state),
|
||||
cache_holder_(cache_holder) {
|
||||
@ -1796,7 +1744,6 @@ MaybeObject* CallStubCompiler::GetCode(PropertyType type, String* name) {
|
||||
type,
|
||||
extra_ic_state_,
|
||||
cache_holder_,
|
||||
in_loop_,
|
||||
argc);
|
||||
return GetCodeWithFlags(flags, name);
|
||||
}
|
||||
|
@ -194,7 +194,6 @@ class StubCache {
|
||||
|
||||
MUST_USE_RESULT MaybeObject* ComputeCallField(
|
||||
int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind,
|
||||
Code::ExtraICState extra_ic_state,
|
||||
String* name,
|
||||
@ -204,7 +203,6 @@ class StubCache {
|
||||
|
||||
MUST_USE_RESULT MaybeObject* ComputeCallConstant(
|
||||
int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind,
|
||||
Code::ExtraICState extra_ic_state,
|
||||
String* name,
|
||||
@ -214,7 +212,6 @@ class StubCache {
|
||||
|
||||
MUST_USE_RESULT MaybeObject* ComputeCallNormal(
|
||||
int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind,
|
||||
Code::ExtraICState extra_ic_state,
|
||||
String* name,
|
||||
@ -230,7 +227,6 @@ class StubCache {
|
||||
|
||||
MUST_USE_RESULT MaybeObject* ComputeCallGlobal(
|
||||
int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind,
|
||||
Code::ExtraICState extra_ic_state,
|
||||
String* name,
|
||||
@ -242,33 +238,27 @@ class StubCache {
|
||||
// ---
|
||||
|
||||
MUST_USE_RESULT MaybeObject* ComputeCallInitialize(int argc,
|
||||
InLoopFlag in_loop,
|
||||
RelocInfo::Mode mode,
|
||||
Code::Kind kind);
|
||||
|
||||
Handle<Code> ComputeCallInitialize(int argc,
|
||||
InLoopFlag in_loop,
|
||||
RelocInfo::Mode mode);
|
||||
|
||||
Handle<Code> ComputeKeyedCallInitialize(int argc, InLoopFlag in_loop);
|
||||
Handle<Code> ComputeKeyedCallInitialize(int argc);
|
||||
|
||||
MUST_USE_RESULT MaybeObject* ComputeCallPreMonomorphic(
|
||||
int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind kind,
|
||||
Code::ExtraICState extra_ic_state);
|
||||
|
||||
MUST_USE_RESULT MaybeObject* ComputeCallNormal(int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind kind,
|
||||
Code::ExtraICState state);
|
||||
|
||||
MUST_USE_RESULT MaybeObject* ComputeCallArguments(int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind kind);
|
||||
|
||||
MUST_USE_RESULT MaybeObject* ComputeCallMegamorphic(int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind kind,
|
||||
Code::ExtraICState state);
|
||||
|
||||
@ -278,7 +268,6 @@ class StubCache {
|
||||
|
||||
// Finds the Code object stored in the Heap::non_monomorphic_cache().
|
||||
MUST_USE_RESULT Code* FindCallInitialize(int argc,
|
||||
InLoopFlag in_loop,
|
||||
RelocInfo::Mode mode,
|
||||
Code::Kind kind);
|
||||
|
||||
@ -379,11 +368,7 @@ class StubCache {
|
||||
// Use the seed from the primary cache in the secondary cache.
|
||||
uint32_t string_low32bits =
|
||||
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name));
|
||||
// We always set the in_loop bit to zero when generating the lookup code
|
||||
// so do it here too so the hash codes match.
|
||||
uint32_t iflags =
|
||||
(static_cast<uint32_t>(flags) & ~Code::ICInLoopField::kMask);
|
||||
uint32_t key = seed - string_low32bits + iflags;
|
||||
uint32_t key = seed - string_low32bits + flags;
|
||||
return key & ((kSecondaryTableSize - 1) << kHeapObjectTagSize);
|
||||
}
|
||||
|
||||
@ -755,7 +740,6 @@ class CallOptimization;
|
||||
class CallStubCompiler: public StubCompiler {
|
||||
public:
|
||||
CallStubCompiler(int argc,
|
||||
InLoopFlag in_loop,
|
||||
Code::Kind kind,
|
||||
Code::ExtraICState extra_ic_state,
|
||||
InlineCacheHolderFlag cache_holder);
|
||||
@ -815,7 +799,6 @@ class CallStubCompiler: public StubCompiler {
|
||||
String* name);
|
||||
|
||||
const ParameterCount arguments_;
|
||||
const InLoopFlag in_loop_;
|
||||
const Code::Kind kind_;
|
||||
const Code::ExtraICState extra_ic_state_;
|
||||
const InlineCacheHolderFlag cache_holder_;
|
||||
|
@ -190,7 +190,6 @@ void TypeFeedbackOracle::CallReceiverTypes(Call* expr,
|
||||
NORMAL,
|
||||
extra_ic_state,
|
||||
OWN_MAP,
|
||||
NOT_IN_LOOP,
|
||||
arity);
|
||||
CollectReceiverTypes(expr->id(), name, flags, types);
|
||||
}
|
||||
|
@ -302,12 +302,6 @@ enum CheckType {
|
||||
};
|
||||
|
||||
|
||||
enum InLoopFlag {
|
||||
NOT_IN_LOOP,
|
||||
IN_LOOP
|
||||
};
|
||||
|
||||
|
||||
enum CallFunctionFlags {
|
||||
NO_CALL_FUNCTION_FLAGS = 0,
|
||||
// Receiver might implicitly be the global objects. If it is, the
|
||||
|
@ -1926,9 +1926,8 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
|
||||
// Record source position for debugger.
|
||||
SetSourcePosition(expr->position());
|
||||
// Call the IC initialization code.
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
Handle<Code> ic =
|
||||
ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode);
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
|
||||
__ call(ic, mode, expr->id());
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
@ -1959,9 +1958,8 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
|
||||
// Record source position for debugger.
|
||||
SetSourcePosition(expr->position());
|
||||
// Call the IC initialization code.
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
Handle<Code> ic =
|
||||
ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop);
|
||||
isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
|
||||
__ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key.
|
||||
__ call(ic, RelocInfo::CODE_TARGET, expr->id());
|
||||
RecordJSReturnSite(expr);
|
||||
@ -1982,8 +1980,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
|
||||
}
|
||||
// Record source position for debugger.
|
||||
SetSourcePosition(expr->position());
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
CallFunctionStub stub(arg_count, in_loop, flags);
|
||||
CallFunctionStub stub(arg_count, flags);
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
@ -2075,8 +2072,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
}
|
||||
// Record source position for debugger.
|
||||
SetSourcePosition(expr->position());
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT);
|
||||
CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT);
|
||||
__ CallStub(&stub);
|
||||
RecordJSReturnSite(expr);
|
||||
// Restore context register.
|
||||
@ -3477,10 +3473,9 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
if (expr->is_jsruntime()) {
|
||||
// Call the JS runtime function using a call IC.
|
||||
__ Move(rcx, expr->name());
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
|
||||
Handle<Code> ic =
|
||||
ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode);
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
|
||||
__ call(ic, mode, expr->id());
|
||||
// Restore context register.
|
||||
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
||||
|
@ -720,7 +720,6 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
|
||||
|
||||
// Probe the stub cache.
|
||||
Code::Flags flags = Code::ComputeFlags(kind,
|
||||
NOT_IN_LOOP,
|
||||
MONOMORPHIC,
|
||||
extra_ic_state,
|
||||
NORMAL,
|
||||
@ -1267,9 +1266,7 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
|
||||
// -----------------------------------
|
||||
|
||||
// Probe the stub cache.
|
||||
Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC,
|
||||
NOT_IN_LOOP,
|
||||
MONOMORPHIC);
|
||||
Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, MONOMORPHIC);
|
||||
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rax, rcx, rbx,
|
||||
rdx);
|
||||
|
||||
@ -1372,10 +1369,8 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
|
||||
// -----------------------------------
|
||||
|
||||
// Get the receiver from the stack and probe the stub cache.
|
||||
Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
|
||||
NOT_IN_LOOP,
|
||||
MONOMORPHIC,
|
||||
strict_mode);
|
||||
Code::Flags flags =
|
||||
Code::ComputeFlags(Code::STORE_IC, MONOMORPHIC, strict_mode);
|
||||
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx,
|
||||
no_reg);
|
||||
|
||||
|
@ -2953,8 +2953,8 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
|
||||
ASSERT(ToRegister(instr->result()).is(rax));
|
||||
|
||||
int arity = instr->arity();
|
||||
Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(
|
||||
arity, NOT_IN_LOOP);
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeKeyedCallInitialize(arity);
|
||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
||||
}
|
||||
@ -2966,7 +2966,7 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) {
|
||||
int arity = instr->arity();
|
||||
RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode);
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
|
||||
__ Move(rcx, instr->name());
|
||||
CallCode(ic, mode, instr);
|
||||
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
||||
@ -2977,7 +2977,7 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
|
||||
ASSERT(ToRegister(instr->result()).is(rax));
|
||||
|
||||
int arity = instr->arity();
|
||||
CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT);
|
||||
CallFunctionStub stub(arity, RECEIVER_MIGHT_BE_IMPLICIT);
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
||||
__ Drop(1);
|
||||
@ -2989,7 +2989,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
|
||||
int arity = instr->arity();
|
||||
RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
|
||||
Handle<Code> ic =
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode);
|
||||
isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
|
||||
__ Move(rcx, instr->name());
|
||||
CallCode(ic, mode, instr);
|
||||
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
||||
|
Loading…
Reference in New Issue
Block a user