X87: [stubs] Port FastNewObjectStub to TF.
port 5b02a98bfa
(r41986)
original commit message:
In the process, convert from a code stub into a builtin.
BUG=
Review-Url: https://codereview.chromium.org/2608203002
Cr-Commit-Position: refs/heads/master@{#42018}
This commit is contained in:
parent
5892cc9b61
commit
0522ea7424
@ -135,8 +135,8 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function,
|
||||
// Allocate the new receiver object.
|
||||
__ Push(edi);
|
||||
__ Push(edx);
|
||||
FastNewObjectStub stub(masm->isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(CodeFactory::FastNewObject(masm->isolate()).code(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ mov(ebx, eax);
|
||||
__ Pop(edx);
|
||||
__ Pop(edi);
|
||||
@ -1938,8 +1938,8 @@ void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) {
|
||||
FrameScope scope(masm, StackFrame::MANUAL);
|
||||
__ EnterBuiltinFrame(esi, edi, ecx);
|
||||
__ Push(ebx); // the first argument
|
||||
FastNewObjectStub stub(masm->isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(CodeFactory::FastNewObject(masm->isolate()).code(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ Pop(FieldOperand(eax, JSValue::kValueOffset));
|
||||
__ LeaveBuiltinFrame(esi, edi, ecx);
|
||||
}
|
||||
@ -2101,8 +2101,8 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
|
||||
__ SmiTag(ebx);
|
||||
__ EnterBuiltinFrame(esi, edi, ebx);
|
||||
__ Push(eax); // the first argument
|
||||
FastNewObjectStub stub(masm->isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(CodeFactory::FastNewObject(masm->isolate()).code(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ Pop(FieldOperand(eax, JSValue::kValueOffset));
|
||||
__ LeaveBuiltinFrame(esi, edi, ebx);
|
||||
__ SmiUntag(ebx);
|
||||
|
@ -3130,134 +3130,6 @@ void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
GenerateCase(masm, FAST_ELEMENTS);
|
||||
}
|
||||
|
||||
void FastNewObjectStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- edi : target
|
||||
// -- edx : new target
|
||||
// -- esi : context
|
||||
// -- esp[0] : return address
|
||||
// -----------------------------------
|
||||
__ AssertFunction(edi);
|
||||
__ AssertReceiver(edx);
|
||||
|
||||
// Verify that the new target is a JSFunction.
|
||||
Label new_object;
|
||||
__ CmpObjectType(edx, JS_FUNCTION_TYPE, ebx);
|
||||
__ j(not_equal, &new_object);
|
||||
|
||||
// Load the initial map and verify that it's in fact a map.
|
||||
__ mov(ecx, FieldOperand(edx, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
__ JumpIfSmi(ecx, &new_object);
|
||||
__ CmpObjectType(ecx, MAP_TYPE, ebx);
|
||||
__ j(not_equal, &new_object);
|
||||
|
||||
// Fall back to runtime if the target differs from the new target's
|
||||
// initial map constructor.
|
||||
__ cmp(edi, FieldOperand(ecx, Map::kConstructorOrBackPointerOffset));
|
||||
__ j(not_equal, &new_object);
|
||||
|
||||
// Allocate the JSObject on the heap.
|
||||
Label allocate, done_allocate;
|
||||
__ movzx_b(ebx, FieldOperand(ecx, Map::kInstanceSizeOffset));
|
||||
__ lea(ebx, Operand(ebx, times_pointer_size, 0));
|
||||
__ Allocate(ebx, eax, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS);
|
||||
__ bind(&done_allocate);
|
||||
|
||||
// Initialize the JSObject fields.
|
||||
__ mov(FieldOperand(eax, JSObject::kMapOffset), ecx);
|
||||
__ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
|
||||
masm->isolate()->factory()->empty_fixed_array());
|
||||
__ mov(FieldOperand(eax, JSObject::kElementsOffset),
|
||||
masm->isolate()->factory()->empty_fixed_array());
|
||||
STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize);
|
||||
__ lea(ebx, FieldOperand(eax, JSObject::kHeaderSize));
|
||||
|
||||
// ----------- S t a t e -------------
|
||||
// -- eax : result (tagged)
|
||||
// -- ebx : result fields (untagged)
|
||||
// -- edi : result end (untagged)
|
||||
// -- ecx : initial map
|
||||
// -- esi : context
|
||||
// -- esp[0] : return address
|
||||
// -----------------------------------
|
||||
|
||||
// Perform in-object slack tracking if requested.
|
||||
Label slack_tracking;
|
||||
STATIC_ASSERT(Map::kNoSlackTracking == 0);
|
||||
__ test(FieldOperand(ecx, Map::kBitField3Offset),
|
||||
Immediate(Map::ConstructionCounter::kMask));
|
||||
__ j(not_zero, &slack_tracking, Label::kNear);
|
||||
{
|
||||
// Initialize all in-object fields with undefined.
|
||||
__ LoadRoot(edx, Heap::kUndefinedValueRootIndex);
|
||||
__ InitializeFieldsWithFiller(ebx, edi, edx);
|
||||
__ Ret();
|
||||
}
|
||||
__ bind(&slack_tracking);
|
||||
{
|
||||
// Decrease generous allocation count.
|
||||
STATIC_ASSERT(Map::ConstructionCounter::kNext == 32);
|
||||
__ sub(FieldOperand(ecx, Map::kBitField3Offset),
|
||||
Immediate(1 << Map::ConstructionCounter::kShift));
|
||||
|
||||
// Initialize the in-object fields with undefined.
|
||||
__ movzx_b(edx, FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset));
|
||||
__ neg(edx);
|
||||
__ lea(edx, Operand(edi, edx, times_pointer_size, 0));
|
||||
__ LoadRoot(edi, Heap::kUndefinedValueRootIndex);
|
||||
__ InitializeFieldsWithFiller(ebx, edx, edi);
|
||||
|
||||
// Initialize the remaining (reserved) fields with one pointer filler map.
|
||||
__ movzx_b(edx, FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset));
|
||||
__ lea(edx, Operand(ebx, edx, times_pointer_size, 0));
|
||||
__ LoadRoot(edi, Heap::kOnePointerFillerMapRootIndex);
|
||||
__ InitializeFieldsWithFiller(ebx, edx, edi);
|
||||
|
||||
// Check if we can finalize the instance size.
|
||||
Label finalize;
|
||||
STATIC_ASSERT(Map::kSlackTrackingCounterEnd == 1);
|
||||
__ test(FieldOperand(ecx, Map::kBitField3Offset),
|
||||
Immediate(Map::ConstructionCounter::kMask));
|
||||
__ j(zero, &finalize, Label::kNear);
|
||||
__ Ret();
|
||||
|
||||
// Finalize the instance size.
|
||||
__ bind(&finalize);
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ Push(eax);
|
||||
__ Push(ecx);
|
||||
__ CallRuntime(Runtime::kFinalizeInstanceSize);
|
||||
__ Pop(eax);
|
||||
}
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
// Fall back to %AllocateInNewSpace.
|
||||
__ bind(&allocate);
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ SmiTag(ebx);
|
||||
__ Push(ecx);
|
||||
__ Push(ebx);
|
||||
__ CallRuntime(Runtime::kAllocateInNewSpace);
|
||||
__ Pop(ecx);
|
||||
}
|
||||
__ movzx_b(ebx, FieldOperand(ecx, Map::kInstanceSizeOffset));
|
||||
__ lea(edi, Operand(eax, ebx, times_pointer_size, 0));
|
||||
STATIC_ASSERT(kHeapObjectTag == 1);
|
||||
__ dec(edi);
|
||||
__ jmp(&done_allocate);
|
||||
|
||||
// Fall back to %NewObject.
|
||||
__ bind(&new_object);
|
||||
__ PopReturnAddressTo(ecx);
|
||||
__ Push(edi);
|
||||
__ Push(edx);
|
||||
__ PushReturnAddressFrom(ecx);
|
||||
__ TailCallRuntime(Runtime::kNewObject);
|
||||
}
|
||||
|
||||
void FastNewRestParameterStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- edi : function
|
||||
|
@ -68,12 +68,6 @@ void FastNewClosureDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
|
||||
}
|
||||
|
||||
void FastNewObjectDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {edi, edx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void FastNewRestParameterDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {edi};
|
||||
|
Loading…
Reference in New Issue
Block a user