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:
svenpanne 2015-03-11 07:03:21 -07:00 committed by Commit bot
parent df9e6fe329
commit 611eb25894
13 changed files with 244 additions and 216 deletions

View File

@ -4615,18 +4615,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
void FullCodeGenerator::VisitCallRuntime(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(); ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length(); int arg_count = args->length();
if (expr->is_jsruntime()) { if (expr->is_jsruntime()) {
Comment cmnt(masm_, "[ CallRuntime");
// Push the builtins object as the receiver. // Push the builtins object as the receiver.
Register receiver = LoadDescriptor::ReceiverRegister(); Register receiver = LoadDescriptor::ReceiverRegister();
__ ldr(receiver, GlobalObjectOperand()); __ ldr(receiver, GlobalObjectOperand());
@ -4649,7 +4642,6 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ str(r0, MemOperand(sp, kPointerSize)); __ str(r0, MemOperand(sp, kPointerSize));
// Push the arguments ("left-to-right"). // Push the arguments ("left-to-right").
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i)); VisitForStackValue(args->at(i));
} }
@ -4664,15 +4656,29 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
context()->DropAndPlug(1, r0); 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. } else {
__ CallRuntime(expr->function(), arg_count); const Runtime::Function* function = expr->function();
context()->Plug(r0); 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);
}
}
} }
} }

View File

@ -4305,18 +4305,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
void FullCodeGenerator::VisitCallRuntime(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(); ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length(); int arg_count = args->length();
if (expr->is_jsruntime()) { if (expr->is_jsruntime()) {
Comment cmnt(masm_, "[ CallRunTime");
// Push the builtins object as the receiver. // Push the builtins object as the receiver.
__ Ldr(x10, GlobalObjectMemOperand()); __ Ldr(x10, GlobalObjectMemOperand());
__ Ldr(LoadDescriptor::ReceiverRegister(), __ Ldr(LoadDescriptor::ReceiverRegister(),
@ -4338,7 +4331,6 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ Pop(x10); __ Pop(x10);
__ Push(x0, x10); __ Push(x0, x10);
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i)); VisitForStackValue(args->at(i));
} }
@ -4353,15 +4345,29 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
context()->DropAndPlug(1, x0); 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. } else {
__ CallRuntime(expr->function(), arg_count); const Runtime::Function* function = expr->function();
context()->Plug(x0); 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);
}
}
} }
} }

View File

@ -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) { void FullCodeGenerator::EmitGeneratorNext(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 2); DCHECK(args->length() == 2);

View File

@ -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 // A platform-specific utility to overwrite the accumulator register
// with a GC-safe value. // with a GC-safe value.
void ClearAccumulator(); void ClearAccumulator();
@ -495,16 +490,52 @@ class FullCodeGenerator: public AstVisitor {
void EmitKeyedCallWithLoadIC(Call* expr, Expression* key); void EmitKeyedCallWithLoadIC(Call* expr, Expression* key);
void EmitKeyedSuperCallWithLoadIC(Call* expr); void EmitKeyedSuperCallWithLoadIC(Call* expr);
// Platform-specific code for inline runtime calls. #define FOR_EACH_FULL_CODE_INTRINSIC(F) \
InlineFunctionGenerator FindInlineFunctionGenerator(CallRuntime* expr); 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, #define GENERATOR_DECLARATION(Name) void Emit##Name(CallRuntime* call);
InlineFunctionGenerator generator); FOR_EACH_FULL_CODE_INTRINSIC(GENERATOR_DECLARATION)
#undef GENERATOR_DECLARATION
#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
// Platform-specific code for resuming generators. // Platform-specific code for resuming generators.
void EmitGeneratorResume(Expression *generator, void EmitGeneratorResume(Expression *generator,

View File

@ -4540,17 +4540,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
void FullCodeGenerator::VisitCallRuntime(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(); ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
if (expr->is_jsruntime()) { if (expr->is_jsruntime()) {
Comment cmnt(masm_, "[ CallRuntime");
// Push the builtins object as receiver. // Push the builtins object as receiver.
__ mov(eax, GlobalObjectOperand()); __ mov(eax, GlobalObjectOperand());
__ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
@ -4570,9 +4564,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ push(Operand(esp, 0)); __ push(Operand(esp, 0));
__ mov(Operand(esp, kPointerSize), eax); __ mov(Operand(esp, kPointerSize), eax);
// Code common for calls using the IC. // Push the arguments ("left-to-right").
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i)); VisitForStackValue(args->at(i));
} }
@ -4582,21 +4574,33 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub); __ CallStub(&stub);
// Restore context register. // Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
context()->DropAndPlug(1, eax); context()->DropAndPlug(1, eax);
} else { } else {
// Push the arguments ("left-to-right"). const Runtime::Function* function = expr->function();
int arg_count = args->length(); switch (function->function_id) {
for (int i = 0; i < arg_count; i++) { #define CALL_INTRINSIC_GENERATOR(Name) \
VisitForStackValue(args->at(i)); 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);
} }
} }

View File

@ -4623,18 +4623,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
void FullCodeGenerator::VisitCallRuntime(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(); ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length(); int arg_count = args->length();
if (expr->is_jsruntime()) { if (expr->is_jsruntime()) {
Comment cmnt(masm_, "[ CallRuntime");
// Push the builtins object as the receiver. // Push the builtins object as the receiver.
Register receiver = LoadDescriptor::ReceiverRegister(); Register receiver = LoadDescriptor::ReceiverRegister();
__ lw(receiver, GlobalObjectOperand()); __ lw(receiver, GlobalObjectOperand());
@ -4657,7 +4650,6 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ sw(v0, MemOperand(sp, kPointerSize)); __ sw(v0, MemOperand(sp, kPointerSize));
// Push the arguments ("left-to-right"). // Push the arguments ("left-to-right").
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i)); VisitForStackValue(args->at(i));
} }
@ -4672,15 +4664,29 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
context()->DropAndPlug(1, v0); 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. } else {
__ CallRuntime(expr->function(), arg_count); const Runtime::Function* function = expr->function();
context()->Plug(v0); 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);
}
}
} }
} }

View File

@ -4626,18 +4626,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
void FullCodeGenerator::VisitCallRuntime(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(); ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length(); int arg_count = args->length();
if (expr->is_jsruntime()) { if (expr->is_jsruntime()) {
Comment cmnt(masm_, "[ CallRuntime");
// Push the builtins object as the receiver. // Push the builtins object as the receiver.
Register receiver = LoadDescriptor::ReceiverRegister(); Register receiver = LoadDescriptor::ReceiverRegister();
__ ld(receiver, GlobalObjectOperand()); __ ld(receiver, GlobalObjectOperand());
@ -4660,7 +4653,6 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ sd(v0, MemOperand(sp, kPointerSize)); __ sd(v0, MemOperand(sp, kPointerSize));
// Push the arguments ("left-to-right"). // Push the arguments ("left-to-right").
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i)); VisitForStackValue(args->at(i));
} }
@ -4676,14 +4668,27 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
context()->DropAndPlug(1, v0); context()->DropAndPlug(1, v0);
} else { } else {
// Push the arguments ("left-to-right"). const Runtime::Function* function = expr->function();
for (int i = 0; i < arg_count; i++) { switch (function->function_id) {
VisitForStackValue(args->at(i)); #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. // Call the C runtime function.
__ CallRuntime(expr->function(), arg_count); __ CallRuntime(expr->function(), arg_count);
context()->Plug(v0); context()->Plug(v0);
}
}
} }
} }

View File

@ -4623,18 +4623,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
void FullCodeGenerator::VisitCallRuntime(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(); ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length(); int arg_count = args->length();
if (expr->is_jsruntime()) { if (expr->is_jsruntime()) {
Comment cmnt(masm_, "[ CallRuntime");
// Push the builtins object as the receiver. // Push the builtins object as the receiver.
Register receiver = LoadDescriptor::ReceiverRegister(); Register receiver = LoadDescriptor::ReceiverRegister();
__ LoadP(receiver, GlobalObjectOperand()); __ LoadP(receiver, GlobalObjectOperand());
@ -4658,7 +4651,6 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ StoreP(r3, MemOperand(sp, kPointerSize)); __ StoreP(r3, MemOperand(sp, kPointerSize));
// Push the arguments ("left-to-right"). // Push the arguments ("left-to-right").
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i)); VisitForStackValue(args->at(i));
} }
@ -4673,15 +4665,29 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
context()->DropAndPlug(1, r3); 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. } else {
__ CallRuntime(expr->function(), arg_count); const Runtime::Function* function = expr->function();
context()->Plug(r3); 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);
}
}
} }
} }

View File

@ -48,9 +48,7 @@ INLINE_FUNCTION_LIST(F)
static const Runtime::Function kIntrinsicFunctions[] = { static const Runtime::Function kIntrinsicFunctions[] = {
RUNTIME_FUNCTION_LIST(F) INLINE_FUNCTION_LIST(F) FOR_EACH_INTRINSIC(F) FOR_EACH_INTRINSIC(I)};
INLINE_OPTIMIZED_FUNCTION_LIST(F) RUNTIME_FUNCTION_LIST(I)
INLINE_FUNCTION_LIST(I) INLINE_OPTIMIZED_FUNCTION_LIST(I)};
#undef I #undef I
#undef F #undef F

View File

@ -15,10 +15,6 @@ namespace internal {
// The interface to C++ runtime functions. // 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 // 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 // MSVC Intellisense to crash. It was broken into two macros to work around
// this problem. Please avoid large recursive macros whenever possible. // this problem. Please avoid large recursive macros whenever possible.
@ -630,12 +626,6 @@ namespace internal {
#endif #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) \ #define RUNTIME_FUNCTION_LIST_RETURN_OBJECT(F) \
RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \ RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \
RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \ RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
@ -644,13 +634,18 @@ namespace internal {
RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F) 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) \ #define RUNTIME_FUNCTION_LIST(F) \
RUNTIME_FUNCTION_LIST_RETURN_OBJECT(F) \ RUNTIME_FUNCTION_LIST_RETURN_OBJECT(F) \
RUNTIME_FUNCTION_LIST_RETURN_PAIR(F) RUNTIME_FUNCTION_LIST_RETURN_PAIR(F)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// INLINE_FUNCTION_LIST defines all inlined functions accessed // INLINE_FUNCTION_LIST defines the intrinsics typically handled specially by
// with a native call of the form %_name from within JS code. // the various compilers.
// Entries have the form F(name, number of arguments, number of return values). // Entries have the form F(name, number of arguments, number of return values).
#define INLINE_FUNCTION_LIST(F) \ #define INLINE_FUNCTION_LIST(F) \
F(IsSmi, 1, 1) \ F(IsSmi, 1, 1) \
@ -697,11 +692,8 @@ namespace internal {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// INLINE_OPTIMIZED_FUNCTION_LIST defines all inlined functions accessed // INLINE_OPTIMIZED_FUNCTION_LIST defines the intrinsics typically handled
// with a native call of the form %_name from within JS code that also have // specially by Crankshaft.
// 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).
// Entries have the form F(name, number of arguments, number of return values). // Entries have the form F(name, number of arguments, number of return values).
#define INLINE_OPTIMIZED_FUNCTION_LIST(F) \ #define INLINE_OPTIMIZED_FUNCTION_LIST(F) \
/* Typed Arrays */ \ /* Typed Arrays */ \
@ -740,6 +732,11 @@ namespace internal {
F(GetPrototype, 1, 1) 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. // Runtime provides access to all C++ runtime functions.
@ -772,15 +769,10 @@ class Runtime : public AllStatic {
enum FunctionId { enum FunctionId {
#define F(name, nargs, ressize) k##name, #define F(name, nargs, ressize) k##name,
#define I(name, nargs, ressize) kInline##name, #define I(name, nargs, ressize) kInline##name,
RUNTIME_FUNCTION_LIST(F) INLINE_FUNCTION_LIST(F) FOR_EACH_INTRINSIC(F) FOR_EACH_INTRINSIC(I)
INLINE_OPTIMIZED_FUNCTION_LIST(F) RUNTIME_FUNCTION_LIST(I)
INLINE_FUNCTION_LIST(I) INLINE_OPTIMIZED_FUNCTION_LIST(I)
#undef I #undef I
#undef F #undef F
kNumFunctions, kNumFunctions,
// TODO(svenpanne) The values below are cruel hacks, remove them!
kFirstInlineFunction = kInlineIsSmi,
kLastInlineFunction = kInlineDebugIsActive
}; };
enum IntrinsicType { RUNTIME, INLINE }; enum IntrinsicType { RUNTIME, INLINE };

View File

@ -221,8 +221,7 @@ ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
#define RUNTIME_ENTRY(name, i1, i2) \ #define RUNTIME_ENTRY(name, i1, i2) \
{ Runtime::k##name, "Runtime::" #name } \ { Runtime::k##name, "Runtime::" #name } \
, ,
RUNTIME_FUNCTION_LIST(RUNTIME_ENTRY) INLINE_FUNCTION_LIST(RUNTIME_ENTRY) FOR_EACH_INTRINSIC(RUNTIME_ENTRY)
INLINE_OPTIMIZED_FUNCTION_LIST(RUNTIME_ENTRY)
#undef RUNTIME_ENTRY #undef RUNTIME_ENTRY
}; };

View File

@ -4564,18 +4564,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
void FullCodeGenerator::VisitCallRuntime(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(); ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length(); int arg_count = args->length();
if (expr->is_jsruntime()) { if (expr->is_jsruntime()) {
Comment cmnt(masm_, "[ CallRuntime");
// Push the builtins object as receiver. // Push the builtins object as receiver.
__ movp(rax, GlobalObjectOperand()); __ movp(rax, GlobalObjectOperand());
__ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset));
@ -4611,14 +4604,27 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
context()->DropAndPlug(1, rax); context()->DropAndPlug(1, rax);
} else { } else {
// Push the arguments ("left-to-right"). const Runtime::Function* function = expr->function();
for (int i = 0; i < arg_count; i++) { switch (function->function_id) {
VisitForStackValue(args->at(i)); #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. // Call the C runtime.
__ CallRuntime(expr->function(), arg_count); __ CallRuntime(function, arg_count);
context()->Plug(rax); context()->Plug(rax);
}
}
} }
} }

View File

@ -4495,17 +4495,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
void FullCodeGenerator::VisitCallRuntime(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(); ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
if (expr->is_jsruntime()) { if (expr->is_jsruntime()) {
Comment cmnt(masm_, "[ CallRuntime");
// Push the builtins object as receiver. // Push the builtins object as receiver.
__ mov(eax, GlobalObjectOperand()); __ mov(eax, GlobalObjectOperand());
__ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
@ -4525,9 +4519,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ push(Operand(esp, 0)); __ push(Operand(esp, 0));
__ mov(Operand(esp, kPointerSize), eax); __ mov(Operand(esp, kPointerSize), eax);
// Code common for calls using the IC. // Push the arguments ("left-to-right").
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i)); VisitForStackValue(args->at(i));
} }
@ -4542,16 +4534,27 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
context()->DropAndPlug(1, eax); context()->DropAndPlug(1, eax);
} else { } else {
// Push the arguments ("left-to-right"). const Runtime::Function* function = expr->function();
int arg_count = args->length(); switch (function->function_id) {
for (int i = 0; i < arg_count; i++) { #define CALL_INTRINSIC_GENERATOR(Name) \
VisitForStackValue(args->at(i)); 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);
} }
} }