Commit 6b60546b authored by verwaest@chromium.org's avatar verwaest@chromium.org

Remove ArrayPush from the custom call generators, and instead call directly to...

Remove ArrayPush from the custom call generators, and instead call directly to the handler in crankshaft.

R=mvstanton@chromium.org

Review URL: https://codereview.chromium.org/137693003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18790 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 033174ab
......@@ -427,6 +427,21 @@ void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
descriptor->param_representations_ = representations;
descriptor->platform_specific_descriptor_ = &noInlineDescriptor;
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::CallHandler);
static Register registers[] = { cp, // context
r0, // receiver
};
static Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // receiver
};
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->param_representations_ = representations;
descriptor->platform_specific_descriptor_ = &default_descriptor;
}
}
......
......@@ -7659,6 +7659,41 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
return true;
}
case kArrayPush: {
if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) {
return false;
}
if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
ElementsKind elements_kind = receiver_map->elements_kind();
if (!IsFastElementsKind(elements_kind)) return false;
AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
HValue* op_vals[] = {
context(),
// Receiver.
environment()->ExpressionStackAt(expr->arguments()->length())
};
const int argc = expr->arguments()->length();
// Includes receiver.
PushArgumentsFromEnvironment(argc + 1);
CallInterfaceDescriptor* descriptor =
isolate()->call_descriptor(Isolate::CallHandler);
ArrayPushStub stub(receiver_map->elements_kind(), argc);
Handle<Code> code = stub.GetCode(isolate());
HConstant* code_value = Add<HConstant>(code);
ASSERT((sizeof(op_vals) / kPointerSize) ==
descriptor->environment_length());
HInstruction* call = New<HCallWithDescriptor>(
code_value, argc + 1, descriptor,
Vector<HValue*>(op_vals, descriptor->environment_length()));
ast_context()->ReturnInstruction(call, expr->id());
return true;
}
default:
// Not yet supported for inlining.
break;
......
......@@ -421,6 +421,20 @@ void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
descriptor->register_params_ = registers;
descriptor->param_representations_ = representations;
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::CallHandler);
static Register registers[] = { esi, // context
edx, // receiver
};
static Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // receiver
};
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->param_representations_ = representations;
}
}
......
......@@ -1076,6 +1076,7 @@ class Isolate {
enum CallDescriptorKey {
KeyedCall,
NamedCall,
CallHandler,
ArgumentAdaptorCall,
NUMBER_OF_CALL_DESCRIPTORS
};
......
......@@ -1282,41 +1282,6 @@ void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
}
Handle<Code> CallStubCompiler::CompileArrayPushCall(
Handle<Object> object,
Handle<JSObject> holder,
Handle<Cell> cell,
Handle<JSFunction> function,
Handle<String> name,
Code::StubType type) {
// If object is not an array or is observed or sealed, bail out to regular
// call.
if (!object->IsJSArray() ||
!cell.is_null() ||
Handle<JSArray>::cast(object)->map()->is_observed() ||
!Handle<JSArray>::cast(object)->map()->is_extensible()) {
return Handle<Code>::null();
}
Label miss;
HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
Handle<Map> map(Handle<JSArray>::cast(object)->map());
ElementsKind elements_kind = map->elements_kind();
const int argc = arguments().immediate();
ArrayPushStub stub(elements_kind, argc);
Handle<Code> code = stub.GetCode(isolate());
StubCompiler::GenerateTailCall(masm(), code);
HandlerFrontendFooter(&miss);
// Return the generated code.
return GetCode(type, name);
}
Handle<Code> CallStubCompiler::CompileCallConstant(
Handle<Object> object,
Handle<JSObject> holder,
......@@ -1913,13 +1878,6 @@ CallStubCompiler::CallStubCompiler(Isolate* isolate,
bool CallStubCompiler::HasCustomCallGenerator(Handle<JSFunction> function) {
if (function->shared()->HasBuiltinFunctionId()) {
BuiltinFunctionId id = function->shared()->builtin_function_id();
#define CALL_GENERATOR_CASE(name) if (id == k##name) return true;
CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
#undef CALL_GENERATOR_CASE
}
CallOptimization optimization(function);
return optimization.is_simple_api_call();
}
......@@ -1933,21 +1891,6 @@ Handle<Code> CallStubCompiler::CompileCustomCall(
Handle<String> fname,
Code::StubType type) {
ASSERT(HasCustomCallGenerator(function));
if (function->shared()->HasBuiltinFunctionId()) {
BuiltinFunctionId id = function->shared()->builtin_function_id();
#define CALL_GENERATOR_CASE(name) \
if (id == k##name) { \
return CallStubCompiler::Compile##name##Call(object, \
holder, \
cell, \
function, \
fname, \
type); \
}
CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
#undef CALL_GENERATOR_CASE
}
CallOptimization optimization(function);
ASSERT(optimization.is_simple_api_call());
return CompileFastApiCall(optimization,
......
......@@ -868,12 +868,6 @@ class KeyedStoreStubCompiler: public StoreStubCompiler {
};
// Subset of FUNCTIONS_WITH_ID_LIST with custom constant/global call
// IC stubs.
#define CUSTOM_CALL_IC_GENERATORS(V) \
V(ArrayPush)
class CallStubCompiler: public StubCompiler {
public:
CallStubCompiler(Isolate* isolate,
......@@ -940,16 +934,6 @@ class CallStubCompiler: public StubCompiler {
Handle<String> name,
Code::StubType type);
#define DECLARE_CALL_GENERATOR(name) \
Handle<Code> Compile##name##Call(Handle<Object> object, \
Handle<JSObject> holder, \
Handle<Cell> cell, \
Handle<JSFunction> function, \
Handle<String> fname, \
Code::StubType type);
CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR)
#undef DECLARE_CALL_GENERATOR
Handle<Code> CompileFastApiCall(const CallOptimization& optimization,
Handle<Object> object,
Handle<JSObject> holder,
......
......@@ -418,6 +418,20 @@ void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
descriptor->register_params_ = registers;
descriptor->param_representations_ = representations;
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::CallHandler);
static Register registers[] = { rsi, // context
rdx, // receiver
};
static Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // receiver
};
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->param_representations_ = representations;
}
}
......
......@@ -251,8 +251,7 @@ assertOptimized(shift_call);
Object.seal(obj);
assertThrows(function() { push_call(obj); }, TypeError);
assertThrows(function() { shift_call(obj); }, TypeError);
assertOptimized(push_call);
// shift() doesn't have a custom call generator, so deopt will occur.
assertUnoptimized(push_call);
assertUnoptimized(shift_call);
assertDoesNotThrow(function() { push_call(objControl); });
assertDoesNotThrow(function() { shift_call(objControl); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment