Revision: 5451
Author: [email protected]
Date: Tue Sep 14 07:52:53 2010
Log: Move inlined function declarations and support from codegen.* to
runtime.*.
Review URL: http://codereview.chromium.org/3293002
http://code.google.com/p/v8/source/detail?r=5451
Modified:
/branches/bleeding_edge/src/arm/codegen-arm.h
/branches/bleeding_edge/src/codegen.cc
/branches/bleeding_edge/src/codegen.h
/branches/bleeding_edge/src/full-codegen.cc
/branches/bleeding_edge/src/full-codegen.h
/branches/bleeding_edge/src/handles.cc
/branches/bleeding_edge/src/heap.cc
/branches/bleeding_edge/src/heap.h
/branches/bleeding_edge/src/ia32/codegen-ia32.h
/branches/bleeding_edge/src/parser.cc
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/runtime.h
/branches/bleeding_edge/src/x64/codegen-x64.h
=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.h Wed Sep 1 06:13:31 2010
+++ /branches/bleeding_edge/src/arm/codegen-arm.h Tue Sep 14 07:52:53 2010
@@ -270,10 +270,6 @@
}
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() {
@@ -290,6 +286,12 @@
}
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 @@
void Branch(bool if_true, JumpTarget* target);
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);
static Handle<Code> ComputeLazyCompile(int argc);
@@ -599,8 +597,6 @@
// 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;
=======================================
--- /branches/bleeding_edge/src/codegen.cc Wed Sep 1 06:13:31 2010
+++ /branches/bleeding_edge/src/codegen.cc Tue Sep 14 07:52:53 2010
@@ -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,53 +344,40 @@
}
-// 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.
-
-#define INLINE_RUNTIME_ENTRY(Name, argc,
ressize) \
- {&CodeGenerator::Generate##Name, "_" #Name,
argc}, \
-
-CodeGenerator::InlineRuntimeLUT CodeGenerator::kInlineRuntimeLUT[] = {
- INLINE_RUNTIME_FUNCTION_LIST(INLINE_RUNTIME_ENTRY)
+// Lookup table for code generators for special runtime calls which are
+// generated inline.
+#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \
+ &CodeGenerator::Generate##Name,
+
+const CodeGenerator::InlineFunctionGenerator
+ CodeGenerator::kInlineFunctionGenerators[] = {
+ INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
+ INLINE_RUNTIME_FUNCTION_LIST(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;
+#undef INLINE_FUNCTION_GENERATOR_ADDRESS
+
+
+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;
}
}
return false;
}
-
-
-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
=======================================
--- /branches/bleeding_edge/src/codegen.h Wed Sep 1 06:13:31 2010
+++ /branches/bleeding_edge/src/codegen.h Tue Sep 14 07:52:53 2010
@@ -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
=======================================
--- /branches/bleeding_edge/src/full-codegen.cc Thu Sep 9 03:44:24 2010
+++ /branches/bleeding_edge/src/full-codegen.cc Tue Sep 14 07:52:53 2010
@@ -505,18 +505,36 @@
}
-void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) {
- Handle<String> name = expr->name();
- SmartPointer<char> cstring = name->ToCString();
-
-#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();
+// 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)
+ 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);
}
=======================================
--- /branches/bleeding_edge/src/full-codegen.h Fri Sep 10 03:57:07 2010
+++ /branches/bleeding_edge/src/full-codegen.h Tue Sep 14 07:52:53 2010
@@ -243,6 +243,12 @@
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 @@
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
=======================================
--- /branches/bleeding_edge/src/handles.cc Tue Aug 17 04:44:01 2010
+++ /branches/bleeding_edge/src/handles.cc Tue Sep 14 07:52:53 2010
@@ -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"
=======================================
--- /branches/bleeding_edge/src/heap.cc Mon Aug 30 05:34:32 2010
+++ /branches/bleeding_edge/src/heap.cc Tue Sep 14 07:52:53 2010
@@ -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 @@
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.
=======================================
--- /branches/bleeding_edge/src/heap.h Tue Aug 31 01:05:42 2010
+++ /branches/bleeding_edge/src/heap.h Tue Sep 14 07:52:53 2010
@@ -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 @@
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) \
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.h Wed Sep 1 06:13:31 2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.h Tue Sep 14 07:52:53 2010
@@ -344,10 +344,6 @@
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.
@@ -363,6 +359,12 @@
}
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 @@
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);
@@ -792,8 +790,6 @@
// in a spilled state.
bool in_spilled_code_;
- static InlineRuntimeLUT kInlineRuntimeLUT[];
-
friend class VirtualFrame;
friend class JumpTarget;
friend class Reference;
=======================================
--- /branches/bleeding_edge/src/parser.cc Thu Sep 9 04:49:21 2010
+++ /branches/bleeding_edge/src/parser.cc Tue Sep 14 07:52:53 2010
@@ -4243,58 +4243,43 @@
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)) {
- // ...
- }
-
- if (!*ok) {
- // We found a macro but it failed.
+ Runtime::Function* function = Runtime::FunctionForSymbol(name);
+
+ // 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());
+ *ok = false;
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;
- }
- }
+ // 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;
}
- // Otherwise we have a valid runtime call.
+ // We have a valid intrinsics call or a call to a builtin.
return NEW(CallRuntime(name, function, args));
}
=======================================
--- /branches/bleeding_edge/src/runtime.cc Fri Sep 10 02:22:41 2010
+++ /branches/bleeding_edge/src/runtime.cc Tue Sep 14 07:52:53 2010
@@ -4519,7 +4519,6 @@
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 @@
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,33 +10090,56 @@
//
----------------------------------------------------------------------------
// Implementation of Runtime
-#define F(name, nargs, ressize) \
- { #name, FUNCTION_ADDR(Runtime_##name), nargs, \
- static_cast<int>(Runtime::k##name), ressize },
-
-static Runtime::Function Runtime_functions[] = {
+#define F(name, number_of_args, result_size) \
+ { Runtime::k##name, Runtime::RUNTIME, #name, \
+ FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
+
+
+#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
-
-
-Runtime::Function* Runtime::FunctionForId(FunctionId fid) {
- ASSERT(0 <= fid && fid < kNofFunctions);
- return &Runtime_functions[fid];
+
+const int Runtime::kNotFound;
+
+
+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) {
=======================================
--- /branches/bleeding_edge/src/runtime.h Thu Aug 26 06:59:37 2010
+++ /branches/bleeding_edge/src/runtime.h Tue Sep 14 07:52:53 2010
@@ -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 @@
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 @@
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);
-
- // Get the runtime function with the given name.
- static Function* FunctionForName(Vector<const char> name);
-
+ static const int kNotFound = -1;
+
+ // 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);
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.h Wed Sep 1 06:13:31 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.h Tue Sep 14 07:52:53 2010
@@ -342,16 +342,18 @@
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 @@
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 @@
// in a spilled state.
bool in_spilled_code_;
- static InlineRuntimeLUT kInlineRuntimeLUT[];
-
friend class VirtualFrame;
friend class JumpTarget;
friend class Reference;
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev