Move inlined function declarations and support from codegen.* to runtime.*.

Review URL: http://codereview.chromium.org/3293002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5451 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
whesse@chromium.org 2010-09-14 14:52:53 +00:00
parent 2388079051
commit fc83faa8fd
13 changed files with 242 additions and 194 deletions

View File

@ -271,10 +271,6 @@ class CodeGenerator: public AstVisitor {
void AddDeferred(DeferredCode* code) { deferred_.Add(code); }
// If the name is an inline runtime function call return the number of
// expected arguments. Otherwise return -1.
static int InlineRuntimeCallArgumentsCount(Handle<String> name);
// Constants related to patching of inlined load/store.
static int GetInlinedKeyedLoadInstructionsAfterPatch() {
return FLAG_debug_code ? 32 : 13;
@ -290,6 +286,12 @@ class CodeGenerator: public AstVisitor {
}
private:
// Type of a member function that generates inline code for a native function.
typedef void (CodeGenerator::*InlineFunctionGenerator)
(ZoneList<Expression*>*);
static const InlineFunctionGenerator kInlineFunctionGenerators[];
// Construction/Destruction
explicit CodeGenerator(MacroAssembler* masm);
@ -447,13 +449,9 @@ class CodeGenerator: public AstVisitor {
void Branch(bool if_true, JumpTarget* target);
void CheckStack();
struct InlineRuntimeLUT {
void (CodeGenerator::*method)(ZoneList<Expression*>*);
const char* name;
int nargs;
};
static InlineFunctionGenerator FindInlineFunctionGenerator(
Runtime::FunctionId function_id);
static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name);
bool CheckForInlineRuntimeCall(CallRuntime* node);
static Handle<Code> ComputeLazyCompile(int argc);
@ -599,8 +597,6 @@ class CodeGenerator: public AstVisitor {
// Size of inlined write barriers generated by EmitNamedStore.
static int inlined_write_barrier_size_;
static InlineRuntimeLUT kInlineRuntimeLUT[];
friend class VirtualFrame;
friend class JumpTarget;
friend class Reference;

View File

@ -1,4 +1,4 @@
// Copyright 2009 the V8 project authors. All rights reserved.
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@ -344,40 +344,35 @@ void CodeGenerator::VisitIncrementOperation(IncrementOperation* expr) {
}
// List of special runtime calls which are generated inline. For some of these
// functions the code will be generated inline, and for others a call to a code
// stub will be inlined.
// Lookup table for code generators for special runtime calls which are
// generated inline.
#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \
&CodeGenerator::Generate##Name,
#define INLINE_RUNTIME_ENTRY(Name, argc, ressize) \
{&CodeGenerator::Generate##Name, "_" #Name, argc}, \
CodeGenerator::InlineRuntimeLUT CodeGenerator::kInlineRuntimeLUT[] = {
INLINE_RUNTIME_FUNCTION_LIST(INLINE_RUNTIME_ENTRY)
const CodeGenerator::InlineFunctionGenerator
CodeGenerator::kInlineFunctionGenerators[] = {
INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
};
#undef INLINE_FUNCTION_GENERATOR_ADDRESS
#undef INLINE_RUNTIME_ENTRY
CodeGenerator::InlineRuntimeLUT* CodeGenerator::FindInlineRuntimeLUT(
Handle<String> name) {
const int entries_count =
sizeof(kInlineRuntimeLUT) / sizeof(InlineRuntimeLUT);
for (int i = 0; i < entries_count; i++) {
InlineRuntimeLUT* entry = &kInlineRuntimeLUT[i];
if (name->IsEqualTo(CStrVector(entry->name))) {
return entry;
}
}
return NULL;
CodeGenerator::InlineFunctionGenerator
CodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) {
return kInlineFunctionGenerators[
static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction)];
}
bool CodeGenerator::CheckForInlineRuntimeCall(CallRuntime* node) {
ZoneList<Expression*>* args = node->arguments();
Handle<String> name = node->name();
if (name->length() > 0 && name->Get(0) == '_') {
InlineRuntimeLUT* entry = FindInlineRuntimeLUT(name);
if (entry != NULL) {
((*this).*(entry->method))(args);
Runtime::Function* function = node->function();
if (function != NULL && function->intrinsic_type == Runtime::INLINE) {
InlineFunctionGenerator generator =
FindInlineFunctionGenerator(function->function_id);
if (generator != NULL) {
((*this).*(generator))(args);
return true;
}
}
@ -385,14 +380,6 @@ bool CodeGenerator::CheckForInlineRuntimeCall(CallRuntime* node) {
}
int CodeGenerator::InlineRuntimeCallArgumentsCount(Handle<String> name) {
CodeGenerator::InlineRuntimeLUT* f =
CodeGenerator::FindInlineRuntimeLUT(name);
if (f != NULL) return f->nargs;
return -1;
}
// Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
// known result for the test expression, with no side effects.
CodeGenerator::ConditionAnalysis CodeGenerator::AnalyzeCondition(

View File

@ -1,4 +1,4 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@ -71,48 +71,6 @@
// CodeForDoWhileConditionPosition
// CodeForSourcePosition
#define INLINE_RUNTIME_FUNCTION_LIST(F) \
F(IsSmi, 1, 1) \
F(IsNonNegativeSmi, 1, 1) \
F(IsArray, 1, 1) \
F(IsRegExp, 1, 1) \
F(CallFunction, -1 /* receiver + n args + function */, 1) \
F(IsConstructCall, 0, 1) \
F(ArgumentsLength, 0, 1) \
F(Arguments, 1, 1) \
F(ClassOf, 1, 1) \
F(ValueOf, 1, 1) \
F(SetValueOf, 2, 1) \
F(StringCharCodeAt, 2, 1) \
F(StringCharFromCode, 1, 1) \
F(StringCharAt, 2, 1) \
F(ObjectEquals, 2, 1) \
F(Log, 3, 1) \
F(RandomHeapNumber, 0, 1) \
F(IsObject, 1, 1) \
F(IsFunction, 1, 1) \
F(IsUndetectableObject, 1, 1) \
F(IsSpecObject, 1, 1) \
F(IsStringWrapperSafeForDefaultValueOf, 1, 1) \
F(StringAdd, 2, 1) \
F(SubString, 3, 1) \
F(StringCompare, 2, 1) \
F(RegExpExec, 4, 1) \
F(RegExpConstructResult, 3, 1) \
F(RegExpCloneResult, 1, 1) \
F(GetFromCache, 2, 1) \
F(NumberToString, 1, 1) \
F(SwapElements, 3, 1) \
F(MathPow, 2, 1) \
F(MathSin, 1, 1) \
F(MathCos, 1, 1) \
F(MathSqrt, 1, 1) \
F(IsRegExpEquivalent, 2, 1) \
F(HasCachedArrayIndex, 1, 1) \
F(GetCachedArrayIndex, 1, 1)
#if V8_TARGET_ARCH_IA32
#include "ia32/codegen-ia32.h"
#elif V8_TARGET_ARCH_X64

View File

@ -505,18 +505,36 @@ void FullCodeGenerator::SetSourcePosition(int pos) {
}
void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) {
Handle<String> name = expr->name();
SmartPointer<char> cstring = name->ToCString();
// Lookup table for code generators for special runtime calls which are
// generated inline.
#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \
&FullCodeGenerator::Emit##Name,
#define CHECK_EMIT_INLINE_CALL(name, x, y) \
if (strcmp("_"#name, *cstring) == 0) { \
Emit##name(expr->arguments()); \
return; \
}
INLINE_RUNTIME_FUNCTION_LIST(CHECK_EMIT_INLINE_CALL)
#undef CHECK_EMIT_INLINE_CALL
UNREACHABLE();
const FullCodeGenerator::InlineFunctionGenerator
FullCodeGenerator::kInlineFunctionGenerators[] = {
INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
};
#undef INLINE_FUNCTION_GENERATOR_ADDRESS
FullCodeGenerator::InlineFunctionGenerator
FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) {
return kInlineFunctionGenerators[
static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction)];
}
void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* node) {
ZoneList<Expression*>* args = node->arguments();
Handle<String> name = node->name();
Runtime::Function* function = node->function();
ASSERT(function != NULL);
ASSERT(function->intrinsic_type == Runtime::INLINE);
InlineFunctionGenerator generator =
FindInlineFunctionGenerator(function->function_id);
ASSERT(generator != NULL);
((*this).*(generator))(args);
}

View File

@ -243,6 +243,12 @@ class FullCodeGenerator: public AstVisitor {
kRightConstant
};
// Type of a member function that generates inline code for a native function.
typedef void (FullCodeGenerator::*InlineFunctionGenerator)
(ZoneList<Expression*>*);
static const InlineFunctionGenerator kInlineFunctionGenerators[];
// Compute the frame pointer relative offset for a given local or
// parameter slot.
int SlotOffset(Slot* slot);
@ -373,10 +379,13 @@ class FullCodeGenerator: public AstVisitor {
void EmitKeyedCallWithIC(Call* expr, Expression* key, RelocInfo::Mode mode);
// Platform-specific code for inline runtime calls.
InlineFunctionGenerator FindInlineFunctionGenerator(Runtime::FunctionId id);
void EmitInlineRuntimeCall(CallRuntime* expr);
#define EMIT_INLINE_RUNTIME_CALL(name, x, y) \
void Emit##name(ZoneList<Expression*>* arguments);
INLINE_FUNCTION_LIST(EMIT_INLINE_RUNTIME_CALL)
INLINE_RUNTIME_FUNCTION_LIST(EMIT_INLINE_RUNTIME_CALL)
#undef EMIT_INLINE_RUNTIME_CALL

View File

@ -31,7 +31,6 @@
#include "api.h"
#include "arguments.h"
#include "bootstrapper.h"
#include "codegen.h"
#include "compiler.h"
#include "debug.h"
#include "execution.h"

View File

@ -1,4 +1,4 @@
// Copyright 2009 the V8 project authors. All rights reserved.
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@ -1834,6 +1834,13 @@ bool Heap::CreateInitialObjects() {
CreateFixedStubs();
// Allocate the dictionary of intrinsic function names.
obj = StringDictionary::Allocate(Runtime::kNumFunctions);
if (obj->IsFailure()) return false;
obj = Runtime::InitializeIntrinsicFunctionNames(obj);
if (obj->IsFailure()) return false;
set_intrinsic_function_names(StringDictionary::cast(obj));
if (InitializeNumberStringCache()->IsFailure()) return false;
// Allocate cache for single character ASCII strings.

View File

@ -1,4 +1,4 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@ -114,6 +114,7 @@ namespace internal {
V(Object, last_script_id, LastScriptId) \
V(Script, empty_script, EmptyScript) \
V(Smi, real_stack_limit, RealStackLimit) \
V(StringDictionary, intrinsic_function_names, IntrinsicFunctionNames) \
#if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP
#define STRONG_ROOT_LIST(V) \

View File

@ -345,10 +345,6 @@ class CodeGenerator: public AstVisitor {
bool in_spilled_code() const { return in_spilled_code_; }
void set_in_spilled_code(bool flag) { in_spilled_code_ = flag; }
// If the name is an inline runtime function call return the number of
// expected arguments. Otherwise return -1.
static int InlineRuntimeCallArgumentsCount(Handle<String> name);
// Return a position of the element at |index_as_smi| + |additional_offset|
// in FixedArray pointer to which is held in |array|. |index_as_smi| is Smi.
static Operand FixedArrayElementOperand(Register array,
@ -363,6 +359,12 @@ class CodeGenerator: public AstVisitor {
}
private:
// Type of a member function that generates inline code for a native function.
typedef void (CodeGenerator::*InlineFunctionGenerator)
(ZoneList<Expression*>*);
static const InlineFunctionGenerator kInlineFunctionGenerators[];
// Construction/Destruction
explicit CodeGenerator(MacroAssembler* masm);
@ -624,13 +626,9 @@ class CodeGenerator: public AstVisitor {
void CheckStack();
struct InlineRuntimeLUT {
void (CodeGenerator::*method)(ZoneList<Expression*>*);
const char* name;
int nargs;
};
static InlineFunctionGenerator FindInlineFunctionGenerator(
Runtime::FunctionId function_id);
static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name);
bool CheckForInlineRuntimeCall(CallRuntime* node);
void ProcessDeclarations(ZoneList<Declaration*>* declarations);
@ -792,8 +790,6 @@ class CodeGenerator: public AstVisitor {
// in a spilled state.
bool in_spilled_code_;
static InlineRuntimeLUT kInlineRuntimeLUT[];
friend class VirtualFrame;
friend class JumpTarget;
friend class Reference;

View File

@ -4243,58 +4243,43 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
Expect(Token::MOD, CHECK_OK);
Handle<String> name = ParseIdentifier(CHECK_OK);
Runtime::Function* function =
Runtime::FunctionForName(scanner_.literal());
ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
if (function == NULL && extension_ != NULL) {
if (is_pre_parsing_) return NULL;
if (extension_ != NULL) {
// The extension structures are only accessible while parsing the
// very first time not when reparsing because of lazy compilation.
top_scope_->ForceEagerCompilation();
}
// Check for built-in macros.
if (!is_pre_parsing_) {
if (function == Runtime::FunctionForId(Runtime::kIS_VAR)) {
// %IS_VAR(x)
// evaluates to x if x is a variable,
// leads to a parse error otherwise
if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
return args->at(0);
}
*ok = false;
// Check here for other macros.
// } else if (function == Runtime::FunctionForId(Runtime::kIS_VAR)) {
// ...
}
Runtime::Function* function = Runtime::FunctionForSymbol(name);
if (!*ok) {
// We found a macro but it failed.
// Check for built-in IS_VAR macro.
if (function != NULL &&
function->intrinsic_type == Runtime::RUNTIME &&
function->function_id == Runtime::kIS_VAR) {
// %IS_VAR(x) evaluates to x if x is a variable,
// leads to a parse error otherwise. Could be implemented as an
// inline function %_IS_VAR(x) to eliminate this special case.
if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
return args->at(0);
} else {
ReportMessage("unable_to_parse", Vector<const char*>::empty());
return NULL;
}
}
// Check that the expected number arguments are passed to runtime functions.
if (!is_pre_parsing_) {
if (function != NULL
&& function->nargs != -1
&& function->nargs != args->length()) {
ReportMessage("illegal_access", Vector<const char*>::empty());
*ok = false;
return NULL;
} else if (function == NULL && !name.is_null()) {
// If this is not a runtime function implemented in C++ it might be an
// inlined runtime function.
int argc = CodeGenerator::InlineRuntimeCallArgumentsCount(name);
if (argc != -1 && argc != args->length()) {
ReportMessage("illegal_access", Vector<const char*>::empty());
*ok = false;
return NULL;
}
}
}
// Otherwise we have a valid runtime call.
// Check that the expected number of arguments are being passed.
if (function != NULL &&
function->nargs != -1 &&
function->nargs != args->length()) {
ReportMessage("illegal_access", Vector<const char*>::empty());
*ok = false;
return NULL;
}
// We have a valid intrinsics call or a call to a builtin.
return NEW(CallRuntime(name, function, args));
}

View File

@ -4519,7 +4519,6 @@ static Object* Runtime_StringParseInt(Arguments args) {
RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
double value = StringToInt(s, radix);
return Heap::NumberFromDouble(value);
return Heap::nan_value();
}
@ -10064,6 +10063,7 @@ static Object* Runtime_ListNatives(Arguments args) {
inline_runtime_functions = false;
RUNTIME_FUNCTION_LIST(ADD_ENTRY)
inline_runtime_functions = true;
INLINE_FUNCTION_LIST(ADD_ENTRY)
INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY)
#undef ADD_ENTRY
return *result;
@ -10090,35 +10090,58 @@ static Object* Runtime_IS_VAR(Arguments args) {
// ----------------------------------------------------------------------------
// Implementation of Runtime
#define F(name, nargs, ressize) \
{ #name, FUNCTION_ADDR(Runtime_##name), nargs, \
static_cast<int>(Runtime::k##name), ressize },
#define F(name, number_of_args, result_size) \
{ Runtime::k##name, Runtime::RUNTIME, #name, \
FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
static Runtime::Function Runtime_functions[] = {
#define I(name, number_of_args, result_size) \
{ Runtime::kInline##name, Runtime::INLINE, \
"_" #name, NULL, number_of_args, result_size },
Runtime::Function kIntrinsicFunctions[] = {
RUNTIME_FUNCTION_LIST(F)
{ NULL, NULL, 0, -1, 0 }
INLINE_FUNCTION_LIST(I)
INLINE_RUNTIME_FUNCTION_LIST(I)
};
#undef F
const int Runtime::kNotFound;
Runtime::Function* Runtime::FunctionForId(FunctionId fid) {
ASSERT(0 <= fid && fid < kNofFunctions);
return &Runtime_functions[fid];
Object* Runtime::InitializeIntrinsicFunctionNames(Object* dictionary) {
ASSERT(dictionary != NULL);
ASSERT(StringDictionary::cast(dictionary)->NumberOfElements() == 0);
for (int i = 0; i < kNumFunctions; ++i) {
Object* name_symbol = Heap::LookupAsciiSymbol(kIntrinsicFunctions[i].name);
if (name_symbol->IsFailure()) return name_symbol;
StringDictionary* string_dictionary = StringDictionary::cast(dictionary);
dictionary = string_dictionary->Add(String::cast(name_symbol),
Smi::FromInt(i),
PropertyDetails(NONE, NORMAL));
// Non-recoverable failure. Calling code must restart heap initialization.
if (dictionary->IsFailure()) return dictionary;
}
return dictionary;
}
Runtime::Function* Runtime::FunctionForName(Vector<const char> name) {
for (Function* f = Runtime_functions; f->name != NULL; f++) {
if (strncmp(f->name, name.start(), name.length()) == 0
&& f->name[name.length()] == 0) {
return f;
}
Runtime::Function* Runtime::FunctionForSymbol(Handle<String> name) {
int entry = Heap::intrinsic_function_names()->FindEntry(*name);
if (entry != kNotFound) {
Object* smi_index = Heap::intrinsic_function_names()->ValueAt(entry);
int function_index = Smi::cast(smi_index)->value();
return &(kIntrinsicFunctions[function_index]);
}
return NULL;
}
Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
return &(kIntrinsicFunctions[static_cast<int>(id)]);
}
void Runtime::PerformGC(Object* result) {
Failure* failure = Failure::cast(result);
if (failure->IsRetryAfterGC()) {

View File

@ -1,4 +1,4 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@ -389,6 +389,59 @@ namespace internal {
RUNTIME_FUNCTION_LIST_PROFILER_SUPPORT(F)
// ----------------------------------------------------------------------------
// INLINE_FUNCTION_LIST defines all inlined functions accessed
// with a native call of the form %_name from within JS code.
// Entries have the form F(name, number of arguments, number of return values).
#define INLINE_FUNCTION_LIST(F) \
F(IsSmi, 1, 1) \
F(IsNonNegativeSmi, 1, 1) \
F(IsArray, 1, 1) \
F(IsRegExp, 1, 1) \
F(CallFunction, -1 /* receiver + n args + function */, 1) \
F(ArgumentsLength, 0, 1) \
F(Arguments, 1, 1) \
F(ValueOf, 1, 1) \
F(SetValueOf, 2, 1) \
F(StringCharFromCode, 1, 1) \
F(StringCharAt, 2, 1) \
F(ObjectEquals, 2, 1) \
F(RandomHeapNumber, 0, 1) \
F(IsObject, 1, 1) \
F(IsFunction, 1, 1) \
F(IsUndetectableObject, 1, 1) \
F(IsSpecObject, 1, 1) \
F(IsStringWrapperSafeForDefaultValueOf, 1, 1) \
F(MathPow, 2, 1) \
F(MathSin, 1, 1) \
F(MathCos, 1, 1) \
F(MathSqrt, 1, 1) \
F(IsRegExpEquivalent, 2, 1) \
F(HasCachedArrayIndex, 1, 1) \
F(GetCachedArrayIndex, 1, 1)
// ----------------------------------------------------------------------------
// INLINE_AND_RUNTIME_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 for slow cases.
// Entries have the form F(name, number of arguments, number of return values).
#define INLINE_RUNTIME_FUNCTION_LIST(F) \
F(IsConstructCall, 0, 1) \
F(ClassOf, 1, 1) \
F(StringCharCodeAt, 2, 1) \
F(Log, 3, 1) \
F(StringAdd, 2, 1) \
F(SubString, 3, 1) \
F(StringCompare, 2, 1) \
F(RegExpExec, 4, 1) \
F(RegExpConstructResult, 3, 1) \
F(RegExpCloneResult, 1, 1) \
F(GetFromCache, 2, 1) \
F(NumberToString, 1, 1) \
F(SwapElements, 3, 1)
//---------------------------------------------------------------------------
// Runtime provides access to all C++ runtime functions.
class Runtime : public AllStatic {
@ -396,33 +449,52 @@ class Runtime : public AllStatic {
enum FunctionId {
#define F(name, nargs, ressize) k##name,
RUNTIME_FUNCTION_LIST(F)
kNofFunctions
#undef F
#define F(name, nargs, ressize) kInline##name,
INLINE_FUNCTION_LIST(F)
INLINE_RUNTIME_FUNCTION_LIST(F)
#undef F
kNumFunctions,
kFirstInlineFunction = kInlineIsSmi
};
// Runtime function descriptor.
enum IntrinsicType {
RUNTIME,
INLINE
};
// Intrinsic function descriptor.
struct Function {
FunctionId function_id;
IntrinsicType intrinsic_type;
// The JS name of the function.
const char* name;
// The C++ (native) entry point.
// The C++ (native) entry point. NULL if the function is inlined.
byte* entry;
// The number of arguments expected; nargs < 0 if variable no. of
// arguments.
// The number of arguments expected. nargs is -1 if the function takes
// a variable number of arguments.
int nargs;
int stub_id;
// Size of result, if complex (larger than a single pointer),
// otherwise zero.
// Size of result. Most functions return a single pointer, size 1.
int result_size;
};
// Get the runtime function with the given function id.
static Function* FunctionForId(FunctionId fid);
static const int kNotFound = -1;
// Get the runtime function with the given name.
static Function* FunctionForName(Vector<const char> name);
// Add symbols for all the intrinsic function names to a StringDictionary.
// Returns failure if an allocation fails. In this case, it must be
// retried with a new, empty StringDictionary, not with the same one.
// Alternatively, heap initialization can be completely restarted.
static Object* InitializeIntrinsicFunctionNames(Object* dictionary);
// Get the intrinsic function with the given name, which must be a symbol.
static Function* FunctionForSymbol(Handle<String> name);
// Get the intrinsic function with the given FunctionId.
static Function* FunctionForId(FunctionId id);
// General-purpose helper functions for runtime system.
static int StringMatch(Handle<String> sub, Handle<String> pat, int index);
static bool IsUpperCaseChar(uint16_t ch);

View File

@ -343,15 +343,17 @@ class CodeGenerator: public AstVisitor {
bool in_spilled_code() const { return in_spilled_code_; }
void set_in_spilled_code(bool flag) { in_spilled_code_ = flag; }
// If the name is an inline runtime function call return the number of
// expected arguments. Otherwise return -1.
static int InlineRuntimeCallArgumentsCount(Handle<String> name);
static Operand ContextOperand(Register context, int index) {
return Operand(context, Context::SlotOffset(index));
}
private:
// Type of a member function that generates inline code for a native function.
typedef void (CodeGenerator::*InlineFunctionGenerator)
(ZoneList<Expression*>*);
static const InlineFunctionGenerator kInlineFunctionGenerators[];
// Construction/Destruction
explicit CodeGenerator(MacroAssembler* masm);
@ -584,12 +586,9 @@ class CodeGenerator: public AstVisitor {
void CheckStack();
struct InlineRuntimeLUT {
void (CodeGenerator::*method)(ZoneList<Expression*>*);
const char* name;
int nargs;
};
static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name);
static InlineFunctionGenerator FindInlineFunctionGenerator(
Runtime::FunctionId function_id);
bool CheckForInlineRuntimeCall(CallRuntime* node);
void ProcessDeclarations(ZoneList<Declaration*>* declarations);
@ -742,8 +741,6 @@ class CodeGenerator: public AstVisitor {
// in a spilled state.
bool in_spilled_code_;
static InlineRuntimeLUT kInlineRuntimeLUT[];
friend class VirtualFrame;
friend class JumpTarget;
friend class Reference;