Revision: 4606
Author: [email protected]
Date: Thu May 6 06:21:53 2010
Log: Refactored custom call IC generators:
* All generators are listed in a single place.
* Generators are installed as a separate pass in the bootstrapper.
* Replaced pointers to generator functions with integer ids.
Review URL: http://codereview.chromium.org/1981002
http://code.google.com/p/v8/source/detail?r=4606
Modified:
/branches/bleeding_edge/src/arm/stub-cache-arm.cc
/branches/bleeding_edge/src/assembler.cc
/branches/bleeding_edge/src/assembler.h
/branches/bleeding_edge/src/bootstrapper.cc
/branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/serialize.cc
/branches/bleeding_edge/src/stub-cache.cc
/branches/bleeding_edge/src/stub-cache.h
/branches/bleeding_edge/src/x64/stub-cache-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Tue May 4 23:40:14
2010
+++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Thu May 6 06:21:53
2010
@@ -1121,11 +1121,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- String* function_name = NULL;
- if (function->shared()->name()->IsString()) {
- function_name = String::cast(function->shared()->name());
- }
- return GetCode(CONSTANT_FUNCTION, function_name);
+ return GetCode(function);
}
@@ -1175,11 +1171,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- String* function_name = NULL;
- if (function->shared()->name()->IsString()) {
- function_name = String::cast(function->shared()->name());
- }
- return GetCode(CONSTANT_FUNCTION, function_name);
+ return GetCode(function);
}
@@ -1194,9 +1186,9 @@
// -----------------------------------
SharedFunctionInfo* function_info = function->shared();
if (function_info->HasCustomCallGenerator()) {
- CustomCallGenerator generator =
- ToCData<CustomCallGenerator>(function_info->function_data());
- Object* result = generator(this, object, holder, function, name,
check);
+ const int id = function_info->custom_call_generator_id();
+ Object* result =
+ CompileCustomCall(id, object, holder, function, name, check);
// undefined means bail out to regular compiler.
if (!result->IsUndefined()) {
return result;
@@ -1334,11 +1326,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- String* function_name = NULL;
- if (function->shared()->name()->IsString()) {
- function_name = String::cast(function->shared()->name());
- }
- return GetCode(CONSTANT_FUNCTION, function_name);
+ return GetCode(function);
}
=======================================
--- /branches/bleeding_edge/src/assembler.cc Mon Apr 19 12:30:11 2010
+++ /branches/bleeding_edge/src/assembler.cc Thu May 6 06:21:53 2010
@@ -668,16 +668,6 @@
ExternalReference ExternalReference::scheduled_exception_address() {
return ExternalReference(Top::scheduled_exception_address());
}
-
-
-ExternalReference ExternalReference::compile_array_pop_call() {
- return ExternalReference(FUNCTION_ADDR(CompileArrayPopCall));
-}
-
-
-ExternalReference ExternalReference::compile_array_push_call() {
- return ExternalReference(FUNCTION_ADDR(CompileArrayPushCall));
-}
#ifndef V8_INTERPRETED_REGEXP
=======================================
--- /branches/bleeding_edge/src/assembler.h Mon Apr 19 12:30:11 2010
+++ /branches/bleeding_edge/src/assembler.h Thu May 6 06:21:53 2010
@@ -444,9 +444,6 @@
static ExternalReference scheduled_exception_address();
- static ExternalReference compile_array_pop_call();
- static ExternalReference compile_array_push_call();
-
Address address() const {return reinterpret_cast<Address>(address_);}
#ifdef ENABLE_DEBUGGER_SUPPORT
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Tue May 4 09:42:11 2010
+++ /branches/bleeding_edge/src/bootstrapper.cc Thu May 6 06:21:53 2010
@@ -37,6 +37,7 @@
#include "macro-assembler.h"
#include "natives.h"
#include "snapshot.h"
+#include "stub-cache.h"
namespace v8 {
namespace internal {
@@ -228,6 +229,7 @@
// Used for creating a context from scratch.
void InstallNativeFunctions();
bool InstallNatives();
+ void InstallCustomCallGenerators();
void InstallJSFunctionResultCaches();
// Used both for deserialized and from-scratch contexts to add the
extensions
// provided.
@@ -1229,6 +1231,8 @@
InstallNativeFunctions();
+ InstallCustomCallGenerators();
+
// Install Function.prototype.call and apply.
{ Handle<String> key = Factory::function_class_symbol();
Handle<JSFunction> function =
@@ -1324,6 +1328,29 @@
return true;
}
+
+
+static void InstallCustomCallGenerator(Handle<JSFunction> holder_function,
+ const char* function_name,
+ int id) {
+ Handle<JSObject>
proto(JSObject::cast(holder_function->instance_prototype()));
+ Handle<String> name = Factory::LookupAsciiSymbol(function_name);
+ Handle<JSFunction> function(JSFunction::cast(proto->GetProperty(*name)));
+ function->shared()->set_function_data(Smi::FromInt(id));
+}
+
+
+void Genesis::InstallCustomCallGenerators() {
+ HandleScope scope;
+#define INSTALL_CALL_GENERATOR(holder_fun, fun_name, name) \
+ { \
+ Handle<JSFunction> holder(global_context()->holder_fun##_function()); \
+ const int id = CallStubCompiler::k##name##CallGenerator; \
+ InstallCustomCallGenerator(holder, #fun_name, id); \
+ }
+ CUSTOM_CALL_IC_GENERATORS(INSTALL_CALL_GENERATOR)
+#undef INSTALL_CALL_GENERATOR
+}
// Do not forget to update macros.py with named constant
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Tue May 4 07:49:50
2010
+++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Thu May 6 06:21:53
2010
@@ -1264,16 +1264,11 @@
}
__ bind(&miss);
-
Handle<Code> ic = ComputeCallMiss(arguments().immediate());
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- String* function_name = NULL;
- if (function->shared()->name()->IsString()) {
- function_name = String::cast(function->shared()->name());
- }
- return GetCode(CONSTANT_FUNCTION, function_name);
+ return GetCode(function);
}
@@ -1351,16 +1346,11 @@
1);
__ bind(&miss);
-
Handle<Code> ic = ComputeCallMiss(arguments().immediate());
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- String* function_name = NULL;
- if (function->shared()->name()->IsString()) {
- function_name = String::cast(function->shared()->name());
- }
- return GetCode(CONSTANT_FUNCTION, function_name);
+ return GetCode(function);
}
@@ -1379,9 +1369,9 @@
SharedFunctionInfo* function_info = function->shared();
if (function_info->HasCustomCallGenerator()) {
- CustomCallGenerator generator =
- ToCData<CustomCallGenerator>(function_info->function_data());
- Object* result = generator(this, object, holder, function, name,
check);
+ const int id = function_info->custom_call_generator_id();
+ Object* result =
+ CompileCustomCall(id, object, holder, function, name, check);
// undefined means bail out to regular compiler.
if (!result->IsUndefined()) {
return result;
@@ -1518,11 +1508,7 @@
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- String* function_name = NULL;
- if (function->shared()->name()->IsString()) {
- function_name = String::cast(function->shared()->name());
- }
- return GetCode(CONSTANT_FUNCTION, function_name);
+ return GetCode(function);
}
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Tue May 4 09:42:11 2010
+++ /branches/bleeding_edge/src/objects-inl.h Thu May 6 06:21:53 2010
@@ -2530,7 +2530,13 @@
bool SharedFunctionInfo::HasCustomCallGenerator() {
- return function_data()->IsProxy();
+ return function_data()->IsSmi();
+}
+
+
+int SharedFunctionInfo::custom_call_generator_id() {
+ ASSERT(HasCustomCallGenerator());
+ return Smi::cast(function_data())->value();
}
=======================================
--- /branches/bleeding_edge/src/objects.h Tue May 4 09:42:11 2010
+++ /branches/bleeding_edge/src/objects.h Thu May 6 06:21:53 2010
@@ -3200,7 +3200,7 @@
// [function data]: This field holds some additional data for function.
// Currently it either has FunctionTemplateInfo to make benefit the API
- // or Proxy wrapping CustomCallGenerator.
+ // or Smi identifying a custom call generator.
// In the long run we don't want all functions to have this field but
// we can fix that when we have a better model for storing hidden data
// on objects.
@@ -3209,6 +3209,7 @@
inline bool IsApiFunction();
inline FunctionTemplateInfo* get_api_func_data();
inline bool HasCustomCallGenerator();
+ inline int custom_call_generator_id();
// [script info]: Script from which the function originates.
DECL_ACCESSORS(script, Object)
=======================================
--- /branches/bleeding_edge/src/runtime.cc Tue May 4 10:24:41 2010
+++ /branches/bleeding_edge/src/runtime.cc Thu May 6 06:21:53 2010
@@ -1323,20 +1323,11 @@
prototype->set_elements(Heap::empty_fixed_array());
return Smi::FromInt(0);
}
-
-
-static void SetCustomCallGenerator(Handle<JSFunction> function,
- ExternalReference* generator) {
- if (function->shared()->function_data()->IsUndefined()) {
-
function->shared()->set_function_data(*FromCData(generator->address()));
- }
-}
static Handle<JSFunction> InstallBuiltin(Handle<JSObject> holder,
const char* name,
- Builtins::Name builtin_name,
- ExternalReference* generator =
NULL) {
+ Builtins::Name builtin_name) {
Handle<String> key = Factory::LookupAsciiSymbol(name);
Handle<Code> code(Builtins::builtin(builtin_name));
Handle<JSFunction> optimized = Factory::NewFunction(key,
@@ -1345,32 +1336,9 @@
code,
false);
optimized->shared()->DontAdaptArguments();
- if (generator != NULL) {
- SetCustomCallGenerator(optimized, generator);
- }
SetProperty(holder, key, optimized, NONE);
return optimized;
}
-
-
-Object* CompileArrayPushCall(CallStubCompiler* compiler,
- Object* object,
- JSObject* holder,
- JSFunction* function,
- String* name,
- StubCompiler::CheckType check) {
- return compiler->CompileArrayPushCall(object, holder, function, name,
check);
-}
-
-
-Object* CompileArrayPopCall(CallStubCompiler* compiler,
- Object* object,
- JSObject* holder,
- JSFunction* function,
- String* name,
- StubCompiler::CheckType check) {
- return compiler->CompileArrayPopCall(object, holder, function, name,
check);
-}
static Object* Runtime_SpecialArrayFunctions(Arguments args) {
@@ -1378,11 +1346,8 @@
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSObject, holder, 0);
- ExternalReference pop = ExternalReference::compile_array_pop_call();
- ExternalReference push = ExternalReference::compile_array_push_call();
-
- InstallBuiltin(holder, "pop", Builtins::ArrayPop, &pop);
- InstallBuiltin(holder, "push", Builtins::ArrayPush, &push);
+ InstallBuiltin(holder, "pop", Builtins::ArrayPop);
+ InstallBuiltin(holder, "push", Builtins::ArrayPush);
InstallBuiltin(holder, "shift", Builtins::ArrayShift);
InstallBuiltin(holder, "unshift", Builtins::ArrayUnshift);
InstallBuiltin(holder, "slice", Builtins::ArraySlice);
=======================================
--- /branches/bleeding_edge/src/serialize.cc Thu Apr 22 05:41:10 2010
+++ /branches/bleeding_edge/src/serialize.cc Thu May 6 06:21:53 2010
@@ -414,44 +414,36 @@
UNCLASSIFIED,
19,
"compare_doubles");
- Add(ExternalReference::compile_array_pop_call().address(),
- UNCLASSIFIED,
- 20,
- "compile_array_pop");
- Add(ExternalReference::compile_array_push_call().address(),
- UNCLASSIFIED,
- 21,
- "compile_array_push");
#ifndef V8_INTERPRETED_REGEXP
Add(ExternalReference::re_case_insensitive_compare_uc16().address(),
UNCLASSIFIED,
- 22,
+ 20,
"NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16()");
Add(ExternalReference::re_check_stack_guard_state().address(),
UNCLASSIFIED,
- 23,
+ 21,
"RegExpMacroAssembler*::CheckStackGuardState()");
Add(ExternalReference::re_grow_stack().address(),
UNCLASSIFIED,
- 24,
+ 22,
"NativeRegExpMacroAssembler::GrowStack()");
Add(ExternalReference::re_word_character_map().address(),
UNCLASSIFIED,
- 25,
+ 23,
"NativeRegExpMacroAssembler::word_character_map");
#endif // V8_INTERPRETED_REGEXP
// Keyed lookup cache.
Add(ExternalReference::keyed_lookup_cache_keys().address(),
UNCLASSIFIED,
- 26,
+ 24,
"KeyedLookupCache::keys()");
Add(ExternalReference::keyed_lookup_cache_field_offsets().address(),
UNCLASSIFIED,
- 27,
+ 25,
"KeyedLookupCache::field_offsets()");
Add(ExternalReference::transcendental_cache_array_address().address(),
UNCLASSIFIED,
- 28,
+ 26,
"TranscendentalCache::caches()");
}
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc Wed Apr 28 07:06:35 2010
+++ /branches/bleeding_edge/src/stub-cache.cc Thu May 6 06:21:53 2010
@@ -1140,6 +1140,29 @@
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC,
type);
return GetCodeWithFlags(flags, name);
}
+
+
+Object* CallStubCompiler::CompileCustomCall(int generator_id,
+ Object* object,
+ JSObject* holder,
+ JSFunction* function,
+ String* fname,
+ CheckType check) {
+ ASSERT(generator_id >= 0 && generator_id < kNumCallGenerators);
+ switch (generator_id) {
+#define CALL_GENERATOR_CASE(ignored1, ignored2, name) \
+ case k##name##CallGenerator: \
+ return CallStubCompiler::Compile##name##Call(object, \
+ holder, \
+ function, \
+ fname, \
+ check);
+ CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
+#undef CALL_GENERATOR_CASE
+ }
+ UNREACHABLE();
+ return Heap::undefined_value();
+}
Object* CallStubCompiler::GetCode(PropertyType type, String* name) {
@@ -1150,6 +1173,15 @@
argc);
return GetCodeWithFlags(flags, name);
}
+
+
+Object* CallStubCompiler::GetCode(JSFunction* function) {
+ String* function_name = NULL;
+ if (function->shared()->name()->IsString()) {
+ function_name = String::cast(function->shared()->name());
+ }
+ return GetCode(CONSTANT_FUNCTION, function_name);
+}
Object* ConstructStubCompiler::GetCode() {
=======================================
--- /branches/bleeding_edge/src/stub-cache.h Wed Apr 28 07:06:35 2010
+++ /branches/bleeding_edge/src/stub-cache.h Thu May 6 06:21:53 2010
@@ -559,8 +559,30 @@
};
+// List of functions with custom constant call IC stubs.
+//
+// Installation of custom call generators for the selected builtins is
+// handled by the bootstrapper.
+//
+// Each entry has a name of a global function (lowercased), a name of
+// a builtin function on its instance prototype (the one the generator
+// is set for), and a name of a generator itself (used to build ids
+// and generator function names).
+#define CUSTOM_CALL_IC_GENERATORS(V) \
+ V(array, push, ArrayPush) \
+ V(array, pop, ArrayPop)
+
+
class CallStubCompiler: public StubCompiler {
public:
+ enum {
+#define DECLARE_CALL_GENERATOR_ID(ignored1, ignored2, name) \
+ k##name##CallGenerator,
+ CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR_ID)
+#undef DECLARE_CALL_GENERATOR_ID
+ kNumCallGenerators
+ };
+
CallStubCompiler(int argc, InLoopFlag in_loop)
: arguments_(argc), in_loop_(in_loop) { }
@@ -582,17 +604,22 @@
JSFunction* function,
String* name);
- Object* CompileArrayPushCall(Object* object,
- JSObject* holder,
- JSFunction* function,
- String* name,
- CheckType check);
-
- Object* CompileArrayPopCall(Object* object,
- JSObject* holder,
- JSFunction* function,
- String* name,
+ // Compiles a custom call constant IC using the generator with given id.
+ Object* CompileCustomCall(int generator_id,
+ Object* object,
+ JSObject* holder,
+ JSFunction* function,
+ String* name,
+ CheckType check);
+
+#define DECLARE_CALL_GENERATOR(ignored1, ignored2, name) \
+ Object* Compile##name##Call(Object* object, \
+ JSObject* holder, \
+ JSFunction* function, \
+ String* fname, \
CheckType check);
+ CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR)
+#undef DECLARE_CALL_GENERATOR
private:
const ParameterCount arguments_;
@@ -601,6 +628,10 @@
const ParameterCount& arguments() { return arguments_; }
Object* GetCode(PropertyType type, String* name);
+
+ // Convenience function. Calls GetCode above passing
+ // CONSTANT_FUNCTION type and the name of the given function.
+ Object* GetCode(JSFunction* function);
};
@@ -663,31 +694,6 @@
CallHandlerInfo* api_call_info_;
};
-
-typedef Object* (*CustomCallGenerator)(CallStubCompiler* compiler,
- Object* object,
- JSObject* holder,
- JSFunction* function,
- String* name,
- StubCompiler::CheckType check);
-
-
-Object* CompileArrayPushCall(CallStubCompiler* compiler,
- Object* object,
- JSObject* holder,
- JSFunction* function,
- String* name,
- StubCompiler::CheckType check);
-
-
-Object* CompileArrayPopCall(CallStubCompiler* compiler,
- Object* object,
- JSObject* holder,
- JSFunction* function,
- String* name,
- StubCompiler::CheckType check);
-
-
} } // namespace v8::internal
#endif // V8_STUB_CACHE_H_
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Tue May 4 07:49:50
2010
+++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Thu May 6 06:21:53
2010
@@ -870,9 +870,9 @@
SharedFunctionInfo* function_info = function->shared();
if (function_info->HasCustomCallGenerator()) {
- CustomCallGenerator generator =
- ToCData<CustomCallGenerator>(function_info->function_data());
- Object* result = generator(this, object, holder, function, name,
check);
+ const int id = function_info->custom_call_generator_id();
+ Object* result =
+ CompileCustomCall(id, object, holder, function, name, check);
// undefined means bail out to regular compiler.
if (!result->IsUndefined()) {
return result;
@@ -1007,11 +1007,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- String* function_name = NULL;
- if (function->shared()->name()->IsString()) {
- function_name = String::cast(function->shared()->name());
- }
- return GetCode(CONSTANT_FUNCTION, function_name);
+ return GetCode(function);
}
@@ -1219,11 +1215,7 @@
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- String* function_name = NULL;
- if (function->shared()->name()->IsString()) {
- function_name = String::cast(function->shared()->name());
- }
- return GetCode(CONSTANT_FUNCTION, function_name);
+ return GetCode(function);
}
@@ -1308,11 +1300,7 @@
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- String* function_name = NULL;
- if (function->shared()->name()->IsString()) {
- function_name = String::cast(function->shared()->name());
- }
- return GetCode(CONSTANT_FUNCTION, function_name);
+ return GetCode(function);
}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev