diff options
Diffstat (limited to 'V8Binding/v8/src/arm/macro-assembler-arm.cc')
-rw-r--r-- | V8Binding/v8/src/arm/macro-assembler-arm.cc | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/V8Binding/v8/src/arm/macro-assembler-arm.cc b/V8Binding/v8/src/arm/macro-assembler-arm.cc index 65c2a3e..c77209e 100644 --- a/V8Binding/v8/src/arm/macro-assembler-arm.cc +++ b/V8Binding/v8/src/arm/macro-assembler-arm.cc @@ -768,11 +768,139 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, } +void MacroAssembler::AllocateObjectInNewSpace(int object_size, + Register result, + Register scratch1, + Register scratch2, + Label* gc_required, + AllocationFlags flags) { + ASSERT(!result.is(scratch1)); + ASSERT(!scratch1.is(scratch2)); + + // Load address of new object into result and allocation top address into + // scratch1. + ExternalReference new_space_allocation_top = + ExternalReference::new_space_allocation_top_address(); + mov(scratch1, Operand(new_space_allocation_top)); + if ((flags & RESULT_CONTAINS_TOP) == 0) { + ldr(result, MemOperand(scratch1)); + } else { +#ifdef DEBUG + // Assert that result actually contains top on entry. scratch2 is used + // immediately below so this use of scratch2 does not cause difference with + // respect to register content between debug and release mode. + ldr(scratch2, MemOperand(scratch1)); + cmp(result, scratch2); + Check(eq, "Unexpected allocation top"); +#endif + } + + // Calculate new top and bail out if new space is exhausted. Use result + // to calculate the new top. + ExternalReference new_space_allocation_limit = + ExternalReference::new_space_allocation_limit_address(); + mov(scratch2, Operand(new_space_allocation_limit)); + ldr(scratch2, MemOperand(scratch2)); + add(result, result, Operand(object_size * kPointerSize)); + cmp(result, Operand(scratch2)); + b(hi, gc_required); + + // Update allocation top. result temporarily holds the new top, + str(result, MemOperand(scratch1)); + + // Tag and adjust back to start of new object. + if ((flags & TAG_OBJECT) != 0) { + sub(result, result, Operand((object_size * kPointerSize) - + kHeapObjectTag)); + } else { + sub(result, result, Operand(object_size * kPointerSize)); + } +} + + +void MacroAssembler::AllocateObjectInNewSpace(Register object_size, + Register result, + Register scratch1, + Register scratch2, + Label* gc_required, + AllocationFlags flags) { + ASSERT(!result.is(scratch1)); + ASSERT(!scratch1.is(scratch2)); + + // Load address of new object into result and allocation top address into + // scratch1. + ExternalReference new_space_allocation_top = + ExternalReference::new_space_allocation_top_address(); + mov(scratch1, Operand(new_space_allocation_top)); + if ((flags & RESULT_CONTAINS_TOP) == 0) { + ldr(result, MemOperand(scratch1)); + } else { +#ifdef DEBUG + // Assert that result actually contains top on entry. scratch2 is used + // immediately below so this use of scratch2 does not cause difference with + // respect to register content between debug and release mode. + ldr(scratch2, MemOperand(scratch1)); + cmp(result, scratch2); + Check(eq, "Unexpected allocation top"); +#endif + } + + // Calculate new top and bail out if new space is exhausted. Use result + // to calculate the new top. Object size is in words so a shift is required to + // get the number of bytes + ExternalReference new_space_allocation_limit = + ExternalReference::new_space_allocation_limit_address(); + mov(scratch2, Operand(new_space_allocation_limit)); + ldr(scratch2, MemOperand(scratch2)); + add(result, result, Operand(object_size, LSL, kPointerSizeLog2)); + cmp(result, Operand(scratch2)); + b(hi, gc_required); + + // Update allocation top. result temporarily holds the new top, + str(result, MemOperand(scratch1)); + + // Adjust back to start of new object. + sub(result, result, Operand(object_size, LSL, kPointerSizeLog2)); + + // Tag object if requested. + if ((flags & TAG_OBJECT) != 0) { + add(result, result, Operand(kHeapObjectTag)); + } +} + + +void MacroAssembler::UndoAllocationInNewSpace(Register object, + Register scratch) { + ExternalReference new_space_allocation_top = + ExternalReference::new_space_allocation_top_address(); + + // Make sure the object has no tag before resetting top. + and_(object, object, Operand(~kHeapObjectTagMask)); +#ifdef DEBUG + // Check that the object un-allocated is below the current top. + mov(scratch, Operand(new_space_allocation_top)); + ldr(scratch, MemOperand(scratch)); + cmp(object, scratch); + Check(lt, "Undo allocation of non allocated memory"); +#endif + // Write the address of the object to un-allocate as the current top. + mov(scratch, Operand(new_space_allocation_top)); + str(object, MemOperand(scratch)); +} + + void MacroAssembler::CompareObjectType(Register function, Register map, Register type_reg, InstanceType type) { ldr(map, FieldMemOperand(function, HeapObject::kMapOffset)); + CompareInstanceType(map, type_reg, type); +} + + +void MacroAssembler::CompareInstanceType(Register map, + Register type_reg, + InstanceType type) { ldrb(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); cmp(type_reg, Operand(type)); } @@ -1022,4 +1150,5 @@ void MacroAssembler::Abort(const char* msg) { // will not return here } + } } // namespace v8::internal |