Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(540)

Unified Diff: src/x64/codegen-x64.cc

Issue 1520001: Start using String type info: (Closed)
Patch Set: Review Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/type-info.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x64/codegen-x64.cc
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index dd8015f14d10f78933afad97aa1e94c1aa5429ce..27e12afdae67bce0646f52b8c770052fc4e1068d 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -3129,14 +3129,16 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
}
-// The value in dst was optimistically incremented or decremented. The
-// result overflowed or was not smi tagged. Undo the operation, call
-// into the runtime to convert the argument to a number, and call the
-// specialized add or subtract stub. The result is left in dst.
+// The value in dst was optimistically incremented or decremented.
+// The result overflowed or was not smi tagged. Call into the runtime
+// to convert the argument to a number, and call the specialized add
+// or subtract stub. The result is left in dst.
class DeferredPrefixCountOperation: public DeferredCode {
public:
- DeferredPrefixCountOperation(Register dst, bool is_increment)
- : dst_(dst), is_increment_(is_increment) {
+ DeferredPrefixCountOperation(Register dst,
+ bool is_increment,
+ TypeInfo input_type)
+ : dst_(dst), is_increment_(is_increment), input_type_(input_type) {
set_comment("[ DeferredCountOperation");
}
@@ -3145,13 +3147,16 @@ class DeferredPrefixCountOperation: public DeferredCode {
private:
Register dst_;
bool is_increment_;
+ TypeInfo input_type_;
};
void DeferredPrefixCountOperation::Generate() {
__ push(dst_);
- __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
- __ push(rax);
+ if (!input_type_.IsNumber()) {
+ __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
+ __ push(rax);
+ }
__ Push(Smi::FromInt(1));
if (is_increment_) {
__ CallRuntime(Runtime::kNumberAdd, 2);
@@ -3162,15 +3167,21 @@ void DeferredPrefixCountOperation::Generate() {
}
-// The value in dst was optimistically incremented or decremented. The
-// result overflowed or was not smi tagged. Undo the operation and call
-// into the runtime to convert the argument to a number. Update the
-// original value in old. Call the specialized add or subtract stub.
-// The result is left in dst.
+// The value in dst was optimistically incremented or decremented.
+// The result overflowed or was not smi tagged. Call into the runtime
+// to convert the argument to a number. Update the original value in
+// old. Call the specialized add or subtract stub. The result is
+// left in dst.
class DeferredPostfixCountOperation: public DeferredCode {
public:
- DeferredPostfixCountOperation(Register dst, Register old, bool is_increment)
- : dst_(dst), old_(old), is_increment_(is_increment) {
+ DeferredPostfixCountOperation(Register dst,
+ Register old,
+ bool is_increment,
+ TypeInfo input_type)
+ : dst_(dst),
+ old_(old),
+ is_increment_(is_increment),
+ input_type_(input_type) {
set_comment("[ DeferredCountOperation");
}
@@ -3180,18 +3191,22 @@ class DeferredPostfixCountOperation: public DeferredCode {
Register dst_;
Register old_;
bool is_increment_;
+ TypeInfo input_type_;
};
void DeferredPostfixCountOperation::Generate() {
- __ push(dst_);
- __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
-
- // Save the result of ToNumber to use as the old value.
- __ push(rax);
+ if (input_type_.IsNumber()) {
+ __ push(dst_); // Save the input to use as the old value.
+ __ push(dst_);
+ } else {
+ __ push(dst_);
+ __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
+ __ push(rax); // Save the result of ToNumber to use as the old value.
+ __ push(rax);
+ }
// Call the runtime for the addition or subtraction.
- __ push(rax);
__ Push(Smi::FromInt(1));
if (is_increment_) {
__ CallRuntime(Runtime::kNumberAdd, 2);
@@ -3238,6 +3253,14 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
old_value = allocator_->Allocate();
ASSERT(old_value.is_valid());
__ movq(old_value.reg(), new_value.reg());
+
+ // The return value for postfix operations is ToNumber(input).
+ // Keep more precise type info if the input is some kind of
+ // number already. If the input is not a number we have to wait
+ // for the deferred code to convert it.
+ if (new_value.type_info().IsNumber()) {
+ old_value.set_type_info(new_value.type_info());
+ }
}
// Ensure the new value is writable.
frame_->Spill(new_value.reg());
@@ -3246,10 +3269,12 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
if (is_postfix) {
deferred = new DeferredPostfixCountOperation(new_value.reg(),
old_value.reg(),
- is_increment);
+ is_increment,
+ new_value.type_info());
} else {
deferred = new DeferredPrefixCountOperation(new_value.reg(),
- is_increment);
+ is_increment,
+ new_value.type_info());
}
__ JumpIfNotSmi(new_value.reg(), deferred->entry_label());
@@ -3267,6 +3292,15 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
__ movq(new_value.reg(), kScratchRegister);
deferred->BindExit();
+ // Postfix count operations return their input converted to
+ // number. The case when the input is already a number is covered
+ // above in the allocation code for old_value.
+ if (is_postfix && !new_value.type_info().IsNumber()) {
+ old_value.set_type_info(TypeInfo::Number());
+ }
+
+ new_value.set_type_info(TypeInfo::Number());
+
// Postfix: store the old value in the allocated slot under the
// reference.
if (is_postfix) frame_->SetElementAt(target.size(), &old_value);
@@ -5254,8 +5288,13 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
Result left = frame_->Pop();
if (op == Token::ADD) {
- bool left_is_string = left.is_constant() && left.handle()->IsString();
- bool right_is_string = right.is_constant() && right.handle()->IsString();
+ const bool left_is_string = left.type_info().IsString();
+ const bool right_is_string = right.type_info().IsString();
+ // Make sure constant strings have string type info.
+ ASSERT(!(left.is_constant() && left.handle()->IsString()) ||
+ left_is_string);
+ ASSERT(!(right.is_constant() && right.handle()->IsString()) ||
+ right_is_string);
if (left_is_string || right_is_string) {
frame_->Push(&left);
frame_->Push(&right);
@@ -5264,7 +5303,8 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
if (right_is_string) {
// TODO(lrn): if both are constant strings
// -- do a compile time cons, if allocation during codegen is allowed.
- answer = frame_->CallRuntime(Runtime::kStringAdd, 2);
+ StringAddStub stub(NO_STRING_CHECK_IN_STUB);
+ answer = frame_->CallStub(&stub, 2);
} else {
answer =
frame_->InvokeBuiltin(Builtins::STRING_ADD_LEFT, CALL_FUNCTION, 2);
@@ -5273,6 +5313,7 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
answer =
frame_->InvokeBuiltin(Builtins::STRING_ADD_RIGHT, CALL_FUNCTION, 2);
}
+ answer.set_type_info(TypeInfo::String());
frame_->Push(&answer);
return;
}
@@ -5358,10 +5399,13 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
: TypeInfo::Number();
break;
case Token::ADD:
- // Result could be a string or a number. Check types of inputs.
- result_type = operands_type.IsNumber()
- ? TypeInfo::Number()
- : TypeInfo::Unknown();
+ if (operands_type.IsNumber()) {
+ result_type = TypeInfo::Number();
+ } else if (operands_type.IsString()) {
+ result_type = TypeInfo::String();
+ } else {
+ result_type = TypeInfo::Unknown();
+ }
break;
case Token::SUB:
case Token::MUL:
« no previous file with comments | « src/type-info.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698