Second step in allocating objects in generated code on ARM.

Objects which require an additional fixed array to be allocated now have this allocated in generated code as well. Added allocation flags to the macro assembler new space allocation routines.

Changed the ia32 and x64 macro assemblers to take allocation flags to the allocation routines instead of boolean flag.
Review URL: http://codereview.chromium.org/201015

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2832 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
sgjesse@chromium.org 2009-09-07 09:44:29 +00:00
parent 6a323d3afe
commit 2192a315a4
14 changed files with 266 additions and 133 deletions

View File

@ -1,4 +1,4 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved. // Copyright 2006-2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
@ -133,11 +133,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// r2: initial map // r2: initial map
// r7: undefined // r7: undefined
__ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset)); __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset));
// Make sure that the maximum heap object size will never cause us __ AllocateObjectInNewSpace(r3, r4, r5, r6, &rt_call, NO_ALLOCATION_FLAGS);
// problem here, because it is always greater than the maximum
// instance size that can be represented in a byte.
ASSERT(Heap::MaxObjectSizeInPagedSpace() >= JSObject::kMaxInstanceSize);
__ AllocateObjectInNewSpace(r3, r4, r5, r6, &rt_call, false);
// Allocated the JSObject, now initialize the fields. Map is set to initial // Allocated the JSObject, now initialize the fields. Map is set to initial
// map and properties and elements are set to empty fixed array. // map and properties and elements are set to empty fixed array.
@ -163,7 +159,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// r5: First in-object property of JSObject (not tagged) // r5: First in-object property of JSObject (not tagged)
// r7: undefined // r7: undefined
__ add(r6, r4, Operand(r3, LSL, kPointerSizeLog2)); // End of object. __ add(r6, r4, Operand(r3, LSL, kPointerSizeLog2)); // End of object.
ASSERT_EQ(12, JSObject::kHeaderSize); ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize);
{ Label loop, entry; { Label loop, entry;
__ b(&entry); __ b(&entry);
__ bind(&loop); __ bind(&loop);
@ -182,7 +178,6 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// Check if a non-empty properties array is needed. Continue with allocated // Check if a non-empty properties array is needed. Continue with allocated
// object if not fall through to runtime call if it is. // object if not fall through to runtime call if it is.
// r1: constructor function // r1: constructor function
// r2: initial map
// r4: JSObject // r4: JSObject
// r5: start of next object (not tagged) // r5: start of next object (not tagged)
// r7: undefined // r7: undefined
@ -199,7 +194,66 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// Done if no extra properties are to be allocated. // Done if no extra properties are to be allocated.
__ b(eq, &allocated); __ b(eq, &allocated);
__ Assert(al, "Property allocation count failed."); __ Assert(pl, "Property allocation count failed.");
// Scale the number of elements by pointer size and add the header for
// FixedArrays to the start of the next object calculation from above.
// r1: constructor
// r3: number of elements in properties array
// r4: JSObject
// r5: start of next object
// r7: undefined
__ add(r0, r3, Operand(FixedArray::kHeaderSize / kPointerSize));
__ AllocateObjectInNewSpace(r0,
r5,
r6,
r2,
&undo_allocation,
RESULT_CONTAINS_TOP);
// Initialize the FixedArray.
// r1: constructor
// r3: number of elements in properties array
// r4: JSObject
// r5: FixedArray (not tagged)
// r7: undefined
__ LoadRoot(r6, Heap::kFixedArrayMapRootIndex);
__ mov(r2, r5);
ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
__ str(r6, MemOperand(r2, kPointerSize, PostIndex));
ASSERT_EQ(1 * kPointerSize, Array::kLengthOffset);
__ str(r3, MemOperand(r2, kPointerSize, PostIndex));
// Initialize the fields to undefined.
// r1: constructor function
// r2: First element of FixedArray (not tagged)
// r3: number of elements in properties array
// r4: JSObject
// r5: FixedArray (not tagged)
// r7: undefined
__ add(r6, r2, Operand(r3, LSL, kPointerSizeLog2)); // End of object.
ASSERT_EQ(2 * kPointerSize, FixedArray::kHeaderSize);
{ Label loop, entry;
__ b(&entry);
__ bind(&loop);
__ str(r7, MemOperand(r2, kPointerSize, PostIndex));
__ bind(&entry);
__ cmp(r2, Operand(r6));
__ b(lt, &loop);
}
// Store the initialized FixedArray into the properties field of
// the JSObject
// r1: constructor function
// r4: JSObject
// r5: FixedArray (not tagged)
__ add(r5, r5, Operand(kHeapObjectTag)); // Add the heap tag.
__ str(r5, FieldMemOperand(r4, JSObject::kPropertiesOffset));
// Continue with JSObject being successfully allocated
// r1: constructor function
// r4: JSObject
__ jmp(&allocated);
// Undo the setting of the new top so that the heap is verifiable. For // Undo the setting of the new top so that the heap is verifiable. For
// example, the map's unused properties potentially do not match the // example, the map's unused properties potentially do not match the
@ -210,6 +264,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
} }
// Allocate the new receiver object using the runtime call. // Allocate the new receiver object using the runtime call.
// r1: constructor function
__ bind(&rt_call); __ bind(&rt_call);
__ push(r1); // argument for Runtime_NewObject __ push(r1); // argument for Runtime_NewObject
__ CallRuntime(Runtime::kNewObject, 1); __ CallRuntime(Runtime::kNewObject, 1);

View File

@ -4955,7 +4955,7 @@ static void AllocateHeapNumber(
scratch1, scratch1,
scratch2, scratch2,
need_gc, need_gc,
true); TAG_OBJECT);
// Get heap number map and store it in the allocated object. // Get heap number map and store it in the allocated object.
__ LoadRoot(scratch1, Heap::kHeapNumberMapRootIndex); __ LoadRoot(scratch1, Heap::kHeapNumberMapRootIndex);

View File

@ -773,7 +773,7 @@ void MacroAssembler::AllocateObjectInNewSpace(int object_size,
Register scratch1, Register scratch1,
Register scratch2, Register scratch2,
Label* gc_required, Label* gc_required,
bool tag_allocated_object) { AllocationFlags flags) {
ASSERT(!result.is(scratch1)); ASSERT(!result.is(scratch1));
ASSERT(!scratch1.is(scratch2)); ASSERT(!scratch1.is(scratch2));
@ -782,7 +782,18 @@ void MacroAssembler::AllocateObjectInNewSpace(int object_size,
ExternalReference new_space_allocation_top = ExternalReference new_space_allocation_top =
ExternalReference::new_space_allocation_top_address(); ExternalReference::new_space_allocation_top_address();
mov(scratch1, Operand(new_space_allocation_top)); mov(scratch1, Operand(new_space_allocation_top));
ldr(result, MemOperand(scratch1)); 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 // Calculate new top and bail out if new space is exhausted. Use result
// to calculate the new top. // to calculate the new top.
@ -798,7 +809,7 @@ void MacroAssembler::AllocateObjectInNewSpace(int object_size,
str(result, MemOperand(scratch1)); str(result, MemOperand(scratch1));
// Tag and adjust back to start of new object. // Tag and adjust back to start of new object.
if (tag_allocated_object) { if ((flags & TAG_OBJECT) != 0) {
sub(result, result, Operand((object_size * kPointerSize) - sub(result, result, Operand((object_size * kPointerSize) -
kHeapObjectTag)); kHeapObjectTag));
} else { } else {
@ -812,7 +823,7 @@ void MacroAssembler::AllocateObjectInNewSpace(Register object_size,
Register scratch1, Register scratch1,
Register scratch2, Register scratch2,
Label* gc_required, Label* gc_required,
bool tag_allocated_object) { AllocationFlags flags) {
ASSERT(!result.is(scratch1)); ASSERT(!result.is(scratch1));
ASSERT(!scratch1.is(scratch2)); ASSERT(!scratch1.is(scratch2));
@ -821,7 +832,18 @@ void MacroAssembler::AllocateObjectInNewSpace(Register object_size,
ExternalReference new_space_allocation_top = ExternalReference new_space_allocation_top =
ExternalReference::new_space_allocation_top_address(); ExternalReference::new_space_allocation_top_address();
mov(scratch1, Operand(new_space_allocation_top)); mov(scratch1, Operand(new_space_allocation_top));
ldr(result, MemOperand(scratch1)); 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 // 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 // to calculate the new top. Object size is in words so a shift is required to
@ -831,19 +853,18 @@ void MacroAssembler::AllocateObjectInNewSpace(Register object_size,
mov(scratch2, Operand(new_space_allocation_limit)); mov(scratch2, Operand(new_space_allocation_limit));
ldr(scratch2, MemOperand(scratch2)); ldr(scratch2, MemOperand(scratch2));
add(result, result, Operand(object_size, LSL, kPointerSizeLog2)); add(result, result, Operand(object_size, LSL, kPointerSizeLog2));
cmp(result, Operand(scratch2)); cmp(result, Operand(scratch2));
b(hi, gc_required); b(hi, gc_required);
// Update allocation top. result temporarily holds the new top, // Update allocation top. result temporarily holds the new top,
str(result, MemOperand(scratch1)); str(result, MemOperand(scratch1));
// Tag and adjust back to start of new object. // Adjust back to start of new object.
if (tag_allocated_object) { sub(result, result, Operand(object_size, LSL, kPointerSizeLog2));
sub(result, result, Operand(object_size, LSL, kPointerSizeLog2));
// Tag object if requested.
if ((flags & TAG_OBJECT) != 0) {
add(result, result, Operand(kHeapObjectTag)); add(result, result, Operand(kHeapObjectTag));
} else {
sub(result, result, Operand(object_size, LSL, kPointerSizeLog2));
} }
} }

View File

@ -1,4 +1,4 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved. // Copyright 2006-2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
@ -67,6 +67,18 @@ enum HandlerType {
}; };
// Flags used for the AllocateObjectInNewSpace 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
};
// MacroAssembler implements a collection of frequently used macros. // MacroAssembler implements a collection of frequently used macros.
class MacroAssembler: public Assembler { class MacroAssembler: public Assembler {
public: public:
@ -199,13 +211,13 @@ class MacroAssembler: public Assembler {
Register scratch1, Register scratch1,
Register scratch2, Register scratch2,
Label* gc_required, Label* gc_required,
bool tag_allocated_object); AllocationFlags flags);
void AllocateObjectInNewSpace(Register object_size, void AllocateObjectInNewSpace(Register object_size,
Register result, Register result,
Register scratch1, Register scratch1,
Register scratch2, Register scratch2,
Label* gc_required, Label* gc_required,
bool tag_allocated_object); AllocationFlags flags);
// Undo allocation in new space. The object passed and objects allocated after // Undo allocation in new space. The object passed and objects allocated after
// it will no longer be allocated. The caller must make sure that no pointers // it will no longer be allocated. The caller must make sure that no pointers

View File

@ -1,4 +1,4 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved. // Copyright 2006-2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
@ -133,7 +133,12 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// problem here, because it is always greater than the maximum // problem here, because it is always greater than the maximum
// instance size that can be represented in a byte. // instance size that can be represented in a byte.
ASSERT(Heap::MaxObjectSizeInPagedSpace() >= JSObject::kMaxInstanceSize); ASSERT(Heap::MaxObjectSizeInPagedSpace() >= JSObject::kMaxInstanceSize);
__ AllocateObjectInNewSpace(edi, ebx, edi, no_reg, &rt_call, false); __ AllocateObjectInNewSpace(edi,
ebx,
edi,
no_reg,
&rt_call,
NO_ALLOCATION_FLAGS);
// Allocated the JSObject, now initialize the fields. // Allocated the JSObject, now initialize the fields.
// eax: initial map // eax: initial map
// ebx: JSObject // ebx: JSObject
@ -197,7 +202,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
ecx, ecx,
no_reg, no_reg,
&undo_allocation, &undo_allocation,
true); RESULT_CONTAINS_TOP);
// Initialize the FixedArray. // Initialize the FixedArray.
// ebx: JSObject // ebx: JSObject
@ -245,10 +250,10 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
} }
// Allocate the new receiver object using the runtime call. // Allocate the new receiver object using the runtime call.
// edi: function (constructor)
__ bind(&rt_call); __ bind(&rt_call);
// Must restore edi (constructor) before calling runtime. // Must restore edi (constructor) before calling runtime.
__ mov(edi, Operand(esp, 0)); __ mov(edi, Operand(esp, 0));
// edi: function (constructor)
__ push(edi); __ push(edi);
__ CallRuntime(Runtime::kNewObject, 1); __ CallRuntime(Runtime::kNewObject, 1);
__ mov(ebx, Operand(eax)); // store result in ebx __ mov(ebx, Operand(eax)); // store result in ebx

View File

@ -6954,12 +6954,11 @@ void FloatingPointHelper::AllocateHeapNumber(MacroAssembler* masm,
scratch1, scratch1,
scratch2, scratch2,
need_gc, need_gc,
false); TAG_OBJECT);
// Set the map and tag the result. // Set the map.
__ mov(Operand(result, HeapObject::kMapOffset), __ mov(FieldOperand(result, HeapObject::kMapOffset),
Immediate(Factory::heap_number_map())); Immediate(Factory::heap_number_map()));
__ or_(Operand(result), Immediate(kHeapObjectTag));
} }

View File

@ -1,4 +1,4 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved. // Copyright 2006-2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
@ -620,16 +620,15 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
} }
void MacroAssembler::LoadAllocationTopHelper( void MacroAssembler::LoadAllocationTopHelper(Register result,
Register result, Register result_end,
Register result_end, Register scratch,
Register scratch, AllocationFlags flags) {
bool result_contains_top_on_entry) {
ExternalReference new_space_allocation_top = ExternalReference new_space_allocation_top =
ExternalReference::new_space_allocation_top_address(); ExternalReference::new_space_allocation_top_address();
// Just return if allocation top is already known. // Just return if allocation top is already known.
if (result_contains_top_on_entry) { if ((flags & RESULT_CONTAINS_TOP) != 0) {
// No use of scratch if allocation top is provided. // No use of scratch if allocation top is provided.
ASSERT(scratch.is(no_reg)); ASSERT(scratch.is(no_reg));
return; return;
@ -659,20 +658,17 @@ void MacroAssembler::UpdateAllocationTopHelper(Register result_end,
} }
} }
void MacroAssembler::AllocateObjectInNewSpace(
int object_size, void MacroAssembler::AllocateObjectInNewSpace(int object_size,
Register result, Register result,
Register result_end, Register result_end,
Register scratch, Register scratch,
Label* gc_required, Label* gc_required,
bool result_contains_top_on_entry) { AllocationFlags flags) {
ASSERT(!result.is(result_end)); ASSERT(!result.is(result_end));
// Load address of new object into result. // Load address of new object into result.
LoadAllocationTopHelper(result, LoadAllocationTopHelper(result, result_end, scratch, flags);
result_end,
scratch,
result_contains_top_on_entry);
// Calculate new top and bail out if new space is exhausted. // Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit = ExternalReference new_space_allocation_limit =
@ -683,25 +679,26 @@ void MacroAssembler::AllocateObjectInNewSpace(
// Update allocation top. // Update allocation top.
UpdateAllocationTopHelper(result_end, scratch); UpdateAllocationTopHelper(result_end, scratch);
// Tag result if requested.
if ((flags & TAG_OBJECT) != 0) {
or_(Operand(result), Immediate(kHeapObjectTag));
}
} }
void MacroAssembler::AllocateObjectInNewSpace( void MacroAssembler::AllocateObjectInNewSpace(int header_size,
int header_size, ScaleFactor element_size,
ScaleFactor element_size, Register element_count,
Register element_count, Register result,
Register result, Register result_end,
Register result_end, Register scratch,
Register scratch, Label* gc_required,
Label* gc_required, AllocationFlags flags) {
bool result_contains_top_on_entry) {
ASSERT(!result.is(result_end)); ASSERT(!result.is(result_end));
// Load address of new object into result. // Load address of new object into result.
LoadAllocationTopHelper(result, LoadAllocationTopHelper(result, result_end, scratch, flags);
result_end,
scratch,
result_contains_top_on_entry);
// Calculate new top and bail out if new space is exhausted. // Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit = ExternalReference new_space_allocation_limit =
@ -712,24 +709,24 @@ void MacroAssembler::AllocateObjectInNewSpace(
// Update allocation top. // Update allocation top.
UpdateAllocationTopHelper(result_end, scratch); UpdateAllocationTopHelper(result_end, scratch);
// Tag result if requested.
if ((flags & TAG_OBJECT) != 0) {
or_(Operand(result), Immediate(kHeapObjectTag));
}
} }
void MacroAssembler::AllocateObjectInNewSpace( void MacroAssembler::AllocateObjectInNewSpace(Register object_size,
Register object_size, Register result,
Register result, Register result_end,
Register result_end, Register scratch,
Register scratch, Label* gc_required,
Label* gc_required, AllocationFlags flags) {
bool result_contains_top_on_entry) {
ASSERT(!result.is(result_end)); ASSERT(!result.is(result_end));
// Load address of new object into result. // Load address of new object into result.
LoadAllocationTopHelper(result, LoadAllocationTopHelper(result, result_end, scratch, flags);
result_end,
scratch,
result_contains_top_on_entry);
// Calculate new top and bail out if new space is exhausted. // Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit = ExternalReference new_space_allocation_limit =
@ -743,6 +740,11 @@ void MacroAssembler::AllocateObjectInNewSpace(
// Update allocation top. // Update allocation top.
UpdateAllocationTopHelper(result_end, scratch); UpdateAllocationTopHelper(result_end, scratch);
// Tag result if requested.
if ((flags & TAG_OBJECT) != 0) {
or_(Operand(result), Immediate(kHeapObjectTag));
}
} }

View File

@ -1,4 +1,4 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved. // Copyright 2006-2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
@ -56,6 +56,18 @@ enum HandlerType {
}; };
// Flags used for the AllocateObjectInNewSpace 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
};
// MacroAssembler implements a collection of frequently used macros. // MacroAssembler implements a collection of frequently used macros.
class MacroAssembler: public Assembler { class MacroAssembler: public Assembler {
public: public:
@ -201,7 +213,7 @@ class MacroAssembler: public Assembler {
Register result_end, Register result_end,
Register scratch, Register scratch,
Label* gc_required, Label* gc_required,
bool result_contains_top_on_entry); AllocationFlags flags);
void AllocateObjectInNewSpace(int header_size, void AllocateObjectInNewSpace(int header_size,
ScaleFactor element_size, ScaleFactor element_size,
@ -210,14 +222,14 @@ class MacroAssembler: public Assembler {
Register result_end, Register result_end,
Register scratch, Register scratch,
Label* gc_required, Label* gc_required,
bool result_contains_top_on_entry); AllocationFlags flags);
void AllocateObjectInNewSpace(Register object_size, void AllocateObjectInNewSpace(Register object_size,
Register result, Register result,
Register result_end, Register result_end,
Register scratch, Register scratch,
Label* gc_required, Label* gc_required,
bool result_contains_top_on_entry); AllocationFlags flags);
// Undo allocation in new space. The object passed and objects allocated after // Undo allocation in new space. The object passed and objects allocated after
// it will no longer be allocated. Make sure that no pointers are left to the // it will no longer be allocated. Make sure that no pointers are left to the
@ -350,7 +362,7 @@ class MacroAssembler: public Assembler {
void LoadAllocationTopHelper(Register result, void LoadAllocationTopHelper(Register result,
Register result_end, Register result_end,
Register scratch, Register scratch,
bool result_contains_top_on_entry); AllocationFlags flags);
void UpdateAllocationTopHelper(Register result_end, Register scratch); void UpdateAllocationTopHelper(Register result_end, Register scratch);
}; };

View File

@ -1786,7 +1786,12 @@ Object* ConstructStubCompiler::CompileConstructStub(
// Make sure that the maximum heap object size will never cause us // Make sure that the maximum heap object size will never cause us
// problems here. // problems here.
ASSERT(Heap::MaxObjectSizeInPagedSpace() >= JSObject::kMaxInstanceSize); ASSERT(Heap::MaxObjectSizeInPagedSpace() >= JSObject::kMaxInstanceSize);
__ AllocateObjectInNewSpace(ecx, edx, ecx, no_reg, &generic_stub_call, false); __ AllocateObjectInNewSpace(ecx,
edx,
ecx,
no_reg,
&generic_stub_call,
NO_ALLOCATION_FLAGS);
// Allocated the JSObject, now initialize the fields and add the heap tag. // Allocated the JSObject, now initialize the fields and add the heap tag.
// ebx: initial map // ebx: initial map

View File

@ -540,7 +540,12 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// problem here, because it is always greater than the maximum // problem here, because it is always greater than the maximum
// instance size that can be represented in a byte. // instance size that can be represented in a byte.
ASSERT(Heap::MaxObjectSizeInPagedSpace() >= (1 << kBitsPerByte)); ASSERT(Heap::MaxObjectSizeInPagedSpace() >= (1 << kBitsPerByte));
__ AllocateObjectInNewSpace(rdi, rbx, rdi, no_reg, &rt_call, false); __ AllocateObjectInNewSpace(rdi,
rbx,
rdi,
no_reg,
&rt_call,
NO_ALLOCATION_FLAGS);
// Allocated the JSObject, now initialize the fields. // Allocated the JSObject, now initialize the fields.
// rax: initial map // rax: initial map
// rbx: JSObject (not HeapObject tagged - the actual address). // rbx: JSObject (not HeapObject tagged - the actual address).
@ -604,7 +609,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
rax, rax,
no_reg, no_reg,
&undo_allocation, &undo_allocation,
true); RESULT_CONTAINS_TOP);
// Initialize the FixedArray. // Initialize the FixedArray.
// rbx: JSObject // rbx: JSObject

View File

@ -7347,10 +7347,9 @@ void FloatingPointHelper::AllocateHeapNumber(MacroAssembler* masm,
scratch, scratch,
no_reg, no_reg,
need_gc, need_gc,
false); TAG_OBJECT);
// Set the map and tag the result. // Set the map and tag the result.
__ addq(result, Immediate(kHeapObjectTag));
__ LoadRoot(kScratchRegister, Heap::kHeapNumberMapRootIndex); __ LoadRoot(kScratchRegister, Heap::kHeapNumberMapRootIndex);
__ movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); __ movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
} }

View File

@ -1231,16 +1231,15 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
} }
void MacroAssembler::LoadAllocationTopHelper( void MacroAssembler::LoadAllocationTopHelper(Register result,
Register result, Register result_end,
Register result_end, Register scratch,
Register scratch, AllocationFlags flags) {
bool result_contains_top_on_entry) {
ExternalReference new_space_allocation_top = ExternalReference new_space_allocation_top =
ExternalReference::new_space_allocation_top_address(); ExternalReference::new_space_allocation_top_address();
// Just return if allocation top is already known. // Just return if allocation top is already known.
if (result_contains_top_on_entry) { if ((flags & RESULT_CONTAINS_TOP) != 0) {
// No use of scratch if allocation top is provided. // No use of scratch if allocation top is provided.
ASSERT(scratch.is(no_reg)); ASSERT(scratch.is(no_reg));
return; return;
@ -1279,20 +1278,16 @@ void MacroAssembler::UpdateAllocationTopHelper(Register result_end,
} }
void MacroAssembler::AllocateObjectInNewSpace( void MacroAssembler::AllocateObjectInNewSpace(int object_size,
int object_size, Register result,
Register result, Register result_end,
Register result_end, Register scratch,
Register scratch, Label* gc_required,
Label* gc_required, AllocationFlags flags) {
bool result_contains_top_on_entry) {
ASSERT(!result.is(result_end)); ASSERT(!result.is(result_end));
// Load address of new object into result. // Load address of new object into result.
LoadAllocationTopHelper(result, LoadAllocationTopHelper(result, result_end, scratch, flags);
result_end,
scratch,
result_contains_top_on_entry);
// Calculate new top and bail out if new space is exhausted. // Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit = ExternalReference new_space_allocation_limit =
@ -1304,25 +1299,26 @@ void MacroAssembler::AllocateObjectInNewSpace(
// Update allocation top. // Update allocation top.
UpdateAllocationTopHelper(result_end, scratch); UpdateAllocationTopHelper(result_end, scratch);
// Tag the result if requested.
if ((flags & TAG_OBJECT) != 0) {
addq(result, Immediate(kHeapObjectTag));
}
} }
void MacroAssembler::AllocateObjectInNewSpace( void MacroAssembler::AllocateObjectInNewSpace(int header_size,
int header_size, ScaleFactor element_size,
ScaleFactor element_size, Register element_count,
Register element_count, Register result,
Register result, Register result_end,
Register result_end, Register scratch,
Register scratch, Label* gc_required,
Label* gc_required, AllocationFlags flags) {
bool result_contains_top_on_entry) {
ASSERT(!result.is(result_end)); ASSERT(!result.is(result_end));
// Load address of new object into result. // Load address of new object into result.
LoadAllocationTopHelper(result, LoadAllocationTopHelper(result, result_end, scratch, flags);
result_end,
scratch,
result_contains_top_on_entry);
// Calculate new top and bail out if new space is exhausted. // Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit = ExternalReference new_space_allocation_limit =
@ -1334,23 +1330,23 @@ void MacroAssembler::AllocateObjectInNewSpace(
// Update allocation top. // Update allocation top.
UpdateAllocationTopHelper(result_end, scratch); UpdateAllocationTopHelper(result_end, scratch);
// Tag the result if requested.
if ((flags & TAG_OBJECT) != 0) {
addq(result, Immediate(kHeapObjectTag));
}
} }
void MacroAssembler::AllocateObjectInNewSpace( void MacroAssembler::AllocateObjectInNewSpace(Register object_size,
Register object_size, Register result,
Register result, Register result_end,
Register result_end, Register scratch,
Register scratch, Label* gc_required,
Label* gc_required, AllocationFlags flags) {
bool result_contains_top_on_entry) {
// Load address of new object into result. // Load address of new object into result.
LoadAllocationTopHelper(result, LoadAllocationTopHelper(result, result_end, scratch, flags);
result_end,
scratch,
result_contains_top_on_entry);
// Calculate new top and bail out if new space is exhausted. // Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit = ExternalReference new_space_allocation_limit =
@ -1365,6 +1361,11 @@ void MacroAssembler::AllocateObjectInNewSpace(
// Update allocation top. // Update allocation top.
UpdateAllocationTopHelper(result_end, scratch); UpdateAllocationTopHelper(result_end, scratch);
// Tag the result if requested.
if ((flags & TAG_OBJECT) != 0) {
addq(result, Immediate(kHeapObjectTag));
}
} }

View File

@ -1,4 +1,4 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved. // Copyright 2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
@ -61,6 +61,18 @@ enum HandlerType {
}; };
// Flags used for the AllocateObjectInNewSpace 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
};
// MacroAssembler implements a collection of frequently used macros. // MacroAssembler implements a collection of frequently used macros.
class MacroAssembler: public Assembler { class MacroAssembler: public Assembler {
public: public:
@ -244,7 +256,7 @@ class MacroAssembler: public Assembler {
Register result_end, Register result_end,
Register scratch, Register scratch,
Label* gc_required, Label* gc_required,
bool result_contains_top_on_entry); AllocationFlags flags);
void AllocateObjectInNewSpace(int header_size, void AllocateObjectInNewSpace(int header_size,
ScaleFactor element_size, ScaleFactor element_size,
@ -253,14 +265,14 @@ class MacroAssembler: public Assembler {
Register result_end, Register result_end,
Register scratch, Register scratch,
Label* gc_required, Label* gc_required,
bool result_contains_top_on_entry); AllocationFlags flags);
void AllocateObjectInNewSpace(Register object_size, void AllocateObjectInNewSpace(Register object_size,
Register result, Register result,
Register result_end, Register result_end,
Register scratch, Register scratch,
Label* gc_required, Label* gc_required,
bool result_contains_top_on_entry); AllocationFlags flags);
// Undo allocation in new space. The object passed and objects allocated after // Undo allocation in new space. The object passed and objects allocated after
// it will no longer be allocated. Make sure that no pointers are left to the // it will no longer be allocated. Make sure that no pointers are left to the
@ -392,7 +404,7 @@ class MacroAssembler: public Assembler {
void LoadAllocationTopHelper(Register result, void LoadAllocationTopHelper(Register result,
Register result_end, Register result_end,
Register scratch, Register scratch,
bool result_contains_top_on_entry); AllocationFlags flags);
void UpdateAllocationTopHelper(Register result_end, Register scratch); void UpdateAllocationTopHelper(Register result_end, Register scratch);
}; };

View File

@ -1787,7 +1787,12 @@ Object* ConstructStubCompiler::CompileConstructStub(
// Make sure that the maximum heap object size will never cause us // Make sure that the maximum heap object size will never cause us
// problems here. // problems here.
ASSERT(Heap::MaxObjectSizeInPagedSpace() >= JSObject::kMaxInstanceSize); ASSERT(Heap::MaxObjectSizeInPagedSpace() >= JSObject::kMaxInstanceSize);
__ AllocateObjectInNewSpace(rcx, rdx, rcx, no_reg, &generic_stub_call, false); __ AllocateObjectInNewSpace(rcx,
rdx,
rcx,
no_reg,
&generic_stub_call,
NO_ALLOCATION_FLAGS);
// Allocated the JSObject, now initialize the fields and add the heap tag. // Allocated the JSObject, now initialize the fields and add the heap tag.
// rbx: initial map // rbx: initial map