// Allocate the JSArray object together with space for a fixed array with the
// requested elements.
int size = JSArray::kSize + FixedArray::SizeFor(initial_capacity);
- __ AllocateInNewSpace(size / kPointerSize,
+ __ AllocateInNewSpace(size,
result,
scratch2,
scratch3,
// keeps the code below free of special casing for the empty array.
int size = JSArray::kSize +
FixedArray::SizeFor(JSArray::kPreallocatedArrayElements);
- __ AllocateInNewSpace(size / kPointerSize,
+ __ AllocateInNewSpace(size,
result,
elements_array_end,
scratch1,
__ add(elements_array_end,
elements_array_end,
Operand(array_size, ASR, kSmiTagSize));
- __ AllocateInNewSpace(elements_array_end,
- result,
- scratch1,
- scratch2,
- gc_required,
- TAG_OBJECT);
+ __ AllocateInNewSpace(
+ elements_array_end,
+ result,
+ scratch1,
+ scratch2,
+ gc_required,
+ static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
// Allocated the JSArray. Now initialize the fields except for the elements
// array.
// r2: initial map
// r7: undefined
__ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset));
- __ AllocateInNewSpace(r3, r4, r5, r6, &rt_call, NO_ALLOCATION_FLAGS);
+ __ AllocateInNewSpace(r3, r4, r5, r6, &rt_call, SIZE_IN_WORDS);
// Allocated the JSObject, now initialize the fields. Map is set to initial
// map and properties and elements are set to empty fixed array.
// r5: start of next object
// r7: undefined
__ add(r0, r3, Operand(FixedArray::kHeaderSize / kPointerSize));
- __ AllocateInNewSpace(r0,
- r5,
- r6,
- r2,
- &undo_allocation,
- RESULT_CONTAINS_TOP);
+ __ AllocateInNewSpace(
+ r0,
+ r5,
+ r6,
+ r2,
+ &undo_allocation,
+ static_cast<AllocationFlags>(RESULT_CONTAINS_TOP | SIZE_IN_WORDS));
// Initialize the FixedArray.
// r1: constructor
(JSRegExpResult::kSize + FixedArray::kHeaderSize) / kPointerSize;
__ mov(r5, Operand(r1, LSR, kSmiTagSize + kSmiShiftSize));
__ add(r2, r5, Operand(objects_size));
- __ AllocateInNewSpace(r2, // In: Size, in words.
- r0, // Out: Start of allocation (tagged).
- r3, // Scratch register.
- r4, // Scratch register.
- &slowcase,
- TAG_OBJECT);
+ __ AllocateInNewSpace(
+ r2, // In: Size, in words.
+ r0, // Out: Start of allocation (tagged).
+ r3, // Scratch register.
+ r4, // Scratch register.
+ &slowcase,
+ static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
// r0: Start of allocated area, object-tagged.
// r1: Number of elements in array, as smi.
// r5: Number of elements, untagged.
__ pop(r3);
// Attempt to allocate new JSFunction in new space.
- __ AllocateInNewSpace(JSFunction::kSize / kPointerSize,
+ __ AllocateInNewSpace(JSFunction::kSize,
r0,
r1,
r2,
int length = slots_ + Context::MIN_CONTEXT_SLOTS;
// Attempt to allocate the context in new space.
- __ AllocateInNewSpace(length + (FixedArray::kHeaderSize / kPointerSize),
+ __ AllocateInNewSpace(FixedArray::SizeFor(length),
r0,
r1,
r2,
// Allocate both the JS array and the elements array in one big
// allocation. This avoids multiple limit checks.
- __ AllocateInNewSpace(size / kPointerSize,
+ __ AllocateInNewSpace(size,
r0,
r1,
r2,
__ str(r3, MemOperand(sp, 1 * kPointerSize));
// Try the new space allocation. Start out with computing the size
- // of the arguments object and the elements array (in words, not
- // bytes because AllocateInNewSpace expects words).
+ // of the arguments object and the elements array in words.
Label add_arguments_object;
__ bind(&try_allocate);
__ cmp(r1, Operand(0));
__ add(r1, r1, Operand(Heap::kArgumentsObjectSize / kPointerSize));
// Do the allocation of both objects in one go.
- __ AllocateInNewSpace(r1, r0, r2, r3, &runtime, TAG_OBJECT);
+ __ AllocateInNewSpace(
+ r1,
+ r0,
+ r2,
+ r3,
+ &runtime,
+ static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
// Get the arguments boilerplate from the current (global) context.
int offset = Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
ASSERT(!result.is(scratch1));
ASSERT(!scratch1.is(scratch2));
+ // Make object size into bytes.
+ if ((flags & SIZE_IN_WORDS) != 0) {
+ object_size *= kPointerSize;
+ }
+ ASSERT_EQ(0, object_size & kObjectAlignmentMask);
+
// Load address of new object into result and allocation top address into
// scratch1.
ExternalReference new_space_allocation_top =
ExternalReference::new_space_allocation_limit_address();
mov(scratch2, Operand(new_space_allocation_limit));
ldr(scratch2, MemOperand(scratch2));
- add(result, result, Operand(object_size * kPointerSize));
+ add(result, result, Operand(object_size));
cmp(result, Operand(scratch2));
b(hi, gc_required);
-
- // Update allocation top. result temporarily holds the new top.
- if (FLAG_debug_code) {
- tst(result, Operand(kObjectAlignmentMask));
- Check(eq, "Unaligned allocation in new space");
- }
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));
+ sub(result, result, Operand(object_size - kHeapObjectTag));
} else {
- sub(result, result, Operand(object_size * kPointerSize));
+ sub(result, result, Operand(object_size));
}
}
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));
+ if ((flags & SIZE_IN_WORDS) != 0) {
+ add(result, result, Operand(object_size, LSL, kPointerSizeLog2));
+ } else {
+ add(result, result, Operand(object_size));
+ }
cmp(result, Operand(scratch2));
b(hi, gc_required);
str(result, MemOperand(scratch1));
// Adjust back to start of new object.
- sub(result, result, Operand(object_size, LSL, kPointerSizeLog2));
+ if ((flags & SIZE_IN_WORDS) != 0) {
+ sub(result, result, Operand(object_size, LSL, kPointerSizeLog2));
+ } else {
+ sub(result, result, Operand(object_size));
+ }
// Tag object if requested.
if ((flags & TAG_OBJECT) != 0) {
mov(scratch1, Operand(length, LSL, 1)); // Length in bytes, not chars.
add(scratch1, scratch1,
Operand(kObjectAlignmentMask + SeqTwoByteString::kHeaderSize));
- // AllocateInNewSpace expects the size in words, so we can round down
- // to kObjectAlignment and divide by kPointerSize in the same shift.
- ASSERT_EQ(kPointerSize, kObjectAlignmentMask + 1);
- mov(scratch1, Operand(scratch1, ASR, kPointerSizeLog2));
+ and_(scratch1, scratch1, Operand(~kObjectAlignmentMask));
// Allocate two-byte string in new space.
AllocateInNewSpace(scratch1,
ASSERT(kCharSize == 1);
add(scratch1, length,
Operand(kObjectAlignmentMask + SeqAsciiString::kHeaderSize));
- // AllocateInNewSpace expects the size in words, so we can round down
- // to kObjectAlignment and divide by kPointerSize in the same shift.
- ASSERT_EQ(kPointerSize, kObjectAlignmentMask + 1);
- mov(scratch1, Operand(scratch1, ASR, kPointerSizeLog2));
+ and_(scratch1, scratch1, Operand(~kObjectAlignmentMask));
// Allocate ASCII string in new space.
AllocateInNewSpace(scratch1,
Register scratch1,
Register scratch2,
Label* gc_required) {
- AllocateInNewSpace(ConsString::kSize / kPointerSize,
+ AllocateInNewSpace(ConsString::kSize,
result,
scratch1,
scratch2,
Register scratch1,
Register scratch2,
Label* gc_required) {
- AllocateInNewSpace(ConsString::kSize / kPointerSize,
+ AllocateInNewSpace(ConsString::kSize,
result,
scratch1,
scratch2,
Label* gc_required) {
// Allocate an object in the heap for the heap number and tag it as a heap
// object.
- AllocateInNewSpace(HeapNumber::kSize / kPointerSize,
+ AllocateInNewSpace(HeapNumber::kSize,
result,
scratch1,
scratch2,
};
+// Flags used for the AllocateInNewSpace functions.
+enum AllocationFlags {
+ // No special flags.
+ NO_ALLOCATION_FLAGS = 0,
+ // Return the pointer to the allocated already tagged as a heap object.
+ TAG_OBJECT = 1 << 0,
+ // The content of the result register already contains the allocation top in
+ // new space.
+ RESULT_CONTAINS_TOP = 1 << 1,
+ // Specify that the requested size of the space to allocate is specified in
+ // words instead of bytes.
+ SIZE_IN_WORDS = 1 << 2
+};
+
+
// MacroAssembler implements a collection of frequently used macros.
class MacroAssembler: public Assembler {
public:
r5,
r6,
&generic_stub_call,
- NO_ALLOCATION_FLAGS);
+ SIZE_IN_WORDS);
// Allocated the JSObject, now initialize the fields. Map is set to initial
// map and properties and elements are set to empty fixed array.
namespace v8 {
namespace internal {
+// Flags used for the AllocateInNewSpace functions.
+enum AllocationFlags {
+ // No special flags.
+ NO_ALLOCATION_FLAGS = 0,
+ // Return the pointer to the allocated already tagged as a heap object.
+ TAG_OBJECT = 1 << 0,
+ // The content of the result register already contains the allocation top in
+ // new space.
+ RESULT_CONTAINS_TOP = 1 << 1
+};
+
// Convenience for platform-independent signatures. We do not normally
// distinguish memory operands from other operands on ia32.
typedef Operand MemOperand;
};
-// Flags used for the AllocateInNewSpace functions.
-enum AllocationFlags {
- // No special flags.
- NO_ALLOCATION_FLAGS = 0,
- // Return the pointer to the allocated already tagged as a heap object.
- TAG_OBJECT = 1 << 0,
- // The content of the result register already contains the allocation top in
- // new space.
- RESULT_CONTAINS_TOP = 1 << 1
-};
-
// Invalid depth in prototype chain.
const int kInvalidProtoDepth = -1;
namespace v8 {
namespace internal {
+// Flags used for the AllocateInNewSpace functions.
+enum AllocationFlags {
+ // No special flags.
+ NO_ALLOCATION_FLAGS = 0,
+ // Return the pointer to the allocated already tagged as a heap object.
+ TAG_OBJECT = 1 << 0,
+ // The content of the result register already contains the allocation top in
+ // new space.
+ RESULT_CONTAINS_TOP = 1 << 1
+};
+
// Default scratch register used by MacroAssembler (and other code that needs
// a spare register). The register isn't callee save, and not used by the
// function calling convention.