Converted FullCode to have its own list of known intrinsics.
Combined the various lists, the only slightly ugly thing is now the distinction between intrinsics returning pairs and the rest, but that's no big deal. BUG=v8:3947 LOG=n Review URL: https://codereview.chromium.org/989273003 Cr-Commit-Position: refs/heads/master@{#27135}
This commit is contained in:
parent
df9e6fe329
commit
611eb25894
@ -4615,18 +4615,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
InlineFunctionGenerator generator = FindInlineFunctionGenerator(expr);
|
||||
if (generator != nullptr) {
|
||||
Comment cmnt(masm_, "[ InlineRuntimeCall");
|
||||
EmitInlineRuntimeCall(expr, generator);
|
||||
return;
|
||||
}
|
||||
|
||||
Comment cmnt(masm_, "[ CallRuntime");
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
if (expr->is_jsruntime()) {
|
||||
Comment cmnt(masm_, "[ CallRuntime");
|
||||
// Push the builtins object as the receiver.
|
||||
Register receiver = LoadDescriptor::ReceiverRegister();
|
||||
__ ldr(receiver, GlobalObjectOperand());
|
||||
@ -4649,7 +4642,6 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ str(r0, MemOperand(sp, kPointerSize));
|
||||
|
||||
// Push the arguments ("left-to-right").
|
||||
int arg_count = args->length();
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
@ -4664,15 +4656,29 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
|
||||
context()->DropAndPlug(1, r0);
|
||||
} else {
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Call the C runtime function.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
context()->Plug(r0);
|
||||
} else {
|
||||
const Runtime::Function* function = expr->function();
|
||||
switch (function->function_id) {
|
||||
#define CALL_INTRINSIC_GENERATOR(Name) \
|
||||
case Runtime::kInline##Name: { \
|
||||
Comment cmnt(masm_, "[ Inline" #Name); \
|
||||
return Emit##Name(expr); \
|
||||
}
|
||||
FOR_EACH_FULL_CODE_INTRINSIC(CALL_INTRINSIC_GENERATOR)
|
||||
#undef CALL_INTRINSIC_GENERATOR
|
||||
default: {
|
||||
Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Call the C runtime function.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
context()->Plug(r0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4305,18 +4305,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
InlineFunctionGenerator generator = FindInlineFunctionGenerator(expr);
|
||||
if (generator != nullptr) {
|
||||
Comment cmnt(masm_, "[ InlineRuntimeCall");
|
||||
EmitInlineRuntimeCall(expr, generator);
|
||||
return;
|
||||
}
|
||||
|
||||
Comment cmnt(masm_, "[ CallRunTime");
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
if (expr->is_jsruntime()) {
|
||||
Comment cmnt(masm_, "[ CallRunTime");
|
||||
// Push the builtins object as the receiver.
|
||||
__ Ldr(x10, GlobalObjectMemOperand());
|
||||
__ Ldr(LoadDescriptor::ReceiverRegister(),
|
||||
@ -4338,7 +4331,6 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ Pop(x10);
|
||||
__ Push(x0, x10);
|
||||
|
||||
int arg_count = args->length();
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
@ -4353,15 +4345,29 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
|
||||
context()->DropAndPlug(1, x0);
|
||||
} else {
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Call the C runtime function.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
context()->Plug(x0);
|
||||
} else {
|
||||
const Runtime::Function* function = expr->function();
|
||||
switch (function->function_id) {
|
||||
#define CALL_INTRINSIC_GENERATOR(Name) \
|
||||
case Runtime::kInline##Name: { \
|
||||
Comment cmnt(masm_, "[ Inline" #Name); \
|
||||
return Emit##Name(expr); \
|
||||
}
|
||||
FOR_EACH_FULL_CODE_INTRINSIC(CALL_INTRINSIC_GENERATOR)
|
||||
#undef CALL_INTRINSIC_GENERATOR
|
||||
default: {
|
||||
Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Call the C runtime function.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
context()->Plug(x0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -882,40 +882,6 @@ void FullCodeGenerator::SetSourcePosition(int pos) {
|
||||
}
|
||||
|
||||
|
||||
// Lookup table for code generators for special runtime calls which are
|
||||
// generated inline.
|
||||
#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \
|
||||
&FullCodeGenerator::Emit##Name,
|
||||
|
||||
const FullCodeGenerator::InlineFunctionGenerator
|
||||
FullCodeGenerator::kInlineFunctionGenerators[] = {
|
||||
INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
|
||||
};
|
||||
#undef INLINE_FUNCTION_GENERATOR_ADDRESS
|
||||
|
||||
|
||||
FullCodeGenerator::InlineFunctionGenerator
|
||||
FullCodeGenerator::FindInlineFunctionGenerator(CallRuntime* expr) {
|
||||
const Runtime::Function* function = expr->function();
|
||||
if (function == nullptr || function->intrinsic_type != Runtime::INLINE) {
|
||||
return nullptr;
|
||||
}
|
||||
Runtime::FunctionId id = function->function_id;
|
||||
if (id < Runtime::kFirstInlineFunction || Runtime::kLastInlineFunction < id) {
|
||||
return nullptr;
|
||||
}
|
||||
return kInlineFunctionGenerators[static_cast<int>(id) -
|
||||
static_cast<int>(
|
||||
Runtime::kFirstInlineFunction)];
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitInlineRuntimeCall(
|
||||
CallRuntime* expr, InlineFunctionGenerator generator) {
|
||||
((*this).*(generator))(expr);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitGeneratorNext(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
|
@ -291,11 +291,6 @@ class FullCodeGenerator: public AstVisitor {
|
||||
}
|
||||
};
|
||||
|
||||
// Type of a member function that generates inline code for a native function.
|
||||
typedef void (FullCodeGenerator::*InlineFunctionGenerator)(CallRuntime* expr);
|
||||
|
||||
static const InlineFunctionGenerator kInlineFunctionGenerators[];
|
||||
|
||||
// A platform-specific utility to overwrite the accumulator register
|
||||
// with a GC-safe value.
|
||||
void ClearAccumulator();
|
||||
@ -495,16 +490,52 @@ class FullCodeGenerator: public AstVisitor {
|
||||
void EmitKeyedCallWithLoadIC(Call* expr, Expression* key);
|
||||
void EmitKeyedSuperCallWithLoadIC(Call* expr);
|
||||
|
||||
// Platform-specific code for inline runtime calls.
|
||||
InlineFunctionGenerator FindInlineFunctionGenerator(CallRuntime* expr);
|
||||
#define FOR_EACH_FULL_CODE_INTRINSIC(F) \
|
||||
F(IsSmi) \
|
||||
F(IsNonNegativeSmi) \
|
||||
F(IsArray) \
|
||||
F(IsRegExp) \
|
||||
F(IsJSProxy) \
|
||||
F(IsConstructCall) \
|
||||
F(CallFunction) \
|
||||
F(DefaultConstructorCallSuper) \
|
||||
F(ArgumentsLength) \
|
||||
F(Arguments) \
|
||||
F(ValueOf) \
|
||||
F(SetValueOf) \
|
||||
F(DateField) \
|
||||
F(StringCharFromCode) \
|
||||
F(StringCharAt) \
|
||||
F(OneByteSeqStringSetChar) \
|
||||
F(TwoByteSeqStringSetChar) \
|
||||
F(ObjectEquals) \
|
||||
F(IsObject) \
|
||||
F(IsFunction) \
|
||||
F(IsUndetectableObject) \
|
||||
F(IsSpecObject) \
|
||||
F(IsStringWrapperSafeForDefaultValueOf) \
|
||||
F(MathPow) \
|
||||
F(IsMinusZero) \
|
||||
F(HasCachedArrayIndex) \
|
||||
F(GetCachedArrayIndex) \
|
||||
F(FastOneByteArrayJoin) \
|
||||
F(GeneratorNext) \
|
||||
F(GeneratorThrow) \
|
||||
F(DebugBreakInOptimizedCode) \
|
||||
F(ClassOf) \
|
||||
F(StringCharCodeAt) \
|
||||
F(StringAdd) \
|
||||
F(SubString) \
|
||||
F(StringCompare) \
|
||||
F(RegExpExec) \
|
||||
F(RegExpConstructResult) \
|
||||
F(GetFromCache) \
|
||||
F(NumberToString) \
|
||||
F(DebugIsActive)
|
||||
|
||||
void EmitInlineRuntimeCall(CallRuntime* expr,
|
||||
InlineFunctionGenerator generator);
|
||||
|
||||
#define EMIT_INLINE_RUNTIME_CALL(name, x, y) \
|
||||
void Emit##name(CallRuntime* expr);
|
||||
INLINE_FUNCTION_LIST(EMIT_INLINE_RUNTIME_CALL)
|
||||
#undef EMIT_INLINE_RUNTIME_CALL
|
||||
#define GENERATOR_DECLARATION(Name) void Emit##Name(CallRuntime* call);
|
||||
FOR_EACH_FULL_CODE_INTRINSIC(GENERATOR_DECLARATION)
|
||||
#undef GENERATOR_DECLARATION
|
||||
|
||||
// Platform-specific code for resuming generators.
|
||||
void EmitGeneratorResume(Expression *generator,
|
||||
|
@ -4540,17 +4540,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
InlineFunctionGenerator generator = FindInlineFunctionGenerator(expr);
|
||||
if (generator != nullptr) {
|
||||
Comment cmnt(masm_, "[ InlineRuntimeCall");
|
||||
EmitInlineRuntimeCall(expr, generator);
|
||||
return;
|
||||
}
|
||||
|
||||
Comment cmnt(masm_, "[ CallRuntime");
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
if (expr->is_jsruntime()) {
|
||||
Comment cmnt(masm_, "[ CallRuntime");
|
||||
// Push the builtins object as receiver.
|
||||
__ mov(eax, GlobalObjectOperand());
|
||||
__ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
|
||||
@ -4570,9 +4564,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ push(Operand(esp, 0));
|
||||
__ mov(Operand(esp, kPointerSize), eax);
|
||||
|
||||
// Code common for calls using the IC.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
@ -4582,21 +4574,33 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
|
||||
// Restore context register.
|
||||
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
||||
context()->DropAndPlug(1, eax);
|
||||
|
||||
} else {
|
||||
// Push the arguments ("left-to-right").
|
||||
int arg_count = args->length();
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
const Runtime::Function* function = expr->function();
|
||||
switch (function->function_id) {
|
||||
#define CALL_INTRINSIC_GENERATOR(Name) \
|
||||
case Runtime::kInline##Name: { \
|
||||
Comment cmnt(masm_, "[ Inline" #Name); \
|
||||
return Emit##Name(expr); \
|
||||
}
|
||||
FOR_EACH_FULL_CODE_INTRINSIC(CALL_INTRINSIC_GENERATOR)
|
||||
#undef CALL_INTRINSIC_GENERATOR
|
||||
default: {
|
||||
Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Call the C runtime function.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
context()->Plug(eax);
|
||||
}
|
||||
}
|
||||
|
||||
// Call the C runtime function.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
|
||||
context()->Plug(eax);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4623,18 +4623,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
InlineFunctionGenerator generator = FindInlineFunctionGenerator(expr);
|
||||
if (generator != nullptr) {
|
||||
Comment cmnt(masm_, "[ InlineRuntimeCall");
|
||||
EmitInlineRuntimeCall(expr, generator);
|
||||
return;
|
||||
}
|
||||
|
||||
Comment cmnt(masm_, "[ CallRuntime");
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
if (expr->is_jsruntime()) {
|
||||
Comment cmnt(masm_, "[ CallRuntime");
|
||||
// Push the builtins object as the receiver.
|
||||
Register receiver = LoadDescriptor::ReceiverRegister();
|
||||
__ lw(receiver, GlobalObjectOperand());
|
||||
@ -4657,7 +4650,6 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ sw(v0, MemOperand(sp, kPointerSize));
|
||||
|
||||
// Push the arguments ("left-to-right").
|
||||
int arg_count = args->length();
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
@ -4672,15 +4664,29 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
|
||||
context()->DropAndPlug(1, v0);
|
||||
} else {
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Call the C runtime function.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
context()->Plug(v0);
|
||||
} else {
|
||||
const Runtime::Function* function = expr->function();
|
||||
switch (function->function_id) {
|
||||
#define CALL_INTRINSIC_GENERATOR(Name) \
|
||||
case Runtime::kInline##Name: { \
|
||||
Comment cmnt(masm_, "[ Inline" #Name); \
|
||||
return Emit##Name(expr); \
|
||||
}
|
||||
FOR_EACH_FULL_CODE_INTRINSIC(CALL_INTRINSIC_GENERATOR)
|
||||
#undef CALL_INTRINSIC_GENERATOR
|
||||
default: {
|
||||
Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Call the C runtime function.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
context()->Plug(v0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4626,18 +4626,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
InlineFunctionGenerator generator = FindInlineFunctionGenerator(expr);
|
||||
if (generator != nullptr) {
|
||||
Comment cmnt(masm_, "[ InlineRuntimeCall");
|
||||
EmitInlineRuntimeCall(expr, generator);
|
||||
return;
|
||||
}
|
||||
|
||||
Comment cmnt(masm_, "[ CallRuntime");
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
if (expr->is_jsruntime()) {
|
||||
Comment cmnt(masm_, "[ CallRuntime");
|
||||
// Push the builtins object as the receiver.
|
||||
Register receiver = LoadDescriptor::ReceiverRegister();
|
||||
__ ld(receiver, GlobalObjectOperand());
|
||||
@ -4660,7 +4653,6 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ sd(v0, MemOperand(sp, kPointerSize));
|
||||
|
||||
// Push the arguments ("left-to-right").
|
||||
int arg_count = args->length();
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
@ -4676,14 +4668,27 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
|
||||
context()->DropAndPlug(1, v0);
|
||||
} else {
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
const Runtime::Function* function = expr->function();
|
||||
switch (function->function_id) {
|
||||
#define CALL_INTRINSIC_GENERATOR(Name) \
|
||||
case Runtime::kInline##Name: { \
|
||||
Comment cmnt(masm_, "[ Inline" #Name); \
|
||||
return Emit##Name(expr); \
|
||||
}
|
||||
FOR_EACH_FULL_CODE_INTRINSIC(CALL_INTRINSIC_GENERATOR)
|
||||
#undef CALL_INTRINSIC_GENERATOR
|
||||
default: {
|
||||
Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Call the C runtime function.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
context()->Plug(v0);
|
||||
// Call the C runtime function.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
context()->Plug(v0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4623,18 +4623,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
InlineFunctionGenerator generator = FindInlineFunctionGenerator(expr);
|
||||
if (generator != nullptr) {
|
||||
Comment cmnt(masm_, "[ InlineRuntimeCall");
|
||||
EmitInlineRuntimeCall(expr, generator);
|
||||
return;
|
||||
}
|
||||
|
||||
Comment cmnt(masm_, "[ CallRuntime");
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
if (expr->is_jsruntime()) {
|
||||
Comment cmnt(masm_, "[ CallRuntime");
|
||||
// Push the builtins object as the receiver.
|
||||
Register receiver = LoadDescriptor::ReceiverRegister();
|
||||
__ LoadP(receiver, GlobalObjectOperand());
|
||||
@ -4658,7 +4651,6 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ StoreP(r3, MemOperand(sp, kPointerSize));
|
||||
|
||||
// Push the arguments ("left-to-right").
|
||||
int arg_count = args->length();
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
@ -4673,15 +4665,29 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
|
||||
context()->DropAndPlug(1, r3);
|
||||
} else {
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Call the C runtime function.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
context()->Plug(r3);
|
||||
} else {
|
||||
const Runtime::Function* function = expr->function();
|
||||
switch (function->function_id) {
|
||||
#define CALL_INTRINSIC_GENERATOR(Name) \
|
||||
case Runtime::kInline##Name: { \
|
||||
Comment cmnt(masm_, "[ Inline" #Name); \
|
||||
return Emit##Name(expr); \
|
||||
}
|
||||
FOR_EACH_FULL_CODE_INTRINSIC(CALL_INTRINSIC_GENERATOR)
|
||||
#undef CALL_INTRINSIC_GENERATOR
|
||||
default: {
|
||||
Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Call the C runtime function.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
context()->Plug(r3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,9 +48,7 @@ INLINE_FUNCTION_LIST(F)
|
||||
|
||||
|
||||
static const Runtime::Function kIntrinsicFunctions[] = {
|
||||
RUNTIME_FUNCTION_LIST(F) INLINE_FUNCTION_LIST(F)
|
||||
INLINE_OPTIMIZED_FUNCTION_LIST(F) RUNTIME_FUNCTION_LIST(I)
|
||||
INLINE_FUNCTION_LIST(I) INLINE_OPTIMIZED_FUNCTION_LIST(I)};
|
||||
FOR_EACH_INTRINSIC(F) FOR_EACH_INTRINSIC(I)};
|
||||
|
||||
#undef I
|
||||
#undef F
|
||||
|
@ -15,10 +15,6 @@ namespace internal {
|
||||
// The interface to C++ runtime functions.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RUNTIME_FUNCTION_LIST_ALWAYS defines runtime calls available in both
|
||||
// release and debug mode.
|
||||
// This macro should only be used by the macro RUNTIME_FUNCTION_LIST.
|
||||
|
||||
// WARNING: RUNTIME_FUNCTION_LIST_ALWAYS_* is a very large macro that caused
|
||||
// MSVC Intellisense to crash. It was broken into two macros to work around
|
||||
// this problem. Please avoid large recursive macros whenever possible.
|
||||
@ -630,12 +626,6 @@ namespace internal {
|
||||
#endif
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RUNTIME_FUNCTION_LIST defines all runtime functions accessed
|
||||
// either directly by id (via the code generator), or indirectly
|
||||
// via a native call by name (from within JS code).
|
||||
// Entries have the form F(name, number of arguments, number of return values).
|
||||
|
||||
#define RUNTIME_FUNCTION_LIST_RETURN_OBJECT(F) \
|
||||
RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \
|
||||
RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
|
||||
@ -644,13 +634,18 @@ namespace internal {
|
||||
RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F)
|
||||
|
||||
|
||||
// RUNTIME_FUNCTION_LIST_ defines the intrinsics typically implemented only
|
||||
// as runtime functions. These come in 2 flavors, either returning an object or
|
||||
// returning a pair.
|
||||
// Entries have the form F(name, number of arguments, number of return values).
|
||||
#define RUNTIME_FUNCTION_LIST(F) \
|
||||
RUNTIME_FUNCTION_LIST_RETURN_OBJECT(F) \
|
||||
RUNTIME_FUNCTION_LIST_RETURN_PAIR(F)
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// INLINE_FUNCTION_LIST defines all inlined functions accessed
|
||||
// with a native call of the form %_name from within JS code.
|
||||
// INLINE_FUNCTION_LIST defines the intrinsics typically handled specially by
|
||||
// the various compilers.
|
||||
// Entries have the form F(name, number of arguments, number of return values).
|
||||
#define INLINE_FUNCTION_LIST(F) \
|
||||
F(IsSmi, 1, 1) \
|
||||
@ -697,11 +692,8 @@ namespace internal {
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// INLINE_OPTIMIZED_FUNCTION_LIST defines all inlined functions accessed
|
||||
// with a native call of the form %_name from within JS code that also have
|
||||
// a corresponding runtime function, that is called from non-optimized code.
|
||||
// For the benefit of (fuzz) tests, the runtime version can also be called
|
||||
// directly as %name (i.e. without the leading underscore).
|
||||
// INLINE_OPTIMIZED_FUNCTION_LIST defines the intrinsics typically handled
|
||||
// specially by Crankshaft.
|
||||
// Entries have the form F(name, number of arguments, number of return values).
|
||||
#define INLINE_OPTIMIZED_FUNCTION_LIST(F) \
|
||||
/* Typed Arrays */ \
|
||||
@ -740,6 +732,11 @@ namespace internal {
|
||||
F(GetPrototype, 1, 1)
|
||||
|
||||
|
||||
#define FOR_EACH_INTRINSIC(F) \
|
||||
RUNTIME_FUNCTION_LIST(F) \
|
||||
INLINE_FUNCTION_LIST(F) \
|
||||
INLINE_OPTIMIZED_FUNCTION_LIST(F)
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Runtime provides access to all C++ runtime functions.
|
||||
|
||||
@ -772,15 +769,10 @@ class Runtime : public AllStatic {
|
||||
enum FunctionId {
|
||||
#define F(name, nargs, ressize) k##name,
|
||||
#define I(name, nargs, ressize) kInline##name,
|
||||
RUNTIME_FUNCTION_LIST(F) INLINE_FUNCTION_LIST(F)
|
||||
INLINE_OPTIMIZED_FUNCTION_LIST(F) RUNTIME_FUNCTION_LIST(I)
|
||||
INLINE_FUNCTION_LIST(I) INLINE_OPTIMIZED_FUNCTION_LIST(I)
|
||||
FOR_EACH_INTRINSIC(F) FOR_EACH_INTRINSIC(I)
|
||||
#undef I
|
||||
#undef F
|
||||
kNumFunctions,
|
||||
// TODO(svenpanne) The values below are cruel hacks, remove them!
|
||||
kFirstInlineFunction = kInlineIsSmi,
|
||||
kLastInlineFunction = kInlineDebugIsActive
|
||||
kNumFunctions,
|
||||
};
|
||||
|
||||
enum IntrinsicType { RUNTIME, INLINE };
|
||||
|
@ -221,8 +221,7 @@ ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
|
||||
#define RUNTIME_ENTRY(name, i1, i2) \
|
||||
{ Runtime::k##name, "Runtime::" #name } \
|
||||
,
|
||||
RUNTIME_FUNCTION_LIST(RUNTIME_ENTRY) INLINE_FUNCTION_LIST(RUNTIME_ENTRY)
|
||||
INLINE_OPTIMIZED_FUNCTION_LIST(RUNTIME_ENTRY)
|
||||
FOR_EACH_INTRINSIC(RUNTIME_ENTRY)
|
||||
#undef RUNTIME_ENTRY
|
||||
};
|
||||
|
||||
|
@ -4564,18 +4564,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
InlineFunctionGenerator generator = FindInlineFunctionGenerator(expr);
|
||||
if (generator != nullptr) {
|
||||
Comment cmnt(masm_, "[ InlineRuntimeCall");
|
||||
EmitInlineRuntimeCall(expr, generator);
|
||||
return;
|
||||
}
|
||||
|
||||
Comment cmnt(masm_, "[ CallRuntime");
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
if (expr->is_jsruntime()) {
|
||||
Comment cmnt(masm_, "[ CallRuntime");
|
||||
// Push the builtins object as receiver.
|
||||
__ movp(rax, GlobalObjectOperand());
|
||||
__ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset));
|
||||
@ -4611,14 +4604,27 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
context()->DropAndPlug(1, rax);
|
||||
|
||||
} else {
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
const Runtime::Function* function = expr->function();
|
||||
switch (function->function_id) {
|
||||
#define CALL_INTRINSIC_GENERATOR(Name) \
|
||||
case Runtime::kInline##Name: { \
|
||||
Comment cmnt(masm_, "[ Inline" #Name); \
|
||||
return Emit##Name(expr); \
|
||||
}
|
||||
FOR_EACH_FULL_CODE_INTRINSIC(CALL_INTRINSIC_GENERATOR)
|
||||
#undef CALL_INTRINSIC_GENERATOR
|
||||
default: {
|
||||
Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Call the C runtime.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
context()->Plug(rax);
|
||||
// Call the C runtime.
|
||||
__ CallRuntime(function, arg_count);
|
||||
context()->Plug(rax);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4495,17 +4495,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
InlineFunctionGenerator generator = FindInlineFunctionGenerator(expr);
|
||||
if (generator != nullptr) {
|
||||
Comment cmnt(masm_, "[ InlineRuntimeCall");
|
||||
EmitInlineRuntimeCall(expr, generator);
|
||||
return;
|
||||
}
|
||||
|
||||
Comment cmnt(masm_, "[ CallRuntime");
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
if (expr->is_jsruntime()) {
|
||||
Comment cmnt(masm_, "[ CallRuntime");
|
||||
// Push the builtins object as receiver.
|
||||
__ mov(eax, GlobalObjectOperand());
|
||||
__ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
|
||||
@ -4525,9 +4519,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ push(Operand(esp, 0));
|
||||
__ mov(Operand(esp, kPointerSize), eax);
|
||||
|
||||
// Code common for calls using the IC.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
@ -4542,16 +4534,27 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
context()->DropAndPlug(1, eax);
|
||||
|
||||
} else {
|
||||
// Push the arguments ("left-to-right").
|
||||
int arg_count = args->length();
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
const Runtime::Function* function = expr->function();
|
||||
switch (function->function_id) {
|
||||
#define CALL_INTRINSIC_GENERATOR(Name) \
|
||||
case Runtime::kInline##Name: { \
|
||||
Comment cmnt(masm_, "[ Inline" #Name); \
|
||||
return Emit##Name(expr); \
|
||||
}
|
||||
FOR_EACH_FULL_CODE_INTRINSIC(CALL_INTRINSIC_GENERATOR)
|
||||
#undef CALL_INTRINSIC_GENERATOR
|
||||
default: {
|
||||
Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
|
||||
// Push the arguments ("left-to-right").
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
// Call the C runtime function.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
context()->Plug(eax);
|
||||
}
|
||||
}
|
||||
|
||||
// Call the C runtime function.
|
||||
__ CallRuntime(expr->function(), arg_count);
|
||||
|
||||
context()->Plug(eax);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user