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

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

Issue 115233: Don't go into runtime system for the allocation of floating point... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 7 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/arm/codegen-arm.cc
===================================================================
--- src/arm/codegen-arm.cc (revision 1905)
+++ src/arm/codegen-arm.cc (working copy)
@@ -4335,6 +4335,45 @@
}
+static void AllocateHeapNumber(
+ MacroAssembler* masm,
+ Label* need_gc, // Jump here if young space is full.
+ Register result_reg, // The tagged address of the new heap number.
+ Register allocation_top_addr_reg, // A scratch register.
+ Register scratch2) { // Another scratch register.
+ ExternalReference allocation_top =
+ ExternalReference::new_space_allocation_top_address();
+ ExternalReference allocation_limit =
+ ExternalReference::new_space_allocation_limit_address();
+
+ // allocat := the address of the allocation top variable.
+ __ mov(allocation_top_addr_reg, Operand(allocation_top));
+ // result_reg := the old allocation top.
+ __ ldr(result_reg, MemOperand(allocation_top_addr_reg));
+ // scratch2 := the address of the allocation limit.
+ __ mov(scratch2, Operand(allocation_limit));
+ // scratch2 := the allocation limit.
+ __ ldr(scratch2, MemOperand(scratch2));
+ // result_reg := the new allocation top.
+ __ add(result_reg, result_reg, Operand(HeapNumber::kSize));
+ // Compare new new allocation top and limit.
+ __ cmp(result_reg, Operand(scratch2));
+ // Branch if out of space in young generation.
+ __ b(hi, need_gc);
+ // Store new allocation top.
+ __ str(result_reg, MemOperand(allocation_top_addr_reg)); // store new top
+ // Tag and adjust back to start of new object.
+ __ sub(result_reg, result_reg, Operand(HeapNumber::kSize - kHeapObjectTag));
+ // Get heap number map into scratch2.
+ __ mov(scratch2, Operand(Factory::heap_number_map()));
+ // Store heap number map in new object.
+ __ str(scratch2, FieldMemOperand(result_reg, HeapObject::kMapOffset));
+}
+
+
+// We fall into this code if the operands were Smis, but the result was
+// not (eg. overflow). We branch into this code (to the not_smi label) if
+// the operands were not both Smi.
static void HandleBinaryOpSlowCases(MacroAssembler* masm,
Label* not_smi,
const Builtins::JavaScript& builtin,
@@ -4342,73 +4381,74 @@
int swi_number,
OverwriteMode mode) {
Label slow;
- if (mode == NO_OVERWRITE) {
- __ bind(not_smi);
- }
__ bind(&slow);
__ push(r1);
__ push(r0);
__ mov(r0, Operand(1)); // Set number of arguments.
__ InvokeBuiltin(builtin, JUMP_JS); // Tail call.
- // Could it be a double-double op? If we already have a place to put
- // the answer then we can do the op and skip the builtin and runtime call.
- if (mode != NO_OVERWRITE) {
- __ bind(not_smi);
- __ tst(r0, Operand(kSmiTagMask));
- __ b(eq, &slow); // We can't handle a Smi-double combination yet.
- __ tst(r1, Operand(kSmiTagMask));
- __ b(eq, &slow); // We can't handle a Smi-double combination yet.
- // Get map of r0 into r2.
- __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
- // Get type of r0 into r3.
- __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceTypeOffset));
- __ cmp(r3, Operand(HEAP_NUMBER_TYPE));
- __ b(ne, &slow);
- // Get type of r1 into r3.
- __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
- // Check they are both the same map (heap number map).
- __ cmp(r2, r3);
- __ b(ne, &slow);
- // Both are doubles.
- // Calling convention says that second double is in r2 and r3.
- __ ldr(r2, FieldMemOperand(r0, HeapNumber::kValueOffset));
- __ ldr(r3, FieldMemOperand(r0, HeapNumber::kValueOffset + kPointerSize));
+ __ bind(not_smi);
+ __ tst(r0, Operand(kSmiTagMask));
+ __ b(eq, &slow); // We can't handle a Smi-double combination yet.
+ __ tst(r1, Operand(kSmiTagMask));
+ __ b(eq, &slow); // We can't handle a Smi-double combination yet.
+ // Get map of r0 into r2.
+ __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
+ // Get type of r0 into r3.
+ __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceTypeOffset));
+ __ cmp(r3, Operand(HEAP_NUMBER_TYPE));
+ __ b(ne, &slow);
+ // Get type of r1 into r3.
+ __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
+ // Check they are both the same map (heap number map).
+ __ cmp(r2, r3);
+ __ b(ne, &slow);
+ // Both are doubles.
+ // Calling convention says that second double is in r2 and r3.
+ __ ldr(r2, FieldMemOperand(r0, HeapNumber::kValueOffset));
+ __ ldr(r3, FieldMemOperand(r0, HeapNumber::kValueOffset + kPointerSize));
+
+ if (mode == NO_OVERWRITE) {
+ // Get address of new heap number into r5.
+ AllocateHeapNumber(masm, &slow, r5, r6, r7);
__ push(lr);
- if (mode == OVERWRITE_LEFT) {
- __ push(r1);
- } else {
- __ push(r0);
- }
- // Calling convention says that first double is in r0 and r1.
- __ ldr(r0, FieldMemOperand(r1, HeapNumber::kValueOffset));
- __ ldr(r1, FieldMemOperand(r1, HeapNumber::kValueOffset + kPointerSize));
- // Call C routine that may not cause GC or other trouble.
- __ mov(r5, Operand(ExternalReference::double_fp_operation(operation)));
+ __ push(r5);
+ } else if (mode == OVERWRITE_LEFT) {
+ __ push(lr);
+ __ push(r1);
+ } else {
+ ASSERT(mode == OVERWRITE_RIGHT);
+ __ push(lr);
+ __ push(r0);
+ }
+ // Calling convention says that first double is in r0 and r1.
+ __ ldr(r0, FieldMemOperand(r1, HeapNumber::kValueOffset));
+ __ ldr(r1, FieldMemOperand(r1, HeapNumber::kValueOffset + kPointerSize));
+ // Call C routine that may not cause GC or other trouble.
+ __ mov(r5, Operand(ExternalReference::double_fp_operation(operation)));
#if !defined(__arm__)
- // Notify the simulator that we are calling an add routine in C.
- __ swi(swi_number);
+ // Notify the simulator that we are calling an add routine in C.
+ __ swi(swi_number);
#else
- // Actually call the add routine written in C.
- __ Call(r5);
+ // Actually call the add routine written in C.
+ __ Call(r5);
#endif
- // Store answer in the overwritable heap number.
- __ pop(r4);
+ // Store answer in the overwritable heap number.
+ __ pop(r4);
#if !defined(__ARM_EABI__) && defined(__arm__)
- // Double returned in fp coprocessor register 0 and 1, encoded as register
- // cr8. Offsets must be divisible by 4 for coprocessor so we need to
- // substract the tag from r4.
- __ sub(r5, r4, Operand(kHeapObjectTag));
- __ stc(p1, cr8, MemOperand(r5, HeapNumber::kValueOffset));
+ // Double returned in fp coprocessor register 0 and 1, encoded as register
+ // cr8. Offsets must be divisible by 4 for coprocessor so we need to
+ // substract the tag from r4.
+ __ sub(r5, r4, Operand(kHeapObjectTag));
+ __ stc(p1, cr8, MemOperand(r5, HeapNumber::kValueOffset));
#else
- // Double returned in fp coprocessor register 0 and 1.
- __ str(r0, FieldMemOperand(r4, HeapNumber::kValueOffset));
- __ str(r1, FieldMemOperand(r4, HeapNumber::kValueOffset + kPointerSize));
+ // Double returned in fp coprocessor register 0 and 1.
+ __ str(r0, FieldMemOperand(r4, HeapNumber::kValueOffset));
+ __ str(r1, FieldMemOperand(r4, HeapNumber::kValueOffset + kPointerSize));
#endif
- __ mov(r0, Operand(r4));
- // And we are done.
- __ pop(pc);
- }
+ __ mov(r0, Operand(r4));
+ // And we are done.
+ __ pop(pc);
}
« 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