OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 5 #if V8_TARGET_ARCH_PPC |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 4556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4567 __ Pop(r3, r5); | 4567 __ Pop(r3, r5); |
4568 } | 4568 } |
4569 __ b(&done_allocate); | 4569 __ b(&done_allocate); |
4570 | 4570 |
4571 // Fall back to %NewStrictArguments. | 4571 // Fall back to %NewStrictArguments. |
4572 __ bind(&too_big_for_new_space); | 4572 __ bind(&too_big_for_new_space); |
4573 __ push(r4); | 4573 __ push(r4); |
4574 __ TailCallRuntime(Runtime::kNewStrictArguments); | 4574 __ TailCallRuntime(Runtime::kNewStrictArguments); |
4575 } | 4575 } |
4576 | 4576 |
4577 void StoreGlobalViaContextStub::Generate(MacroAssembler* masm) { | |
4578 Register value = r3; | |
4579 Register slot = r5; | |
4580 | |
4581 Register cell = r4; | |
4582 Register cell_details = r6; | |
4583 Register cell_value = r7; | |
4584 Register cell_value_map = r8; | |
4585 Register scratch = r9; | |
4586 | |
4587 Register context = cp; | |
4588 Register context_temp = cell; | |
4589 | |
4590 Label fast_heapobject_case, fast_smi_case, slow_case; | |
4591 | |
4592 if (FLAG_debug_code) { | |
4593 __ CompareRoot(value, Heap::kTheHoleValueRootIndex); | |
4594 __ Check(ne, kUnexpectedValue); | |
4595 } | |
4596 | |
4597 // Go up the context chain to the script context. | |
4598 for (int i = 0; i < depth(); i++) { | |
4599 __ LoadP(context_temp, ContextMemOperand(context, Context::PREVIOUS_INDEX)); | |
4600 context = context_temp; | |
4601 } | |
4602 | |
4603 // Load the PropertyCell at the specified slot. | |
4604 __ ShiftLeftImm(r0, slot, Operand(kPointerSizeLog2)); | |
4605 __ add(cell, context, r0); | |
4606 __ LoadP(cell, ContextMemOperand(cell)); | |
4607 | |
4608 // Load PropertyDetails for the cell (actually only the cell_type and kind). | |
4609 __ LoadP(cell_details, FieldMemOperand(cell, PropertyCell::kDetailsOffset)); | |
4610 __ SmiUntag(cell_details); | |
4611 __ andi(cell_details, cell_details, | |
4612 Operand(PropertyDetails::PropertyCellTypeField::kMask | | |
4613 PropertyDetails::KindField::kMask | | |
4614 PropertyDetails::kAttributesReadOnlyMask)); | |
4615 | |
4616 // Check if PropertyCell holds mutable data. | |
4617 Label not_mutable_data; | |
4618 __ cmpi(cell_details, Operand(PropertyDetails::PropertyCellTypeField::encode( | |
4619 PropertyCellType::kMutable) | | |
4620 PropertyDetails::KindField::encode(kData))); | |
4621 __ bne(¬_mutable_data); | |
4622 __ JumpIfSmi(value, &fast_smi_case); | |
4623 | |
4624 __ bind(&fast_heapobject_case); | |
4625 __ StoreP(value, FieldMemOperand(cell, PropertyCell::kValueOffset), r0); | |
4626 // RecordWriteField clobbers the value register, so we copy it before the | |
4627 // call. | |
4628 __ mr(r6, value); | |
4629 __ RecordWriteField(cell, PropertyCell::kValueOffset, r6, scratch, | |
4630 kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET, | |
4631 OMIT_SMI_CHECK); | |
4632 __ Ret(); | |
4633 | |
4634 __ bind(¬_mutable_data); | |
4635 // Check if PropertyCell value matches the new value (relevant for Constant, | |
4636 // ConstantType and Undefined cells). | |
4637 Label not_same_value; | |
4638 __ LoadP(cell_value, FieldMemOperand(cell, PropertyCell::kValueOffset)); | |
4639 __ cmp(cell_value, value); | |
4640 __ bne(¬_same_value); | |
4641 | |
4642 // Make sure the PropertyCell is not marked READ_ONLY. | |
4643 __ andi(r0, cell_details, Operand(PropertyDetails::kAttributesReadOnlyMask)); | |
4644 __ bne(&slow_case, cr0); | |
4645 | |
4646 if (FLAG_debug_code) { | |
4647 Label done; | |
4648 // This can only be true for Constant, ConstantType and Undefined cells, | |
4649 // because we never store the_hole via this stub. | |
4650 __ cmpi(cell_details, | |
4651 Operand(PropertyDetails::PropertyCellTypeField::encode( | |
4652 PropertyCellType::kConstant) | | |
4653 PropertyDetails::KindField::encode(kData))); | |
4654 __ beq(&done); | |
4655 __ cmpi(cell_details, | |
4656 Operand(PropertyDetails::PropertyCellTypeField::encode( | |
4657 PropertyCellType::kConstantType) | | |
4658 PropertyDetails::KindField::encode(kData))); | |
4659 __ beq(&done); | |
4660 __ cmpi(cell_details, | |
4661 Operand(PropertyDetails::PropertyCellTypeField::encode( | |
4662 PropertyCellType::kUndefined) | | |
4663 PropertyDetails::KindField::encode(kData))); | |
4664 __ Check(eq, kUnexpectedValue); | |
4665 __ bind(&done); | |
4666 } | |
4667 __ Ret(); | |
4668 __ bind(¬_same_value); | |
4669 | |
4670 // Check if PropertyCell contains data with constant type (and is not | |
4671 // READ_ONLY). | |
4672 __ cmpi(cell_details, Operand(PropertyDetails::PropertyCellTypeField::encode( | |
4673 PropertyCellType::kConstantType) | | |
4674 PropertyDetails::KindField::encode(kData))); | |
4675 __ bne(&slow_case); | |
4676 | |
4677 // Now either both old and new values must be smis or both must be heap | |
4678 // objects with same map. | |
4679 Label value_is_heap_object; | |
4680 __ JumpIfNotSmi(value, &value_is_heap_object); | |
4681 __ JumpIfNotSmi(cell_value, &slow_case); | |
4682 // Old and new values are smis, no need for a write barrier here. | |
4683 __ bind(&fast_smi_case); | |
4684 __ StoreP(value, FieldMemOperand(cell, PropertyCell::kValueOffset), r0); | |
4685 __ Ret(); | |
4686 | |
4687 __ bind(&value_is_heap_object); | |
4688 __ JumpIfSmi(cell_value, &slow_case); | |
4689 | |
4690 __ LoadP(cell_value_map, FieldMemOperand(cell_value, HeapObject::kMapOffset)); | |
4691 __ LoadP(scratch, FieldMemOperand(value, HeapObject::kMapOffset)); | |
4692 __ cmp(cell_value_map, scratch); | |
4693 __ beq(&fast_heapobject_case); | |
4694 | |
4695 // Fallback to runtime. | |
4696 __ bind(&slow_case); | |
4697 __ SmiTag(slot); | |
4698 __ Push(slot, value); | |
4699 __ TailCallRuntime(is_strict(language_mode()) | |
4700 ? Runtime::kStoreGlobalViaContext_Strict | |
4701 : Runtime::kStoreGlobalViaContext_Sloppy); | |
4702 } | |
4703 | |
4704 | |
4705 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { | 4577 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { |
4706 return ref0.address() - ref1.address(); | 4578 return ref0.address() - ref1.address(); |
4707 } | 4579 } |
4708 | 4580 |
4709 | 4581 |
4710 // Calls an API function. Allocates HandleScope, extracts returned value | 4582 // Calls an API function. Allocates HandleScope, extracts returned value |
4711 // from handle and propagates exceptions. Restores context. stack_space | 4583 // from handle and propagates exceptions. Restores context. stack_space |
4712 // - space to be unwound on exit (includes the call JS arguments space and | 4584 // - space to be unwound on exit (includes the call JS arguments space and |
4713 // the additional space allocated for the fast call). | 4585 // the additional space allocated for the fast call). |
4714 static void CallApiFunctionAndReturn(MacroAssembler* masm, | 4586 static void CallApiFunctionAndReturn(MacroAssembler* masm, |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5056 fp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize); | 4928 fp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize); |
5057 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, | 4929 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, |
5058 kStackUnwindSpace, NULL, return_value_operand, NULL); | 4930 kStackUnwindSpace, NULL, return_value_operand, NULL); |
5059 } | 4931 } |
5060 | 4932 |
5061 #undef __ | 4933 #undef __ |
5062 } // namespace internal | 4934 } // namespace internal |
5063 } // namespace v8 | 4935 } // namespace v8 |
5064 | 4936 |
5065 #endif // V8_TARGET_ARCH_PPC | 4937 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |