Commit 5794e68f authored by whesse@chromium.org's avatar whesse@chromium.org

Remove unnecessary formatting differences between ia32 and x64 code...

Remove unnecessary formatting differences between ia32 and x64 code generators.  Mainly just typographical changes.
Review URL: http://codereview.chromium.org/3023001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5080 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 522faec5
...@@ -34,12 +34,9 @@ ...@@ -34,12 +34,9 @@
#include "compiler.h" #include "compiler.h"
#include "debug.h" #include "debug.h"
#include "ic-inl.h" #include "ic-inl.h"
#include "jsregexp.h"
#include "parser.h" #include "parser.h"
#include "regexp-macro-assembler.h" #include "regexp-macro-assembler.h"
#include "regexp-stack.h"
#include "register-allocator-inl.h" #include "register-allocator-inl.h"
#include "runtime.h"
#include "scopes.h" #include "scopes.h"
#include "virtual-frame-inl.h" #include "virtual-frame-inl.h"
...@@ -143,7 +140,7 @@ CodeGenState::~CodeGenState() { ...@@ -143,7 +140,7 @@ CodeGenState::~CodeGenState() {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// CodeGenerator implementation // CodeGenerator implementation.
CodeGenerator::CodeGenerator(MacroAssembler* masm) CodeGenerator::CodeGenerator(MacroAssembler* masm)
: deferred_(8), : deferred_(8),
...@@ -374,12 +371,11 @@ void CodeGenerator::Generate(CompilationInfo* info) { ...@@ -374,12 +371,11 @@ void CodeGenerator::Generate(CompilationInfo* info) {
} }
// Adjust for function-level loop nesting. // Adjust for function-level loop nesting.
ASSERT_EQ(info->loop_nesting(), loop_nesting_); ASSERT_EQ(loop_nesting_, info->loop_nesting());
loop_nesting_ = 0; loop_nesting_ = 0;
// Code generation state must be reset. // Code generation state must be reset.
ASSERT(state_ == NULL); ASSERT(state_ == NULL);
ASSERT(loop_nesting() == 0);
ASSERT(!function_return_is_shadowed_); ASSERT(!function_return_is_shadowed_);
function_return_.Unuse(); function_return_.Unuse();
DeleteFrame(); DeleteFrame();
...@@ -646,7 +642,6 @@ void CodeGenerator::Load(Expression* expr) { ...@@ -646,7 +642,6 @@ void CodeGenerator::Load(Expression* expr) {
} else { } else {
JumpTarget true_target; JumpTarget true_target;
JumpTarget false_target; JumpTarget false_target;
ControlDestination dest(&true_target, &false_target, true); ControlDestination dest(&true_target, &false_target, true);
LoadCondition(expr, &dest, false); LoadCondition(expr, &dest, false);
...@@ -784,9 +779,9 @@ Result CodeGenerator::StoreArgumentsObject(bool initial) { ...@@ -784,9 +779,9 @@ Result CodeGenerator::StoreArgumentsObject(bool initial) {
JumpTarget done; JumpTarget done;
bool skip_arguments = false; bool skip_arguments = false;
if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) {
// We have to skip storing into the arguments slot if it has already // We have to skip storing into the arguments slot if it has
// been written to. This can happen if the a function has a local // already been written to. This can happen if the a function
// variable named 'arguments'. // has a local variable named 'arguments'.
LoadFromSlot(arguments->slot(), NOT_INSIDE_TYPEOF); LoadFromSlot(arguments->slot(), NOT_INSIDE_TYPEOF);
Result probe = frame_->Pop(); Result probe = frame_->Pop();
if (probe.is_constant()) { if (probe.is_constant()) {
...@@ -1434,8 +1429,8 @@ bool CodeGenerator::FoldConstantSmis(Token::Value op, int left, int right) { ...@@ -1434,8 +1429,8 @@ bool CodeGenerator::FoldConstantSmis(Token::Value op, int left, int right) {
} else { } else {
unsigned_left >>= shift_amount; unsigned_left >>= shift_amount;
} }
ASSERT(Smi::IsValid(unsigned_left)); // Converted to signed. ASSERT(Smi::IsValid(static_cast<int32_t>(unsigned_left)));
answer_object = Smi::FromInt(unsigned_left); // Converted to signed. answer_object = Smi::FromInt(static_cast<int32_t>(unsigned_left));
break; break;
} }
default: default:
...@@ -1919,12 +1914,12 @@ class DeferredInlineSmiOperationReversed: public DeferredCode { ...@@ -1919,12 +1914,12 @@ class DeferredInlineSmiOperationReversed: public DeferredCode {
void DeferredInlineSmiOperationReversed::Generate() { void DeferredInlineSmiOperationReversed::Generate() {
GenericBinaryOpStub igostub( GenericBinaryOpStub stub(
op_, op_,
overwrite_mode_, overwrite_mode_,
NO_SMI_CODE_IN_STUB, NO_SMI_CODE_IN_STUB,
TypeInfo::Combine(TypeInfo::Smi(), type_info_)); TypeInfo::Combine(TypeInfo::Smi(), type_info_));
igostub.GenerateCall(masm_, value_, src_); stub.GenerateCall(masm_, value_, src_);
if (!dst_.is(eax)) __ mov(dst_, eax); if (!dst_.is(eax)) __ mov(dst_, eax);
} }
...@@ -2424,6 +2419,7 @@ Result CodeGenerator::ConstantSmiBinaryOperation(BinaryOperation* expr, ...@@ -2424,6 +2419,7 @@ Result CodeGenerator::ConstantSmiBinaryOperation(BinaryOperation* expr,
break; break;
} }
// Fall through if we did not find a power of 2 on the right hand side! // Fall through if we did not find a power of 2 on the right hand side!
// The next case must be the default.
default: { default: {
Result constant_operand(value); Result constant_operand(value);
...@@ -2676,13 +2672,14 @@ void CodeGenerator::Comparison(AstNode* node, ...@@ -2676,13 +2672,14 @@ void CodeGenerator::Comparison(AstNode* node,
} }
} else { } else {
// Neither side is a constant Smi, constant 1-char string or constant null. // Neither side is a constant Smi, constant 1-char string or constant null.
// If either side is a non-smi constant, or known to be a heap number skip // If either side is a non-smi constant, or known to be a heap number,
// the smi check. // skip the smi check.
bool known_non_smi = bool known_non_smi =
(left_side.is_constant() && !left_side.handle()->IsSmi()) || (left_side.is_constant() && !left_side.handle()->IsSmi()) ||
(right_side.is_constant() && !right_side.handle()->IsSmi()) || (right_side.is_constant() && !right_side.handle()->IsSmi()) ||
left_side.type_info().IsDouble() || left_side.type_info().IsDouble() ||
right_side.type_info().IsDouble(); right_side.type_info().IsDouble();
NaNInformation nan_info = NaNInformation nan_info =
(CouldBeNaN(left_side) && CouldBeNaN(right_side)) ? (CouldBeNaN(left_side) && CouldBeNaN(right_side)) ?
kBothCouldBeNaN : kBothCouldBeNaN :
...@@ -2707,14 +2704,15 @@ void CodeGenerator::Comparison(AstNode* node, ...@@ -2707,14 +2704,15 @@ void CodeGenerator::Comparison(AstNode* node,
right_side.ToRegister(); right_side.ToRegister();
if (known_non_smi) { if (known_non_smi) {
// Inline the equality check if both operands can't be a NaN. If both // Inlined equality check:
// objects are the same they are equal. // 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) { if (nan_info == kCantBothBeNaN && cc == equal) {
__ cmp(left_side.reg(), Operand(right_side.reg())); __ cmp(left_side.reg(), Operand(right_side.reg()));
dest->true_target()->Branch(equal); dest->true_target()->Branch(equal);
} }
// Inline number comparison. // Inlined number comparison:
if (inline_number_compare) { if (inline_number_compare) {
GenerateInlineNumberComparison(&left_side, &right_side, cc, dest); GenerateInlineNumberComparison(&left_side, &right_side, cc, dest);
} }
...@@ -2752,7 +2750,7 @@ void CodeGenerator::Comparison(AstNode* node, ...@@ -2752,7 +2750,7 @@ void CodeGenerator::Comparison(AstNode* node,
dest->true_target()->Branch(equal); dest->true_target()->Branch(equal);
} }
// Inline number comparison. // Inlined number comparison:
if (inline_number_compare) { if (inline_number_compare) {
GenerateInlineNumberComparison(&left_side, &right_side, cc, dest); GenerateInlineNumberComparison(&left_side, &right_side, cc, dest);
} }
...@@ -2970,19 +2968,19 @@ static void LoadComparisonOperand(MacroAssembler* masm_, ...@@ -2970,19 +2968,19 @@ static void LoadComparisonOperand(MacroAssembler* masm_,
// target passing the left and right result if the operand is not a number. // target passing the left and right result if the operand is not a number.
static void LoadComparisonOperandSSE2(MacroAssembler* masm_, static void LoadComparisonOperandSSE2(MacroAssembler* masm_,
Result* operand, Result* operand,
XMMRegister reg, XMMRegister xmm_reg,
Result* left_side, Result* left_side,
Result* right_side, Result* right_side,
JumpTarget* not_numbers) { JumpTarget* not_numbers) {
Label done; Label done;
if (operand->type_info().IsDouble()) { if (operand->type_info().IsDouble()) {
// Operand is known to be a heap number, just load it. // Operand is known to be a heap number, just load it.
__ movdbl(reg, FieldOperand(operand->reg(), HeapNumber::kValueOffset)); __ movdbl(xmm_reg, FieldOperand(operand->reg(), HeapNumber::kValueOffset));
} else if (operand->type_info().IsSmi()) { } else if (operand->type_info().IsSmi()) {
// Operand is known to be a smi. Convert it to double and keep the original // Operand is known to be a smi. Convert it to double and keep the original
// smi. // smi.
__ SmiUntag(operand->reg()); __ SmiUntag(operand->reg());
__ cvtsi2sd(reg, Operand(operand->reg())); __ cvtsi2sd(xmm_reg, Operand(operand->reg()));
__ SmiTag(operand->reg()); __ SmiTag(operand->reg());
} else { } else {
// Operand type not known, check for smi or heap number. // Operand type not known, check for smi or heap number.
...@@ -2994,13 +2992,13 @@ static void LoadComparisonOperandSSE2(MacroAssembler* masm_, ...@@ -2994,13 +2992,13 @@ static void LoadComparisonOperandSSE2(MacroAssembler* masm_,
Immediate(Factory::heap_number_map())); Immediate(Factory::heap_number_map()));
not_numbers->Branch(not_equal, left_side, right_side, taken); not_numbers->Branch(not_equal, left_side, right_side, taken);
} }
__ movdbl(reg, FieldOperand(operand->reg(), HeapNumber::kValueOffset)); __ movdbl(xmm_reg, FieldOperand(operand->reg(), HeapNumber::kValueOffset));
__ jmp(&done); __ jmp(&done);
__ bind(&smi); __ bind(&smi);
// Comvert smi to float and keep the original smi. // Comvert smi to float and keep the original smi.
__ SmiUntag(operand->reg()); __ SmiUntag(operand->reg());
__ cvtsi2sd(reg, Operand(operand->reg())); __ cvtsi2sd(xmm_reg, Operand(operand->reg()));
__ SmiTag(operand->reg()); __ SmiTag(operand->reg());
__ jmp(&done); __ jmp(&done);
} }
...@@ -3597,8 +3595,10 @@ void CodeGenerator::GenerateReturnSequence(Result* return_value) { ...@@ -3597,8 +3595,10 @@ void CodeGenerator::GenerateReturnSequence(Result* return_value) {
return_value->ToRegister(eax); return_value->ToRegister(eax);
// Add a label for checking the size of the code used for returning. // Add a label for checking the size of the code used for returning.
#ifdef DEBUG
Label check_exit_codesize; Label check_exit_codesize;
masm_->bind(&check_exit_codesize); masm_->bind(&check_exit_codesize);
#endif
// Leave the frame and return popping the arguments and the // Leave the frame and return popping the arguments and the
// receiver. // receiver.
...@@ -3719,7 +3719,6 @@ void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { ...@@ -3719,7 +3719,6 @@ void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
} }
} }
// The last instruction emitted was a jump, either to the default // The last instruction emitted was a jump, either to the default
// clause or the break target, or else to a case body from the loop // clause or the break target, or else to a case body from the loop
// that compiles the tests. // that compiles the tests.
...@@ -3807,8 +3806,8 @@ void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) { ...@@ -3807,8 +3806,8 @@ void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) {
// Compile the test. // Compile the test.
switch (info) { switch (info) {
case ALWAYS_TRUE: case ALWAYS_TRUE:
// If control flow can fall off the end of the body, jump back to // If control flow can fall off the end of the body, jump back
// the top and bind the break target at the exit. // to the top and bind the break target at the exit.
if (has_valid_frame()) { if (has_valid_frame()) {
node->continue_target()->Jump(); node->continue_target()->Jump();
} }
...@@ -3844,6 +3843,8 @@ void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) { ...@@ -3844,6 +3843,8 @@ void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) {
} }
DecrementLoopNesting(); DecrementLoopNesting();
node->continue_target()->Unuse();
node->break_target()->Unuse();
} }
...@@ -3928,8 +3929,8 @@ void CodeGenerator::VisitWhileStatement(WhileStatement* node) { ...@@ -3928,8 +3929,8 @@ void CodeGenerator::VisitWhileStatement(WhileStatement* node) {
break; break;
case DONT_KNOW: case DONT_KNOW:
if (test_at_bottom) { if (test_at_bottom) {
// If we have chosen to recompile the test at the bottom, then // If we have chosen to recompile the test at the bottom,
// it is the continue target. // then it is the continue target.
if (node->continue_target()->is_linked()) { if (node->continue_target()->is_linked()) {
node->continue_target()->Bind(); node->continue_target()->Bind();
} }
...@@ -4045,6 +4046,7 @@ void CodeGenerator::VisitForStatement(ForStatement* node) { ...@@ -4045,6 +4046,7 @@ void CodeGenerator::VisitForStatement(ForStatement* node) {
node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY); node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
loop.Bind(); loop.Bind();
} }
// Compile the test with the body as the true target and preferred // Compile the test with the body as the true target and preferred
// fall-through and with the break target as the false target. // fall-through and with the break target as the false target.
ControlDestination dest(&body, node->break_target(), true); ControlDestination dest(&body, node->break_target(), true);
...@@ -4154,8 +4156,8 @@ void CodeGenerator::VisitForStatement(ForStatement* node) { ...@@ -4154,8 +4156,8 @@ void CodeGenerator::VisitForStatement(ForStatement* node) {
break; break;
} }
// The break target may be already bound (by the condition), or // The break target may be already bound (by the condition), or there
// there may not be a valid frame. Bind it only if needed. // may not be a valid frame. Bind it only if needed.
if (node->break_target()->is_linked()) { if (node->break_target()->is_linked()) {
node->break_target()->Bind(); node->break_target()->Bind();
} }
......
...@@ -139,7 +139,7 @@ CodeGenState::~CodeGenState() { ...@@ -139,7 +139,7 @@ CodeGenState::~CodeGenState() {
} }
// ----------------------------------------------------------------------------- // -------------------------------------------------------------------------
// CodeGenerator implementation. // CodeGenerator implementation.
CodeGenerator::CodeGenerator(MacroAssembler* masm) CodeGenerator::CodeGenerator(MacroAssembler* masm)
...@@ -155,6 +155,12 @@ CodeGenerator::CodeGenerator(MacroAssembler* masm) ...@@ -155,6 +155,12 @@ CodeGenerator::CodeGenerator(MacroAssembler* masm)
} }
// Calling conventions:
// rbp: caller's frame pointer
// rsp: stack pointer
// rdi: called JS function
// rsi: callee's context
void CodeGenerator::Generate(CompilationInfo* info) { void CodeGenerator::Generate(CompilationInfo* info) {
// Record the position for debugging purposes. // Record the position for debugging purposes.
CodeForFunctionPosition(info->function()); CodeForFunctionPosition(info->function());
...@@ -171,7 +177,7 @@ void CodeGenerator::Generate(CompilationInfo* info) { ...@@ -171,7 +177,7 @@ void CodeGenerator::Generate(CompilationInfo* info) {
// Adjust for function-level loop nesting. // Adjust for function-level loop nesting.
ASSERT_EQ(0, loop_nesting_); ASSERT_EQ(0, loop_nesting_);
loop_nesting_ += info->loop_nesting(); loop_nesting_ = info->loop_nesting();
JumpTarget::set_compiling_deferred_code(false); JumpTarget::set_compiling_deferred_code(false);
...@@ -432,7 +438,7 @@ Operand CodeGenerator::SlotOperand(Slot* slot, Register tmp) { ...@@ -432,7 +438,7 @@ Operand CodeGenerator::SlotOperand(Slot* slot, Register tmp) {
default: default:
UNREACHABLE(); UNREACHABLE();
return Operand(rsp, 0); return Operand(rax);
} }
} }
...@@ -469,14 +475,14 @@ Operand CodeGenerator::ContextSlotOperandCheckExtensions(Slot* slot, ...@@ -469,14 +475,14 @@ Operand CodeGenerator::ContextSlotOperandCheckExtensions(Slot* slot,
// frame. If the expression is boolean-valued it may be compiled (or // frame. If the expression is boolean-valued it may be compiled (or
// partially compiled) into control flow to the control destination. // partially compiled) into control flow to the control destination.
// If force_control is true, control flow is forced. // If force_control is true, control flow is forced.
void CodeGenerator::LoadCondition(Expression* x, void CodeGenerator::LoadCondition(Expression* expr,
ControlDestination* dest, ControlDestination* dest,
bool force_control) { bool force_control) {
ASSERT(!in_spilled_code()); ASSERT(!in_spilled_code());
int original_height = frame_->height(); int original_height = frame_->height();
{ CodeGenState new_state(this, dest); { CodeGenState new_state(this, dest);
Visit(x); Visit(expr);
// If we hit a stack overflow, we may not have actually visited // If we hit a stack overflow, we may not have actually visited
// the expression. In that case, we ensure that we have a // the expression. In that case, we ensure that we have a
...@@ -496,7 +502,6 @@ void CodeGenerator::LoadCondition(Expression* x, ...@@ -496,7 +502,6 @@ void CodeGenerator::LoadCondition(Expression* x,
if (force_control && !dest->is_used()) { if (force_control && !dest->is_used()) {
// Convert the TOS value into flow to the control destination. // Convert the TOS value into flow to the control destination.
// TODO(X64): Make control flow to control destinations work.
ToBoolean(dest); ToBoolean(dest);
} }
...@@ -506,7 +511,6 @@ void CodeGenerator::LoadCondition(Expression* x, ...@@ -506,7 +511,6 @@ void CodeGenerator::LoadCondition(Expression* x,
void CodeGenerator::LoadAndSpill(Expression* expression) { void CodeGenerator::LoadAndSpill(Expression* expression) {
// TODO(x64): No architecture specific code. Move to shared location.
ASSERT(in_spilled_code()); ASSERT(in_spilled_code());
set_in_spilled_code(false); set_in_spilled_code(false);
Load(expression); Load(expression);
...@@ -652,7 +656,6 @@ Result CodeGenerator::StoreArgumentsObject(bool initial) { ...@@ -652,7 +656,6 @@ Result CodeGenerator::StoreArgumentsObject(bool initial) {
frame_->Push(&result); frame_->Push(&result);
} }
Variable* arguments = scope()->arguments()->var(); Variable* arguments = scope()->arguments()->var();
Variable* shadow = scope()->arguments_shadow()->var(); Variable* shadow = scope()->arguments_shadow()->var();
ASSERT(arguments != NULL && arguments->slot() != NULL); ASSERT(arguments != NULL && arguments->slot() != NULL);
...@@ -663,11 +666,11 @@ Result CodeGenerator::StoreArgumentsObject(bool initial) { ...@@ -663,11 +666,11 @@ Result CodeGenerator::StoreArgumentsObject(bool initial) {
// We have to skip storing into the arguments slot if it has // We have to skip storing into the arguments slot if it has
// already been written to. This can happen if the a function // already been written to. This can happen if the a function
// has a local variable named 'arguments'. // has a local variable named 'arguments'.
LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); LoadFromSlot(arguments->slot(), NOT_INSIDE_TYPEOF);
Result probe = frame_->Pop(); Result probe = frame_->Pop();
if (probe.is_constant()) { if (probe.is_constant()) {
// We have to skip updating the arguments object if it has been // We have to skip updating the arguments object if it has
// assigned a proper value. // been assigned a proper value.
skip_arguments = !probe.handle()->IsTheHole(); skip_arguments = !probe.handle()->IsTheHole();
} else { } else {
__ CompareRoot(probe.reg(), Heap::kTheHoleValueRootIndex); __ CompareRoot(probe.reg(), Heap::kTheHoleValueRootIndex);
...@@ -686,9 +689,6 @@ Result CodeGenerator::StoreArgumentsObject(bool initial) { ...@@ -686,9 +689,6 @@ Result CodeGenerator::StoreArgumentsObject(bool initial) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// CodeGenerator implementation of variables, lookups, and stores. // CodeGenerator implementation of variables, lookups, and stores.
//------------------------------------------------------------------------------
// CodeGenerator implementation of variables, lookups, and stores.
Reference::Reference(CodeGenerator* cgen, Reference::Reference(CodeGenerator* cgen,
Expression* expression, Expression* expression,
bool persist_after_get) bool persist_after_get)
...@@ -845,8 +845,8 @@ class FloatingPointHelper : public AllStatic { ...@@ -845,8 +845,8 @@ class FloatingPointHelper : public AllStatic {
const char* GenericBinaryOpStub::GetName() { const char* GenericBinaryOpStub::GetName() {
if (name_ != NULL) return name_; if (name_ != NULL) return name_;
const int len = 100; const int kMaxNameLength = 100;
name_ = Bootstrapper::AllocateAutoDeletedArray(len); name_ = Bootstrapper::AllocateAutoDeletedArray(kMaxNameLength);
if (name_ == NULL) return "OOM"; if (name_ == NULL) return "OOM";
const char* op_name = Token::Name(op_); const char* op_name = Token::Name(op_);
const char* overwrite_name; const char* overwrite_name;
...@@ -857,7 +857,7 @@ const char* GenericBinaryOpStub::GetName() { ...@@ -857,7 +857,7 @@ const char* GenericBinaryOpStub::GetName() {
default: overwrite_name = "UnknownOverwrite"; break; default: overwrite_name = "UnknownOverwrite"; break;
} }
OS::SNPrintF(Vector<char>(name_, len), OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"GenericBinaryOpStub_%s_%s%s_%s%s_%s_%s", "GenericBinaryOpStub_%s_%s%s_%s%s_%s_%s",
op_name, op_name,
overwrite_name, overwrite_name,
...@@ -1138,7 +1138,7 @@ bool CodeGenerator::FoldConstantSmis(Token::Value op, int left, int right) { ...@@ -1138,7 +1138,7 @@ bool CodeGenerator::FoldConstantSmis(Token::Value op, int left, int right) {
if (answer >= Smi::kMinValue && answer <= Smi::kMaxValue) { if (answer >= Smi::kMinValue && answer <= Smi::kMaxValue) {
// If the product is zero and the non-zero factor is negative, // If the product is zero and the non-zero factor is negative,
// the spec requires us to return floating point negative zero. // the spec requires us to return floating point negative zero.
if (answer != 0 || (left + right) >= 0) { if (answer != 0 || (left >= 0 && right >= 0)) {
answer_object = Smi::FromInt(static_cast<int>(answer)); answer_object = Smi::FromInt(static_cast<int>(answer));
} }
} }
...@@ -1645,7 +1645,6 @@ class DeferredInlineSmiSub: public DeferredCode { ...@@ -1645,7 +1645,6 @@ class DeferredInlineSmiSub: public DeferredCode {
}; };
void DeferredInlineSmiSub::Generate() { void DeferredInlineSmiSub::Generate() {
GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, NO_SMI_CODE_IN_STUB); GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, NO_SMI_CODE_IN_STUB);
igostub.GenerateCall(masm_, dst_, value_); igostub.GenerateCall(masm_, dst_, value_);
...@@ -1710,6 +1709,7 @@ Result CodeGenerator::ConstantSmiBinaryOperation(BinaryOperation* expr, ...@@ -1710,6 +1709,7 @@ Result CodeGenerator::ConstantSmiBinaryOperation(BinaryOperation* expr,
} else { } else {
operand->ToRegister(); operand->ToRegister();
frame_->Spill(operand->reg()); frame_->Spill(operand->reg());
answer = *operand;
DeferredCode* deferred = new DeferredInlineSmiSub(operand->reg(), DeferredCode* deferred = new DeferredInlineSmiSub(operand->reg(),
smi_value, smi_value,
overwrite_mode); overwrite_mode);
...@@ -1721,7 +1721,7 @@ Result CodeGenerator::ConstantSmiBinaryOperation(BinaryOperation* expr, ...@@ -1721,7 +1721,7 @@ Result CodeGenerator::ConstantSmiBinaryOperation(BinaryOperation* expr,
smi_value, smi_value,
deferred->entry_label()); deferred->entry_label());
deferred->BindExit(); deferred->BindExit();
answer = *operand; operand->Unuse();
} }
break; break;
} }
...@@ -1932,6 +1932,7 @@ Result CodeGenerator::ConstantSmiBinaryOperation(BinaryOperation* expr, ...@@ -1932,6 +1932,7 @@ Result CodeGenerator::ConstantSmiBinaryOperation(BinaryOperation* expr,
return answer; return answer;
} }
static bool CouldBeNaN(const Result& result) { static bool CouldBeNaN(const Result& result) {
if (result.type_info().IsSmi()) return false; if (result.type_info().IsSmi()) return false;
if (result.type_info().IsInteger32()) return false; if (result.type_info().IsInteger32()) return false;
...@@ -2179,7 +2180,8 @@ void CodeGenerator::Comparison(AstNode* node, ...@@ -2179,7 +2180,8 @@ void CodeGenerator::Comparison(AstNode* node,
} }
} else { } else {
// Neither side is a constant Smi, constant 1-char string, or constant null. // 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. // If either side is a non-smi constant, or known to be a heap number,
// skip the smi check.
bool known_non_smi = bool known_non_smi =
(left_side.is_constant() && !left_side.handle()->IsSmi()) || (left_side.is_constant() && !left_side.handle()->IsSmi()) ||
(right_side.is_constant() && !right_side.handle()->IsSmi()) || (right_side.is_constant() && !right_side.handle()->IsSmi()) ||
...@@ -2205,6 +2207,7 @@ void CodeGenerator::Comparison(AstNode* node, ...@@ -2205,6 +2207,7 @@ void CodeGenerator::Comparison(AstNode* node,
bool inline_number_compare = bool inline_number_compare =
loop_nesting() > 0 && cc != equal && !is_loop_condition; loop_nesting() > 0 && cc != equal && !is_loop_condition;
// Left and right needed in registers for the following code.
left_side.ToRegister(); left_side.ToRegister();
right_side.ToRegister(); right_side.ToRegister();
...@@ -2222,6 +2225,8 @@ void CodeGenerator::Comparison(AstNode* node, ...@@ -2222,6 +2225,8 @@ void CodeGenerator::Comparison(AstNode* node,
GenerateInlineNumberComparison(&left_side, &right_side, cc, dest); GenerateInlineNumberComparison(&left_side, &right_side, cc, dest);
} }
// End of in-line compare, call out to the compare stub. Don't include
// number comparison in the stub if it was inlined.
CompareStub stub(cc, strict, nan_info, !inline_number_compare); CompareStub stub(cc, strict, nan_info, !inline_number_compare);
Result answer = frame_->CallStub(&stub, &left_side, &right_side); Result answer = frame_->CallStub(&stub, &left_side, &right_side);
__ testq(answer.reg(), answer.reg()); // Sets both zero and sign flag. __ testq(answer.reg(), answer.reg()); // Sets both zero and sign flag.
...@@ -2252,6 +2257,8 @@ void CodeGenerator::Comparison(AstNode* node, ...@@ -2252,6 +2257,8 @@ void CodeGenerator::Comparison(AstNode* node,
GenerateInlineNumberComparison(&left_side, &right_side, cc, dest); GenerateInlineNumberComparison(&left_side, &right_side, cc, dest);
} }
// End of in-line compare, call out to the compare stub. Don't include
// number comparison in the stub if it was inlined.
CompareStub stub(cc, strict, nan_info, !inline_number_compare); CompareStub stub(cc, strict, nan_info, !inline_number_compare);
Result answer = frame_->CallStub(&stub, &left_side, &right_side); Result answer = frame_->CallStub(&stub, &left_side, &right_side);
__ testq(answer.reg(), answer.reg()); // Sets both zero and sign flags. __ testq(answer.reg(), answer.reg()); // Sets both zero and sign flags.
...@@ -2704,7 +2711,6 @@ void CodeGenerator::CheckStack() { ...@@ -2704,7 +2711,6 @@ void CodeGenerator::CheckStack() {
void CodeGenerator::VisitAndSpill(Statement* statement) { void CodeGenerator::VisitAndSpill(Statement* statement) {
// TODO(X64): No architecture specific code. Move to shared location.
ASSERT(in_spilled_code()); ASSERT(in_spilled_code());
set_in_spilled_code(false); set_in_spilled_code(false);
Visit(statement); Visit(statement);
...@@ -2716,6 +2722,9 @@ void CodeGenerator::VisitAndSpill(Statement* statement) { ...@@ -2716,6 +2722,9 @@ void CodeGenerator::VisitAndSpill(Statement* statement) {
void CodeGenerator::VisitStatementsAndSpill(ZoneList<Statement*>* statements) { void CodeGenerator::VisitStatementsAndSpill(ZoneList<Statement*>* statements) {
#ifdef DEBUG
int original_height = frame_->height();
#endif
ASSERT(in_spilled_code()); ASSERT(in_spilled_code());
set_in_spilled_code(false); set_in_spilled_code(false);
VisitStatements(statements); VisitStatements(statements);
...@@ -2723,14 +2732,20 @@ void CodeGenerator::VisitStatementsAndSpill(ZoneList<Statement*>* statements) { ...@@ -2723,14 +2732,20 @@ void CodeGenerator::VisitStatementsAndSpill(ZoneList<Statement*>* statements) {
frame_->SpillAll(); frame_->SpillAll();
} }
set_in_spilled_code(true); set_in_spilled_code(true);
ASSERT(!has_valid_frame() || frame_->height() == original_height);
} }
void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
#ifdef DEBUG
int original_height = frame_->height();
#endif
ASSERT(!in_spilled_code()); ASSERT(!in_spilled_code());
for (int i = 0; has_valid_frame() && i < statements->length(); i++) { for (int i = 0; has_valid_frame() && i < statements->length(); i++) {
Visit(statements->at(i)); Visit(statements->at(i));
} }
ASSERT(!has_valid_frame() || frame_->height() == original_height);
} }
...@@ -2966,6 +2981,7 @@ void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { ...@@ -2966,6 +2981,7 @@ void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
CodeForStatementPosition(node); CodeForStatementPosition(node);
Load(node->expression()); Load(node->expression());
Result return_value = frame_->Pop(); Result return_value = frame_->Pop();
masm()->WriteRecordedPositions();
if (function_return_is_shadowed_) { if (function_return_is_shadowed_) {
function_return_.Jump(&return_value); function_return_.Jump(&return_value);
} else { } else {
...@@ -3003,6 +3019,8 @@ void CodeGenerator::GenerateReturnSequence(Result* return_value) { ...@@ -3003,6 +3019,8 @@ void CodeGenerator::GenerateReturnSequence(Result* return_value) {
// receiver. // receiver.
frame_->Exit(); frame_->Exit();
masm_->ret((scope()->num_parameters() + 1) * kPointerSize); masm_->ret((scope()->num_parameters() + 1) * kPointerSize);
DeleteFrame();
#ifdef ENABLE_DEBUGGER_SUPPORT #ifdef ENABLE_DEBUGGER_SUPPORT
// Add padding that will be overwritten by a debugger breakpoint. // Add padding that will be overwritten by a debugger breakpoint.
// frame_->Exit() generates "movq rsp, rbp; pop rbp; ret k" // frame_->Exit() generates "movq rsp, rbp; pop rbp; ret k"
...@@ -3016,7 +3034,6 @@ void CodeGenerator::GenerateReturnSequence(Result* return_value) { ...@@ -3016,7 +3034,6 @@ void CodeGenerator::GenerateReturnSequence(Result* return_value) {
ASSERT_EQ(Assembler::kJSReturnSequenceLength, ASSERT_EQ(Assembler::kJSReturnSequenceLength,
masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
#endif #endif
DeleteFrame();
} }
...@@ -3055,8 +3072,6 @@ void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) { ...@@ -3055,8 +3072,6 @@ void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
// TODO(X64): This code is completely generic and should be moved somewhere
// where it can be shared between architectures.
ASSERT(!in_spilled_code()); ASSERT(!in_spilled_code());
Comment cmnt(masm_, "[ SwitchStatement"); Comment cmnt(masm_, "[ SwitchStatement");
CodeForStatementPosition(node); CodeForStatementPosition(node);
...@@ -3348,8 +3363,8 @@ void CodeGenerator::VisitWhileStatement(WhileStatement* node) { ...@@ -3348,8 +3363,8 @@ void CodeGenerator::VisitWhileStatement(WhileStatement* node) {
LoadCondition(node->cond(), &dest, true); LoadCondition(node->cond(), &dest, true);
} }
} else { } else {
// If we have chosen not to recompile the test at the // If we have chosen not to recompile the test at the bottom,
// bottom, jump back to the one at the top. // jump back to the one at the top.
if (has_valid_frame()) { if (has_valid_frame()) {
node->continue_target()->Jump(); node->continue_target()->Jump();
} }
...@@ -3911,6 +3926,7 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) { ...@@ -3911,6 +3926,7 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) {
node->break_target()->Unuse(); node->break_target()->Unuse();
} }
void CodeGenerator::VisitTryCatchStatement(TryCatchStatement* node) { void CodeGenerator::VisitTryCatchStatement(TryCatchStatement* node) {
ASSERT(!in_spilled_code()); ASSERT(!in_spilled_code());
VirtualFrame::SpilledScope spilled_scope; VirtualFrame::SpilledScope spilled_scope;
......
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