OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 // Allocate a local context if needed. | 706 // Allocate a local context if needed. |
707 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 707 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
708 if (heap_slots > 0) { | 708 if (heap_slots > 0) { |
709 Comment(";;; Allocate local context"); | 709 Comment(";;; Allocate local context"); |
710 // Argument to NewContext is the function, which is in x1. | 710 // Argument to NewContext is the function, which is in x1. |
711 if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 711 if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
712 FastNewContextStub stub(heap_slots); | 712 FastNewContextStub stub(heap_slots); |
713 __ CallStub(&stub); | 713 __ CallStub(&stub); |
714 } else { | 714 } else { |
715 __ Push(x1); | 715 __ Push(x1); |
716 __ CallRuntime(Runtime::kNewFunctionContext, 1); | 716 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); |
717 } | 717 } |
718 RecordSafepoint(Safepoint::kNoLazyDeopt); | 718 RecordSafepoint(Safepoint::kNoLazyDeopt); |
719 // Context is returned in x0. It replaces the context passed to us. It's | 719 // Context is returned in x0. It replaces the context passed to us. It's |
720 // saved in the stack and kept live in cp. | 720 // saved in the stack and kept live in cp. |
721 __ Mov(cp, x0); | 721 __ Mov(cp, x0); |
722 __ Str(x0, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 722 __ Str(x0, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
723 // Copy any necessary parameters into the context. | 723 // Copy any necessary parameters into the context. |
724 int num_parameters = scope()->num_parameters(); | 724 int num_parameters = scope()->num_parameters(); |
725 for (int i = 0; i < num_parameters; i++) { | 725 for (int i = 0; i < num_parameters; i++) { |
726 Variable* var = scope()->parameter(i); | 726 Variable* var = scope()->parameter(i); |
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1586 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { | 1586 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { |
1587 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); | 1587 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); |
1588 flags = AllocateTargetSpace::update(flags, OLD_DATA_SPACE); | 1588 flags = AllocateTargetSpace::update(flags, OLD_DATA_SPACE); |
1589 } else { | 1589 } else { |
1590 flags = AllocateTargetSpace::update(flags, NEW_SPACE); | 1590 flags = AllocateTargetSpace::update(flags, NEW_SPACE); |
1591 } | 1591 } |
1592 __ Mov(x10, Smi::FromInt(flags)); | 1592 __ Mov(x10, Smi::FromInt(flags)); |
1593 __ Push(size, x10); | 1593 __ Push(size, x10); |
1594 | 1594 |
1595 CallRuntimeFromDeferred( | 1595 CallRuntimeFromDeferred( |
1596 Runtime::kAllocateInTargetSpace, 2, instr, instr->context()); | 1596 Runtime::kHiddenAllocateInTargetSpace, 2, instr, instr->context()); |
1597 __ StoreToSafepointRegisterSlot(x0, ToRegister(instr->result())); | 1597 __ StoreToSafepointRegisterSlot(x0, ToRegister(instr->result())); |
1598 } | 1598 } |
1599 | 1599 |
1600 | 1600 |
1601 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { | 1601 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { |
1602 Register receiver = ToRegister(instr->receiver()); | 1602 Register receiver = ToRegister(instr->receiver()); |
1603 Register function = ToRegister(instr->function()); | 1603 Register function = ToRegister(instr->function()); |
1604 Register length = ToRegister32(instr->length()); | 1604 Register length = ToRegister32(instr->length()); |
1605 | 1605 |
1606 Register elements = ToRegister(instr->elements()); | 1606 Register elements = ToRegister(instr->elements()); |
(...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2808 if (!pretenure && instr->hydrogen()->has_no_literals()) { | 2808 if (!pretenure && instr->hydrogen()->has_no_literals()) { |
2809 FastNewClosureStub stub(instr->hydrogen()->strict_mode(), | 2809 FastNewClosureStub stub(instr->hydrogen()->strict_mode(), |
2810 instr->hydrogen()->is_generator()); | 2810 instr->hydrogen()->is_generator()); |
2811 __ Mov(x2, Operand(instr->hydrogen()->shared_info())); | 2811 __ Mov(x2, Operand(instr->hydrogen()->shared_info())); |
2812 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 2812 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
2813 } else { | 2813 } else { |
2814 __ Mov(x2, Operand(instr->hydrogen()->shared_info())); | 2814 __ Mov(x2, Operand(instr->hydrogen()->shared_info())); |
2815 __ Mov(x1, Operand(pretenure ? factory()->true_value() | 2815 __ Mov(x1, Operand(pretenure ? factory()->true_value() |
2816 : factory()->false_value())); | 2816 : factory()->false_value())); |
2817 __ Push(cp, x2, x1); | 2817 __ Push(cp, x2, x1); |
2818 CallRuntime(Runtime::kNewClosure, 3, instr); | 2818 CallRuntime(Runtime::kHiddenNewClosure, 3, instr); |
2819 } | 2819 } |
2820 } | 2820 } |
2821 | 2821 |
2822 | 2822 |
2823 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { | 2823 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { |
2824 Register map = ToRegister(instr->map()); | 2824 Register map = ToRegister(instr->map()); |
2825 Register result = ToRegister(instr->result()); | 2825 Register result = ToRegister(instr->result()); |
2826 Label load_cache, done; | 2826 Label load_cache, done; |
2827 | 2827 |
2828 __ EnumLengthUntagged(result, map); | 2828 __ EnumLengthUntagged(result, map); |
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3749 // be valid. | 3749 // be valid. |
3750 Label result_ok; | 3750 Label result_ok; |
3751 Register input = ToRegister(instr->value()); | 3751 Register input = ToRegister(instr->value()); |
3752 __ JumpIfSmi(result, &result_ok); | 3752 __ JumpIfSmi(result, &result_ok); |
3753 __ Cmp(input, result); | 3753 __ Cmp(input, result); |
3754 __ Assert(eq, kUnexpectedValue); | 3754 __ Assert(eq, kUnexpectedValue); |
3755 __ Bind(&result_ok); | 3755 __ Bind(&result_ok); |
3756 } | 3756 } |
3757 | 3757 |
3758 { PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 3758 { PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
3759 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr, | 3759 CallRuntimeFromDeferred(Runtime::kHiddenAllocateHeapNumber, 0, instr, |
3760 instr->context()); | 3760 instr->context()); |
3761 __ StoreToSafepointRegisterSlot(x0, result); | 3761 __ StoreToSafepointRegisterSlot(x0, result); |
3762 } | 3762 } |
3763 // The inline (non-deferred) code will store result_bits into result. | 3763 // The inline (non-deferred) code will store result_bits into result. |
3764 } | 3764 } |
3765 | 3765 |
3766 | 3766 |
3767 void LCodeGen::DoMathAbsTagged(LMathAbsTagged* instr) { | 3767 void LCodeGen::DoMathAbsTagged(LMathAbsTagged* instr) { |
3768 // Class for deferred case. | 3768 // Class for deferred case. |
3769 class DeferredMathAbsTagged: public LDeferredCode { | 3769 class DeferredMathAbsTagged: public LDeferredCode { |
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4422 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { | 4422 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { |
4423 // TODO(3095996): Get rid of this. For now, we need to make the | 4423 // TODO(3095996): Get rid of this. For now, we need to make the |
4424 // result register contain a valid pointer because it is already | 4424 // result register contain a valid pointer because it is already |
4425 // contained in the register pointer map. | 4425 // contained in the register pointer map. |
4426 Register result = ToRegister(instr->result()); | 4426 Register result = ToRegister(instr->result()); |
4427 __ Mov(result, 0); | 4427 __ Mov(result, 0); |
4428 | 4428 |
4429 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 4429 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
4430 // NumberTagU and NumberTagD use the context from the frame, rather than | 4430 // NumberTagU and NumberTagD use the context from the frame, rather than |
4431 // the environment's HContext or HInlinedContext value. | 4431 // the environment's HContext or HInlinedContext value. |
4432 // They only call Runtime::kAllocateHeapNumber. | 4432 // They only call Runtime::kHiddenAllocateHeapNumber. |
4433 // The corresponding HChange instructions are added in a phase that does | 4433 // The corresponding HChange instructions are added in a phase that does |
4434 // not have easy access to the local context. | 4434 // not have easy access to the local context. |
4435 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4435 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4436 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 4436 __ CallRuntimeSaveDoubles(Runtime::kHiddenAllocateHeapNumber); |
4437 RecordSafepointWithRegisters( | 4437 RecordSafepointWithRegisters( |
4438 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 4438 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
4439 __ StoreToSafepointRegisterSlot(x0, result); | 4439 __ StoreToSafepointRegisterSlot(x0, result); |
4440 } | 4440 } |
4441 | 4441 |
4442 | 4442 |
4443 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 4443 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
4444 class DeferredNumberTagD: public LDeferredCode { | 4444 class DeferredNumberTagD: public LDeferredCode { |
4445 public: | 4445 public: |
4446 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) | 4446 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4488 // TODO(3095996): Put a valid pointer value in the stack slot where the result | 4488 // TODO(3095996): Put a valid pointer value in the stack slot where the result |
4489 // register is stored, as this register is in the pointer map, but contains an | 4489 // register is stored, as this register is in the pointer map, but contains an |
4490 // integer value. | 4490 // integer value. |
4491 __ Mov(dst, 0); | 4491 __ Mov(dst, 0); |
4492 { | 4492 { |
4493 // Preserve the value of all registers. | 4493 // Preserve the value of all registers. |
4494 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 4494 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
4495 | 4495 |
4496 // NumberTagU and NumberTagD use the context from the frame, rather than | 4496 // NumberTagU and NumberTagD use the context from the frame, rather than |
4497 // the environment's HContext or HInlinedContext value. | 4497 // the environment's HContext or HInlinedContext value. |
4498 // They only call Runtime::kAllocateHeapNumber. | 4498 // They only call Runtime::kHiddenAllocateHeapNumber. |
4499 // The corresponding HChange instructions are added in a phase that does | 4499 // The corresponding HChange instructions are added in a phase that does |
4500 // not have easy access to the local context. | 4500 // not have easy access to the local context. |
4501 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4501 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4502 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 4502 __ CallRuntimeSaveDoubles(Runtime::kHiddenAllocateHeapNumber); |
4503 RecordSafepointWithRegisters( | 4503 RecordSafepointWithRegisters( |
4504 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 4504 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
4505 __ StoreToSafepointRegisterSlot(x0, dst); | 4505 __ StoreToSafepointRegisterSlot(x0, dst); |
4506 } | 4506 } |
4507 | 4507 |
4508 // Convert number to floating point and store in the newly allocated heap | 4508 // Convert number to floating point and store in the newly allocated heap |
4509 // number. | 4509 // number. |
4510 __ Bind(&convert_and_store); | 4510 __ Bind(&convert_and_store); |
4511 DoubleRegister dbl_scratch = double_scratch(); | 4511 DoubleRegister dbl_scratch = double_scratch(); |
4512 __ Ucvtf(dbl_scratch, src); | 4512 __ Ucvtf(dbl_scratch, src); |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4908 Register scratch1 = x5; | 4908 Register scratch1 = x5; |
4909 Register scratch2 = x6; | 4909 Register scratch2 = x6; |
4910 ASSERT(instr->IsMarkedAsCall()); | 4910 ASSERT(instr->IsMarkedAsCall()); |
4911 | 4911 |
4912 ASM_UNIMPLEMENTED_BREAK("DoDeclareGlobals"); | 4912 ASM_UNIMPLEMENTED_BREAK("DoDeclareGlobals"); |
4913 // TODO(all): if Mov could handle object in new space then it could be used | 4913 // TODO(all): if Mov could handle object in new space then it could be used |
4914 // here. | 4914 // here. |
4915 __ LoadHeapObject(scratch1, instr->hydrogen()->pairs()); | 4915 __ LoadHeapObject(scratch1, instr->hydrogen()->pairs()); |
4916 __ Mov(scratch2, Smi::FromInt(instr->hydrogen()->flags())); | 4916 __ Mov(scratch2, Smi::FromInt(instr->hydrogen()->flags())); |
4917 __ Push(cp, scratch1, scratch2); // The context is the first argument. | 4917 __ Push(cp, scratch1, scratch2); // The context is the first argument. |
4918 CallRuntime(Runtime::kDeclareGlobals, 3, instr); | 4918 CallRuntime(Runtime::kHiddenDeclareGlobals, 3, instr); |
4919 } | 4919 } |
4920 | 4920 |
4921 | 4921 |
4922 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { | 4922 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { |
4923 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 4923 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
4924 LoadContextFromDeferred(instr->context()); | 4924 LoadContextFromDeferred(instr->context()); |
4925 __ CallRuntimeSaveDoubles(Runtime::kStackGuard); | 4925 __ CallRuntimeSaveDoubles(Runtime::kHiddenStackGuard); |
4926 RecordSafepointWithLazyDeopt( | 4926 RecordSafepointWithLazyDeopt( |
4927 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); | 4927 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); |
4928 ASSERT(instr->HasEnvironment()); | 4928 ASSERT(instr->HasEnvironment()); |
4929 LEnvironment* env = instr->environment(); | 4929 LEnvironment* env = instr->environment(); |
4930 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 4930 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |
4931 } | 4931 } |
4932 | 4932 |
4933 | 4933 |
4934 void LCodeGen::DoStackCheck(LStackCheck* instr) { | 4934 void LCodeGen::DoStackCheck(LStackCheck* instr) { |
4935 class DeferredStackCheck: public LDeferredCode { | 4935 class DeferredStackCheck: public LDeferredCode { |
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5607 __ LoadObject(x7, instr->hydrogen()->literals()); | 5607 __ LoadObject(x7, instr->hydrogen()->literals()); |
5608 __ Ldr(x1, FieldMemOperand(x7, literal_offset)); | 5608 __ Ldr(x1, FieldMemOperand(x7, literal_offset)); |
5609 __ JumpIfNotRoot(x1, Heap::kUndefinedValueRootIndex, &materialized); | 5609 __ JumpIfNotRoot(x1, Heap::kUndefinedValueRootIndex, &materialized); |
5610 | 5610 |
5611 // Create regexp literal using runtime function | 5611 // Create regexp literal using runtime function |
5612 // Result will be in x0. | 5612 // Result will be in x0. |
5613 __ Mov(x12, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); | 5613 __ Mov(x12, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); |
5614 __ Mov(x11, Operand(instr->hydrogen()->pattern())); | 5614 __ Mov(x11, Operand(instr->hydrogen()->pattern())); |
5615 __ Mov(x10, Operand(instr->hydrogen()->flags())); | 5615 __ Mov(x10, Operand(instr->hydrogen()->flags())); |
5616 __ Push(x7, x12, x11, x10); | 5616 __ Push(x7, x12, x11, x10); |
5617 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr); | 5617 CallRuntime(Runtime::kHiddenMaterializeRegExpLiteral, 4, instr); |
5618 __ Mov(x1, x0); | 5618 __ Mov(x1, x0); |
5619 | 5619 |
5620 __ Bind(&materialized); | 5620 __ Bind(&materialized); |
5621 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; | 5621 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; |
5622 Label allocated, runtime_allocate; | 5622 Label allocated, runtime_allocate; |
5623 | 5623 |
5624 __ Allocate(size, x0, x10, x11, &runtime_allocate, TAG_OBJECT); | 5624 __ Allocate(size, x0, x10, x11, &runtime_allocate, TAG_OBJECT); |
5625 __ B(&allocated); | 5625 __ B(&allocated); |
5626 | 5626 |
5627 __ Bind(&runtime_allocate); | 5627 __ Bind(&runtime_allocate); |
5628 __ Mov(x0, Smi::FromInt(size)); | 5628 __ Mov(x0, Smi::FromInt(size)); |
5629 __ Push(x1, x0); | 5629 __ Push(x1, x0); |
5630 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); | 5630 CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1, instr); |
5631 __ Pop(x1); | 5631 __ Pop(x1); |
5632 | 5632 |
5633 __ Bind(&allocated); | 5633 __ Bind(&allocated); |
5634 // Copy the content into the newly allocated memory. | 5634 // Copy the content into the newly allocated memory. |
5635 __ CopyFields(x0, x1, CPURegList(x10, x11, x12), size / kPointerSize); | 5635 __ CopyFields(x0, x1, CPURegList(x10, x11, x12), size / kPointerSize); |
5636 } | 5636 } |
5637 | 5637 |
5638 | 5638 |
5639 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { | 5639 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { |
5640 Register object = ToRegister(instr->object()); | 5640 Register object = ToRegister(instr->object()); |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5871 __ Bind(&out_of_object); | 5871 __ Bind(&out_of_object); |
5872 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5872 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
5873 // Index is equal to negated out of object property index plus 1. | 5873 // Index is equal to negated out of object property index plus 1. |
5874 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5874 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
5875 __ Ldr(result, FieldMemOperand(result, | 5875 __ Ldr(result, FieldMemOperand(result, |
5876 FixedArray::kHeaderSize - kPointerSize)); | 5876 FixedArray::kHeaderSize - kPointerSize)); |
5877 __ Bind(&done); | 5877 __ Bind(&done); |
5878 } | 5878 } |
5879 | 5879 |
5880 } } // namespace v8::internal | 5880 } } // namespace v8::internal |
OLD | NEW |