Speed up conversion of untagged int32 result if we know it must be a smi.
Review URL: http://codereview.chromium.org/1233003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4273 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
f5523ecc6a
commit
a255a71181
66
src/ast.cc
66
src/ast.cc
@ -172,6 +172,72 @@ void TargetCollector::AddTarget(BreakTarget* target) {
|
||||
}
|
||||
|
||||
|
||||
bool Expression::GuaranteedSmiResult() {
|
||||
BinaryOperation* node = AsBinaryOperation();
|
||||
if (node == NULL) return false;
|
||||
Token::Value op = node->op();
|
||||
switch (op) {
|
||||
case Token::COMMA:
|
||||
case Token::OR:
|
||||
case Token::AND:
|
||||
case Token::ADD:
|
||||
case Token::SUB:
|
||||
case Token::MUL:
|
||||
case Token::DIV:
|
||||
case Token::MOD:
|
||||
case Token::BIT_XOR:
|
||||
case Token::SHL:
|
||||
return false;
|
||||
break;
|
||||
case Token::BIT_OR:
|
||||
case Token::BIT_AND: {
|
||||
Literal* left = node->left()->AsLiteral();
|
||||
Literal* right = node->right()->AsLiteral();
|
||||
if (left != NULL && left->handle()->IsSmi()) {
|
||||
int value = Smi::cast(*left->handle())->value();
|
||||
if (op == Token::BIT_OR && ((value & 0xc0000000) == 0xc0000000)) {
|
||||
// Result of bitwise or is always a negative Smi.
|
||||
return true;
|
||||
}
|
||||
if (op == Token::BIT_AND && ((value & 0xc0000000) == 0)) {
|
||||
// Result of bitwise and is always a positive Smi.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (right != NULL && right->handle()->IsSmi()) {
|
||||
int value = Smi::cast(*right->handle())->value();
|
||||
if (op == Token::BIT_OR && ((value & 0xc0000000) == 0xc0000000)) {
|
||||
// Result of bitwise or is always a negative Smi.
|
||||
return true;
|
||||
}
|
||||
if (op == Token::BIT_AND && ((value & 0xc0000000) == 0)) {
|
||||
// Result of bitwise and is always a positive Smi.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case Token::SAR:
|
||||
case Token::SHR: {
|
||||
Literal* right = node->right()->AsLiteral();
|
||||
if (right != NULL && right->handle()->IsSmi()) {
|
||||
int value = Smi::cast(*right->handle())->value();
|
||||
if ((value & 0x1F) > 1 ||
|
||||
(op == Token::SAR && (value & 0x1F) == 1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Implementation of AstVisitor
|
||||
|
||||
|
@ -255,6 +255,10 @@ class Expression: public AstNode {
|
||||
LoopConditionField::encode(flag);
|
||||
}
|
||||
|
||||
// The value of the expression is guaranteed to be a smi, because the
|
||||
// top operation is a bit operation with a mask, or a shift.
|
||||
bool GuaranteedSmiResult();
|
||||
|
||||
// AST analysis results
|
||||
|
||||
// True if the expression rooted at this node can be compiled by the
|
||||
|
@ -490,7 +490,11 @@ void CodeGenerator::LoadInSafeInt32Mode(Expression* expr,
|
||||
Load(expr);
|
||||
Result value = frame_->Pop();
|
||||
ASSERT(frame_->HasNoUntaggedInt32Elements());
|
||||
ConvertInt32ResultToNumber(&value);
|
||||
if (expr->GuaranteedSmiResult()) {
|
||||
ConvertInt32ResultToSmi(&value);
|
||||
} else {
|
||||
ConvertInt32ResultToNumber(&value);
|
||||
}
|
||||
set_in_safe_int32_mode(false);
|
||||
set_unsafe_bailout(NULL);
|
||||
frame_->Push(&value);
|
||||
@ -504,6 +508,19 @@ void CodeGenerator::LoadWithSafeInt32ModeDisabled(Expression* expr) {
|
||||
}
|
||||
|
||||
|
||||
void CodeGenerator::ConvertInt32ResultToSmi(Result* value) {
|
||||
ASSERT(value->is_untagged_int32());
|
||||
if (value->is_register()) {
|
||||
__ add(value->reg(), Operand(value->reg()));
|
||||
} else {
|
||||
ASSERT(value->is_constant());
|
||||
ASSERT(value->handle()->IsSmi());
|
||||
}
|
||||
value->set_untagged_int32(false);
|
||||
value->set_number_info(NumberInfo::Smi());
|
||||
}
|
||||
|
||||
|
||||
void CodeGenerator::ConvertInt32ResultToNumber(Result* value) {
|
||||
ASSERT(value->is_untagged_int32());
|
||||
if (value->is_register()) {
|
||||
@ -552,6 +569,7 @@ void CodeGenerator::ConvertInt32ResultToNumber(Result* value) {
|
||||
ASSERT(value->is_constant());
|
||||
}
|
||||
value->set_untagged_int32(false);
|
||||
value->set_number_info(NumberInfo::Integer32());
|
||||
}
|
||||
|
||||
|
||||
|
@ -373,6 +373,7 @@ class CodeGenerator: public AstVisitor {
|
||||
// Take the Result that is an untagged int32, and convert it to a tagged
|
||||
// Smi or HeapNumber. Remove the untagged_int32 flag from the result.
|
||||
void ConvertInt32ResultToNumber(Result* value);
|
||||
void ConvertInt32ResultToSmi(Result* value);
|
||||
|
||||
// Track loop nesting level.
|
||||
int loop_nesting() const { return loop_nesting_; }
|
||||
|
Loading…
Reference in New Issue
Block a user