OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 4383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4394 | 4394 |
4395 Label fast_elements_case; | 4395 Label fast_elements_case; |
4396 __ cmp(ecx, Immediate(FAST_ELEMENTS)); | 4396 __ cmp(ecx, Immediate(FAST_ELEMENTS)); |
4397 __ j(equal, &fast_elements_case); | 4397 __ j(equal, &fast_elements_case); |
4398 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 4398 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
4399 | 4399 |
4400 __ bind(&fast_elements_case); | 4400 __ bind(&fast_elements_case); |
4401 GenerateCase(masm, FAST_ELEMENTS); | 4401 GenerateCase(masm, FAST_ELEMENTS); |
4402 } | 4402 } |
4403 | 4403 |
| 4404 void FastNewObjectStub::Generate(MacroAssembler* masm) { |
| 4405 // ----------- S t a t e ------------- |
| 4406 // -- edi : target |
| 4407 // -- edx : new target |
| 4408 // -- esi : context |
| 4409 // -- esp[0] : return address |
| 4410 // ----------------------------------- |
| 4411 __ AssertFunction(edi); |
| 4412 __ AssertReceiver(edx); |
| 4413 |
| 4414 // Verify that the new target is a JSFunction. |
| 4415 Label new_object; |
| 4416 __ CmpObjectType(edx, JS_FUNCTION_TYPE, ebx); |
| 4417 __ j(not_equal, &new_object); |
| 4418 |
| 4419 // Load the initial map and verify that it's in fact a map. |
| 4420 __ mov(ecx, FieldOperand(edx, JSFunction::kPrototypeOrInitialMapOffset)); |
| 4421 __ JumpIfSmi(ecx, &new_object); |
| 4422 __ CmpObjectType(ecx, MAP_TYPE, ebx); |
| 4423 __ j(not_equal, &new_object); |
| 4424 |
| 4425 // Fall back to runtime if the target differs from the new target's |
| 4426 // initial map constructor. |
| 4427 __ cmp(edi, FieldOperand(ecx, Map::kConstructorOrBackPointerOffset)); |
| 4428 __ j(not_equal, &new_object); |
| 4429 |
| 4430 // Allocate the JSObject on the heap. |
| 4431 Label allocate, done_allocate; |
| 4432 __ movzx_b(ebx, FieldOperand(ecx, Map::kInstanceSizeOffset)); |
| 4433 __ lea(ebx, Operand(ebx, times_pointer_size, 0)); |
| 4434 __ Allocate(ebx, eax, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
| 4435 __ bind(&done_allocate); |
| 4436 |
| 4437 // Initialize the JSObject fields. |
| 4438 __ mov(Operand(eax, JSObject::kMapOffset), ecx); |
| 4439 __ mov(Operand(eax, JSObject::kPropertiesOffset), |
| 4440 masm->isolate()->factory()->empty_fixed_array()); |
| 4441 __ mov(Operand(eax, JSObject::kElementsOffset), |
| 4442 masm->isolate()->factory()->empty_fixed_array()); |
| 4443 STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize); |
| 4444 __ lea(ebx, Operand(eax, JSObject::kHeaderSize)); |
| 4445 |
| 4446 // ----------- S t a t e ------------- |
| 4447 // -- eax : result (untagged) |
| 4448 // -- ebx : result fields (untagged) |
| 4449 // -- edi : result end (untagged) |
| 4450 // -- ecx : initial map |
| 4451 // -- esi : context |
| 4452 // -- esp[0] : return address |
| 4453 // ----------------------------------- |
| 4454 |
| 4455 // Perform in-object slack tracking if requested. |
| 4456 Label slack_tracking; |
| 4457 STATIC_ASSERT(Map::kNoSlackTracking == 0); |
| 4458 __ test(FieldOperand(ecx, Map::kBitField3Offset), |
| 4459 Immediate(Map::ConstructionCounter::kMask)); |
| 4460 __ j(not_zero, &slack_tracking, Label::kNear); |
| 4461 { |
| 4462 // Initialize all in-object fields with undefined. |
| 4463 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex); |
| 4464 __ InitializeFieldsWithFiller(ebx, edi, edx); |
| 4465 |
| 4466 // Add the object tag to make the JSObject real. |
| 4467 STATIC_ASSERT(kHeapObjectTag == 1); |
| 4468 __ inc(eax); |
| 4469 __ Ret(); |
| 4470 } |
| 4471 __ bind(&slack_tracking); |
| 4472 { |
| 4473 // Decrease generous allocation count. |
| 4474 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); |
| 4475 __ sub(FieldOperand(ecx, Map::kBitField3Offset), |
| 4476 Immediate(1 << Map::ConstructionCounter::kShift)); |
| 4477 |
| 4478 // Initialize the in-object fields with undefined. |
| 4479 __ movzx_b(edx, FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset)); |
| 4480 __ neg(edx); |
| 4481 __ lea(edx, Operand(edi, edx, times_pointer_size, 0)); |
| 4482 __ LoadRoot(edi, Heap::kUndefinedValueRootIndex); |
| 4483 __ InitializeFieldsWithFiller(ebx, edx, edi); |
| 4484 |
| 4485 // Initialize the remaining (reserved) fields with one pointer filler map. |
| 4486 __ movzx_b(edx, FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset)); |
| 4487 __ lea(edx, Operand(ebx, edx, times_pointer_size, 0)); |
| 4488 __ LoadRoot(edi, Heap::kOnePointerFillerMapRootIndex); |
| 4489 __ InitializeFieldsWithFiller(ebx, edx, edi); |
| 4490 |
| 4491 // Add the object tag to make the JSObject real. |
| 4492 STATIC_ASSERT(kHeapObjectTag == 1); |
| 4493 __ inc(eax); |
| 4494 |
| 4495 // Check if we can finalize the instance size. |
| 4496 Label finalize; |
| 4497 STATIC_ASSERT(Map::kSlackTrackingCounterEnd == 1); |
| 4498 __ test(FieldOperand(ecx, Map::kBitField3Offset), |
| 4499 Immediate(Map::ConstructionCounter::kMask)); |
| 4500 __ j(zero, &finalize, Label::kNear); |
| 4501 __ Ret(); |
| 4502 |
| 4503 // Finalize the instance size. |
| 4504 __ bind(&finalize); |
| 4505 { |
| 4506 FrameScope scope(masm, StackFrame::INTERNAL); |
| 4507 __ Push(eax); |
| 4508 __ Push(ecx); |
| 4509 __ CallRuntime(Runtime::kFinalizeInstanceSize); |
| 4510 __ Pop(eax); |
| 4511 } |
| 4512 __ Ret(); |
| 4513 } |
| 4514 |
| 4515 // Fall back to %AllocateInNewSpace. |
| 4516 __ bind(&allocate); |
| 4517 { |
| 4518 FrameScope scope(masm, StackFrame::INTERNAL); |
| 4519 __ SmiTag(ebx); |
| 4520 __ Push(ecx); |
| 4521 __ Push(ebx); |
| 4522 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 4523 __ Pop(ecx); |
| 4524 } |
| 4525 STATIC_ASSERT(kHeapObjectTag == 1); |
| 4526 __ dec(eax); |
| 4527 __ movzx_b(ebx, FieldOperand(ecx, Map::kInstanceSizeOffset)); |
| 4528 __ lea(edi, Operand(eax, ebx, times_pointer_size, 0)); |
| 4529 __ jmp(&done_allocate); |
| 4530 |
| 4531 // Fall back to %NewObject. |
| 4532 __ bind(&new_object); |
| 4533 __ PopReturnAddressTo(ecx); |
| 4534 __ Push(edi); |
| 4535 __ Push(edx); |
| 4536 __ PushReturnAddressFrom(ecx); |
| 4537 __ TailCallRuntime(Runtime::kNewObject); |
| 4538 } |
| 4539 |
4404 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { | 4540 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { |
4405 // ----------- S t a t e ------------- | 4541 // ----------- S t a t e ------------- |
4406 // -- edi : function | 4542 // -- edi : function |
4407 // -- esi : context | 4543 // -- esi : context |
4408 // -- ebp : frame pointer | 4544 // -- ebp : frame pointer |
4409 // -- esp[0] : return address | 4545 // -- esp[0] : return address |
4410 // ----------------------------------- | 4546 // ----------------------------------- |
4411 __ AssertFunction(edi); | 4547 __ AssertFunction(edi); |
4412 | 4548 |
4413 // For Ignition we need to skip all possible handler/stub frames until | 4549 // For Ignition we need to skip all possible handler/stub frames until |
(...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5450 return_value_operand, NULL); | 5586 return_value_operand, NULL); |
5451 } | 5587 } |
5452 | 5588 |
5453 | 5589 |
5454 #undef __ | 5590 #undef __ |
5455 | 5591 |
5456 } // namespace internal | 5592 } // namespace internal |
5457 } // namespace v8 | 5593 } // namespace v8 |
5458 | 5594 |
5459 #endif // V8_TARGET_ARCH_X87 | 5595 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |