summaryrefslogtreecommitdiff
path: root/deps/v8/src/x64
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2010-04-27 00:31:47 -0700
committerRyan Dahl <ry@tinyclouds.org>2010-04-27 00:31:47 -0700
commit24931f840544c9970203660121a1ec4606bdd4f1 (patch)
treef22539325eb06fc50879d9d4f327cf6c83645891 /deps/v8/src/x64
parent2374e557e30fab5c357d3f03716ca3b83131c3c0 (diff)
downloadnode-new-24931f840544c9970203660121a1ec4606bdd4f1.tar.gz
Upgrade V8 to 2.2.5
Diffstat (limited to 'deps/v8/src/x64')
-rw-r--r--deps/v8/src/x64/codegen-x64.cc163
1 files changed, 105 insertions, 58 deletions
diff --git a/deps/v8/src/x64/codegen-x64.cc b/deps/v8/src/x64/codegen-x64.cc
index a6aa36d731..7a3278ca86 100644
--- a/deps/v8/src/x64/codegen-x64.cc
+++ b/deps/v8/src/x64/codegen-x64.cc
@@ -304,8 +304,7 @@ void CodeGenerator::Generate(CompilationInfo* info) {
#endif
// New scope to get automatic timing calculation.
- { // NOLINT
- HistogramTimerScope codegen_timer(&Counters::code_generation);
+ { HistogramTimerScope codegen_timer(&Counters::code_generation);
CodeGenState state(this);
// Entry:
@@ -3118,6 +3117,7 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
GenericUnaryOpStub stub(Token::SUB, overwrite);
Result operand = frame_->Pop();
Result answer = frame_->CallStub(&stub, &operand);
+ answer.set_type_info(TypeInfo::Number());
frame_->Push(&answer);
break;
}
@@ -3141,6 +3141,7 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
frame_->Spill(answer.reg());
__ SmiNot(answer.reg(), answer.reg());
continue_label.Bind(&answer);
+ answer.set_type_info(TypeInfo::Smi());
frame_->Push(&answer);
break;
}
@@ -3149,6 +3150,7 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
// Smi check.
JumpTarget continue_label;
Result operand = frame_->Pop();
+ TypeInfo operand_info = operand.type_info();
operand.ToRegister();
Condition is_smi = masm_->CheckSmi(operand.reg());
continue_label.Branch(is_smi, &operand);
@@ -3157,10 +3159,16 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
CALL_FUNCTION, 1);
continue_label.Bind(&answer);
+ if (operand_info.IsSmi()) {
+ answer.set_type_info(TypeInfo::Smi());
+ } else if (operand_info.IsInteger32()) {
+ answer.set_type_info(TypeInfo::Integer32());
+ } else {
+ answer.set_type_info(TypeInfo::Number());
+ }
frame_->Push(&answer);
break;
}
-
default:
UNREACHABLE();
}
@@ -4297,17 +4305,23 @@ void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) {
frame_->Push(Factory::undefined_value());
return;
}
- Handle<FixedArray> cache_obj(
- FixedArray::cast(jsfunction_result_caches->get(cache_id)));
Load(args->at(1));
Result key = frame_->Pop();
key.ToRegister();
Result cache = allocator()->Allocate();
- __ movq(cache.reg(), cache_obj, RelocInfo::EMBEDDED_OBJECT);
+ ASSERT(cache.is_valid());
+ __ movq(cache.reg(), ContextOperand(rsi, Context::GLOBAL_INDEX));
+ __ movq(cache.reg(),
+ FieldOperand(cache.reg(), GlobalObject::kGlobalContextOffset));
+ __ movq(cache.reg(),
+ ContextOperand(cache.reg(), Context::JSFUNCTION_RESULT_CACHES_INDEX));
+ __ movq(cache.reg(),
+ FieldOperand(cache.reg(), FixedArray::OffsetOfElementAt(cache_id)));
Result tmp = allocator()->Allocate();
+ ASSERT(tmp.is_valid());
DeferredSearchCache* deferred = new DeferredSearchCache(tmp.reg(),
cache.reg(),
@@ -5297,6 +5311,15 @@ void CodeGenerator::LoadTypeofExpression(Expression* expr) {
}
+static bool CouldBeNaN(const Result& result) {
+ if (result.type_info().IsSmi()) return false;
+ if (result.type_info().IsInteger32()) return false;
+ if (!result.is_constant()) return true;
+ if (!result.handle()->IsHeapNumber()) return false;
+ return isnan(HeapNumber::cast(*result.handle())->value());
+}
+
+
void CodeGenerator::Comparison(AstNode* node,
Condition cc,
bool strict,
@@ -5614,15 +5637,29 @@ void CodeGenerator::Comparison(AstNode* node,
right_side.Unuse();
dest->Split(cc);
}
- } else { // Neither side is a constant Smi or null.
+ } else {
+ // Neither side is a constant Smi, constant 1-char string, or constant null.
// If either side is a non-smi constant, skip the smi check.
bool known_non_smi =
(left_side.is_constant() && !left_side.handle()->IsSmi()) ||
(right_side.is_constant() && !right_side.handle()->IsSmi());
+
+ NaNInformation nan_info =
+ (CouldBeNaN(left_side) && CouldBeNaN(right_side)) ?
+ kBothCouldBeNaN :
+ kCantBothBeNaN;
+
left_side.ToRegister();
right_side.ToRegister();
if (known_non_smi) {
+ // If at least one of the objects is not NaN, then if the objects
+ // are identical, they are equal.
+ if (nan_info == kCantBothBeNaN && cc == equal) {
+ __ cmpq(left_side.reg(), right_side.reg());
+ dest->true_target()->Branch(equal);
+ }
+
// When non-smi, call out to the compare stub.
CompareStub stub(cc, strict);
Result answer = frame_->CallStub(&stub, &left_side, &right_side);
@@ -5642,7 +5679,14 @@ void CodeGenerator::Comparison(AstNode* node,
Condition both_smi = masm_->CheckBothSmi(left_reg, right_reg);
is_smi.Branch(both_smi);
- // When non-smi, call out to the compare stub.
+ // When non-smi, call out to the compare stub, after inlined checks.
+ // If at least one of the objects is not NaN, then if the objects
+ // are identical, they are equal.
+ if (nan_info == kCantBothBeNaN && cc == equal) {
+ __ cmpq(left_side.reg(), right_side.reg());
+ dest->true_target()->Branch(equal);
+ }
+
CompareStub stub(cc, strict);
Result answer = frame_->CallStub(&stub, &left_side, &right_side);
__ SmiTest(answer.reg()); // Sets both zero and sign flags.
@@ -5691,6 +5735,57 @@ void DeferredInlineBinaryOperation::Generate() {
}
+static TypeInfo CalculateTypeInfo(TypeInfo operands_type,
+ Token::Value op,
+ const Result& right,
+ const Result& left) {
+ // Set TypeInfo of result according to the operation performed.
+ // We rely on the fact that smis have a 32 bit payload on x64.
+ STATIC_ASSERT(kSmiValueSize == 32);
+ switch (op) {
+ case Token::COMMA:
+ return right.type_info();
+ case Token::OR:
+ case Token::AND:
+ // Result type can be either of the two input types.
+ return operands_type;
+ case Token::BIT_OR:
+ case Token::BIT_XOR:
+ case Token::BIT_AND:
+ // Result is always a smi.
+ return TypeInfo::Smi();
+ case Token::SAR:
+ case Token::SHL:
+ // Result is always a smi.
+ return TypeInfo::Smi();
+ case Token::SHR:
+ // Result of x >>> y is always a smi if masked y >= 1, otherwise a number.
+ return (right.is_constant() && right.handle()->IsSmi()
+ && (Smi::cast(*right.handle())->value() & 0x1F) >= 1)
+ ? TypeInfo::Smi()
+ : TypeInfo::Number();
+ case Token::ADD:
+ if (operands_type.IsNumber()) {
+ return TypeInfo::Number();
+ } else if (left.type_info().IsString() || right.type_info().IsString()) {
+ return TypeInfo::String();
+ } else {
+ return TypeInfo::Unknown();
+ }
+ case Token::SUB:
+ case Token::MUL:
+ case Token::DIV:
+ case Token::MOD:
+ // Result is always a number.
+ return TypeInfo::Number();
+ default:
+ UNREACHABLE();
+ }
+ UNREACHABLE();
+ return TypeInfo::Unknown();
+}
+
+
void CodeGenerator::GenericBinaryOperation(Token::Value op,
StaticType* type,
OverwriteMode overwrite_mode) {
@@ -5756,6 +5851,8 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
TypeInfo operands_type =
TypeInfo::Combine(left.type_info(), right.type_info());
+ TypeInfo result_type = CalculateTypeInfo(operands_type, op, right, left);
+
Result answer;
if (left_is_non_smi_constant || right_is_non_smi_constant) {
GenericBinaryOpStub stub(op,
@@ -5786,56 +5883,6 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
}
}
- // Set TypeInfo of result according to the operation performed.
- // We rely on the fact that smis have a 32 bit payload on x64.
- ASSERT(kSmiValueSize == 32);
- TypeInfo result_type = TypeInfo::Unknown();
- switch (op) {
- case Token::COMMA:
- result_type = right.type_info();
- break;
- case Token::OR:
- case Token::AND:
- // Result type can be either of the two input types.
- result_type = operands_type;
- break;
- case Token::BIT_OR:
- case Token::BIT_XOR:
- case Token::BIT_AND:
- // Result is always a smi.
- result_type = TypeInfo::Smi();
- break;
- case Token::SAR:
- case Token::SHL:
- // Result is always a smi.
- result_type = TypeInfo::Smi();
- break;
- case Token::SHR:
- // Result of x >>> y is always a smi if y >= 1, otherwise a number.
- result_type = (right.is_constant() && right.handle()->IsSmi()
- && Smi::cast(*right.handle())->value() >= 1)
- ? TypeInfo::Smi()
- : TypeInfo::Number();
- break;
- case Token::ADD:
- 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:
- case Token::DIV:
- case Token::MOD:
- // Result is always a number.
- result_type = TypeInfo::Number();
- break;
- default:
- UNREACHABLE();
- }
answer.set_type_info(result_type);
frame_->Push(&answer);
}