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:
parent
6a323d3afe
commit
2192a315a4
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user