Commit 100fb555 authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

Inline number to string conversion for string addition into BinaryOp(Stub).

This fixes a performance regression that was caused by converting the
BinaryOpStub to a Hydrogen code stub. It also fixes a leftover TODO wrt.
the handling of Number*String or String*Number versions of the stub.

R=rossberg@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17290 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ef12527b
......@@ -65,7 +65,8 @@ void NumberToStringStub::InitializeInterfaceDescriptor(
static Register registers[] = { r0 };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kNumberToString)->entry;
}
......
......@@ -351,7 +351,7 @@ template <>
HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() {
info()->MarkAsSavesCallerDoubles();
HValue* number = GetParameter(NumberToStringStub::kNumber);
return BuildNumberToString(number);
return BuildNumberToString(number, handle(Type::Number(), isolate()));
}
......@@ -881,35 +881,52 @@ HValue* CodeStubGraphBuilder<BinaryOpStub>::BuildCodeInitializedStub() {
if (stub->operation() == Token::ADD &&
(left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) &&
!left_type->Is(Type::String()) && !right_type->Is(Type::String())) {
// For the generic add stub a fast case for String add is performance
// For the generic add stub a fast case for string addition is performance
// critical.
if (left_type->Maybe(Type::String())) {
IfBuilder left_string(this);
left_string.If<HIsStringAndBranch>(left);
left_string.Then();
Push(Add<HStringAdd>(left, right, STRING_ADD_CHECK_RIGHT));
left_string.Else();
Push(AddInstruction(BuildBinaryOperation(stub->operation(),
left, right, left_type, right_type, result_type,
stub->fixed_right_arg(), true)));
left_string.End();
IfBuilder if_leftisstring(this);
if_leftisstring.If<HIsStringAndBranch>(left);
if_leftisstring.Then();
{
Push(AddInstruction(BuildBinaryOperation(
stub->operation(), left, right,
handle(Type::String(), isolate()), right_type,
result_type, stub->fixed_right_arg(), true)));
}
if_leftisstring.Else();
{
Push(AddInstruction(BuildBinaryOperation(
stub->operation(), left, right,
left_type, right_type, result_type,
stub->fixed_right_arg(), true)));
}
if_leftisstring.End();
result = Pop();
} else {
IfBuilder right_string(this);
right_string.If<HIsStringAndBranch>(right);
right_string.Then();
Push(Add<HStringAdd>(left, right, STRING_ADD_CHECK_LEFT));
right_string.Else();
Push(AddInstruction(BuildBinaryOperation(stub->operation(),
left, right, left_type, right_type, result_type,
stub->fixed_right_arg(), true)));
right_string.End();
IfBuilder if_rightisstring(this);
if_rightisstring.If<HIsStringAndBranch>(right);
if_rightisstring.Then();
{
Push(AddInstruction(BuildBinaryOperation(
stub->operation(), left, right,
left_type, handle(Type::String(), isolate()),
result_type, stub->fixed_right_arg(), true)));
}
if_rightisstring.Else();
{
Push(AddInstruction(BuildBinaryOperation(
stub->operation(), left, right,
left_type, right_type, result_type,
stub->fixed_right_arg(), true)));
}
if_rightisstring.End();
result = Pop();
}
} else {
result = AddInstruction(BuildBinaryOperation(stub->operation(),
left, right, left_type, right_type, result_type,
stub->fixed_right_arg(), true));
result = AddInstruction(BuildBinaryOperation(
stub->operation(), left, right,
left_type, right_type, result_type,
stub->fixed_right_arg(), true));
}
// If we encounter a generic argument, the number conversion is
......
......@@ -570,14 +570,8 @@ void BinaryOpStub::UpdateStatus(Handle<Object> left,
State max_input = Max(left_state_, right_state_);
// TODO(olivf) Instead of doing this normalization we should have a Hydrogen
// version of the LookupNumberStringCache to avoid a converting StringAddStub.
if (left_state_ == STRING && right_state_ < STRING) {
right_state_ = GENERIC;
} else if (right_state_ == STRING && left_state_ < STRING) {
left_state_ = GENERIC;
} else if (!has_int_result() && op_ != Token::SHR &&
max_input <= NUMBER && max_input > result_state_) {
if (!has_int_result() && op_ != Token::SHR &&
max_input <= NUMBER && max_input > result_state_) {
result_state_ = max_input;
}
......@@ -1127,6 +1121,12 @@ void ArrayConstructorStubBase::InstallDescriptors(Isolate* isolate) {
}
void NumberToStringStub::InstallDescriptors(Isolate* isolate) {
NumberToStringStub stub;
InstallDescriptor(isolate, &stub);
}
void FastNewClosureStub::InstallDescriptors(Isolate* isolate) {
FastNewClosureStub stub(STRICT_MODE, false);
InstallDescriptor(isolate, &stub);
......
......@@ -477,6 +477,8 @@ class NumberToStringStub V8_FINAL : public HydrogenCodeStub {
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
static void InstallDescriptors(Isolate* isolate);
// Parameters accessed via CodeStubGraphBuilder::GetParameter()
static const int kNumber = 0;
......
This diff is collapsed.
......@@ -1234,14 +1234,7 @@ class HGraphBuilder {
ElementsKind to_kind,
bool is_jsarray);
// Do lookup in the number string cache. If the object is not found
// in the cache, the false branch of the continuation is taken;
// otherwise the true branch is taken and the returned value contains
// the cache value for the object. The returned value must NOT be used
// on the false branch.
HValue* BuildLookupNumberStringCache(HValue* object,
HIfContinuation* continuation);
HValue* BuildNumberToString(HValue* number);
HValue* BuildNumberToString(HValue* object, Handle<Type> type);
HInstruction* BuildUncheckedMonomorphicElementAccess(
HValue* checked_object,
......
......@@ -70,7 +70,8 @@ void NumberToStringStub::InitializeInterfaceDescriptor(
static Register registers[] = { eax };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kNumberToString)->entry;
}
......
......@@ -2327,6 +2327,7 @@ bool Isolate::Init(Deserializer* des) {
ArrayConstructorStubBase::InstallDescriptors(this);
InternalArrayConstructorStubBase::InstallDescriptors(this);
FastNewClosureStub::InstallDescriptors(this);
NumberToStringStub::InstallDescriptors(this);
}
if (FLAG_sweeper_threads > 0) {
......
......@@ -66,7 +66,8 @@ void NumberToStringStub::InitializeInterfaceDescriptor(
static Register registers[] = { rax };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kNumberToString)->entry;
}
......
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