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

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

Issue 2814021: X64: Reapply fix for allocating HeapNumber results for >>>. (Closed)
Patch Set: Addressed review comments. Created 10 years, 6 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 | « no previous file | 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 8e6b66fea26ddbb20106b65b501bd0b27031c99e..f5759b276d1c47d7249047a57ffecb0e5a7170f3 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -274,7 +274,11 @@ class FloatingPointHelper : public AllStatic {
// Takes the operands in rdx and rax and loads them as integers in rax
// and rcx.
static void LoadAsIntegers(MacroAssembler* masm,
- Label* operand_conversion_failure);
+ Label* operand_conversion_failure,
+ Register heap_number_map);
+ // As above, but we know the operands to be numbers. In that case,
+ // conversion can't fail.
+ static void LoadNumbersAsIntegers(MacroAssembler* masm);
};
@@ -9928,6 +9932,13 @@ void FloatingPointHelper::LoadSSE2SmiOperands(MacroAssembler* masm) {
void FloatingPointHelper::LoadSSE2NumberOperands(MacroAssembler* masm) {
+ if (FLAG_debug_code) {
+ // Both arguments can not be smis. That case is handled by smi-only code.
+ Label ok;
+ __ JumpIfNotBothSmi(rax, rdx, &ok);
+ __ Abort("Both arguments smi but not handled by smi-code.");
+ __ bind(&ok);
+ }
Label load_smi_rdx, load_nonsmi_rax, load_smi_rax, done;
// Load operand in rdx into xmm0.
__ JumpIfSmi(rdx, &load_smi_rdx);
@@ -9941,7 +9952,7 @@ void FloatingPointHelper::LoadSSE2NumberOperands(MacroAssembler* masm) {
__ bind(&load_smi_rdx);
__ SmiToInteger32(kScratchRegister, rdx);
__ cvtlsi2sd(xmm0, kScratchRegister);
- __ JumpIfNotSmi(rax, &load_nonsmi_rax);
+ __ jmp(&load_nonsmi_rax);
__ bind(&load_smi_rax);
__ SmiToInteger32(kScratchRegister, rax);
@@ -9984,7 +9995,8 @@ void FloatingPointHelper::LoadSSE2UnknownOperands(MacroAssembler* masm,
// Input: rdx, rax are the left and right objects of a bit op.
// Output: rax, rcx are left and right integers for a bit op.
void FloatingPointHelper::LoadAsIntegers(MacroAssembler* masm,
- Label* conversion_failure) {
+ Label* conversion_failure,
+ Register heap_number_map) {
// Check float operands.
Label arg1_is_object, check_undefined_arg1;
Label arg2_is_object, check_undefined_arg2;
@@ -10002,8 +10014,7 @@ void FloatingPointHelper::LoadAsIntegers(MacroAssembler* masm,
__ jmp(&load_arg2);
__ bind(&arg1_is_object);
- __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
- __ CompareRoot(rbx, Heap::kHeapNumberMapRootIndex);
+ __ cmpq(FieldOperand(rdx, HeapObject::kMapOffset), heap_number_map);
__ j(not_equal, &check_undefined_arg1);
// Get the untagged integer version of the edx heap number in rcx.
IntegerConvert(masm, rdx, rdx);
@@ -10024,8 +10035,7 @@ void FloatingPointHelper::LoadAsIntegers(MacroAssembler* masm,
__ jmp(&done);
__ bind(&arg2_is_object);
- __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
- __ CompareRoot(rbx, Heap::kHeapNumberMapRootIndex);
+ __ cmpq(FieldOperand(rax, HeapObject::kMapOffset), heap_number_map);
__ j(not_equal, &check_undefined_arg2);
// Get the untagged integer version of the eax heap number in ecx.
IntegerConvert(masm, rcx, rax);
@@ -10034,6 +10044,41 @@ void FloatingPointHelper::LoadAsIntegers(MacroAssembler* masm,
}
+// Input: rdx, rax are the left and right objects of a bit op.
+// Output: rax, rcx are left and right integers for a bit op.
+void FloatingPointHelper::LoadNumbersAsIntegers(MacroAssembler* masm) {
+ if (FLAG_debug_code) {
+ // Both arguments can not be smis. That case is handled by smi-only code.
+ Label ok;
+ __ JumpIfNotBothSmi(rax, rdx, &ok);
+ __ Abort("Both arguments smi but not handled by smi-code.");
+ __ bind(&ok);
+ }
+ // Check float operands.
+ Label done;
+ Label rax_is_object;
+ Label rdx_is_object;
+ Label rax_is_smi;
+ Label rdx_is_smi;
+
+ __ JumpIfNotSmi(rdx, &rdx_is_object);
+ __ SmiToInteger32(rdx, rdx);
+
+ __ bind(&rax_is_object);
+ IntegerConvert(masm, rcx, rax); // Uses rdi, rcx and rbx.
+ __ jmp(&done);
+
+ __ bind(&rdx_is_object);
+ IntegerConvert(masm, rdx, rdx); // Uses rdi, rcx and rbx.
+ __ JumpIfNotSmi(rax, &rax_is_object);
+ __ bind(&rax_is_smi);
+ __ SmiToInteger32(rcx, rax);
+
+ __ bind(&done);
+ __ movl(rax, rdx);
+}
+
+
const char* GenericBinaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int len = 100;
@@ -10487,34 +10532,52 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
case Token::SAR:
case Token::SHL:
case Token::SHR: {
- Label skip_allocation, non_smi_result;
- FloatingPointHelper::LoadAsIntegers(masm, &call_runtime);
+ Label skip_allocation, non_smi_shr_result;
+ Register heap_number_map = r9;
+ __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
+ if (static_operands_type_.IsNumber()) {
+ if (FLAG_debug_code) {
+ // Assert at runtime that inputs are only numbers.
+ __ AbortIfNotNumber(rdx);
+ __ AbortIfNotNumber(rax);
+ }
+ FloatingPointHelper::LoadNumbersAsIntegers(masm);
+ } else {
+ FloatingPointHelper::LoadAsIntegers(masm,
+ &call_runtime,
+ heap_number_map);
+ }
switch (op_) {
case Token::BIT_OR: __ orl(rax, rcx); break;
case Token::BIT_AND: __ andl(rax, rcx); break;
case Token::BIT_XOR: __ xorl(rax, rcx); break;
case Token::SAR: __ sarl_cl(rax); break;
case Token::SHL: __ shll_cl(rax); break;
- case Token::SHR: __ shrl_cl(rax); break;
+ case Token::SHR: {
+ __ shrl_cl(rax);
+ // Check if result is negative. This can only happen for a shift
+ // by zero.
+ __ testl(rax, rax);
+ __ j(negative, &non_smi_shr_result);
+ break;
+ }
default: UNREACHABLE();
}
- if (op_ == Token::SHR) {
- // Check if result is negative. This can only happen for a shift
- // by zero, which also doesn't update the sign flag.
- __ testl(rax, rax);
- __ j(negative, &non_smi_result);
- }
- __ JumpIfNotValidSmiValue(rax, &non_smi_result);
- // Tag smi result, if possible, and return.
+
+ STATIC_ASSERT(kSmiValueSize == 32);
+ // Tag smi result and return.
__ Integer32ToSmi(rax, rax);
GenerateReturn(masm);
- // All ops except SHR return a signed int32 that we load in
- // a HeapNumber.
- if (op_ != Token::SHR && non_smi_result.is_linked()) {
- __ bind(&non_smi_result);
+ // All bit-ops except SHR return a signed int32 that can be
+ // returned immediately as a smi.
+ // We might need to allocate a HeapNumber if we shift a negative
+ // number right by zero (i.e., convert to UInt32).
+ if (op_ == Token::SHR) {
+ ASSERT(non_smi_shr_result.is_linked());
+ __ bind(&non_smi_shr_result);
// Allocate a heap number if needed.
- __ movsxlq(rbx, rax); // rbx: sign extended 32-bit result
+ __ movl(rbx, rax); // rbx holds result value (uint32 value as int64).
switch (mode_) {
case OVERWRITE_LEFT:
case OVERWRITE_RIGHT:
@@ -10525,22 +10588,33 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
__ JumpIfNotSmi(rax, &skip_allocation);
// Fall through!
case NO_OVERWRITE:
- __ AllocateHeapNumber(rax, rcx, &call_runtime);
+ // Allocate heap number in new space.
+ // Not using AllocateHeapNumber macro in order to reuse
+ // already loaded heap_number_map.
+ __ AllocateInNewSpace(HeapNumber::kSize,
+ rax,
+ rcx,
+ no_reg,
+ &call_runtime,
+ TAG_OBJECT);
+ // Set the map.
+ if (FLAG_debug_code) {
+ __ AbortIfNotRootValue(heap_number_map,
+ Heap::kHeapNumberMapRootIndex,
+ "HeapNumberMap register clobbered.");
+ }
+ __ movq(FieldOperand(rax, HeapObject::kMapOffset),
+ heap_number_map);
__ bind(&skip_allocation);
break;
default: UNREACHABLE();
}
// Store the result in the HeapNumber and return.
- __ movq(Operand(rsp, 1 * kPointerSize), rbx);
- __ fild_s(Operand(rsp, 1 * kPointerSize));
- __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset));
+ __ cvtqsi2sd(xmm0, rbx);
+ __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0);
GenerateReturn(masm);
}
- // SHR should return uint32 - go to runtime for non-smi/negative result.
- if (op_ == Token::SHR) {
- __ bind(&non_smi_result);
- }
break;
}
default: UNREACHABLE(); break;
@@ -10573,7 +10647,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
Label not_strings, both_strings, not_string1, string1, string1_smi2;
// If this stub has already generated FP-specific code then the arguments
- // are already in rdx, rax
+ // are already in rdx and rax.
if (!ShouldGenerateFPCode() && !HasArgsInRegisters()) {
GenerateLoadArguments(masm);
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698