OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
7 | 7 #include "src/interface-descriptors.h" |
8 #include "src/macro-assembler.h" | 8 #include "src/macro-assembler.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
11 namespace internal { | 11 namespace internal { |
12 | 12 |
13 BUILTIN(Illegal) { | 13 BUILTIN(Illegal) { |
14 UNREACHABLE(); | 14 UNREACHABLE(); |
15 return isolate->heap()->undefined_value(); // Make compiler happy. | 15 return isolate->heap()->undefined_value(); // Make compiler happy. |
16 } | 16 } |
17 | 17 |
(...skipping 25 matching lines...) Expand all Loading... |
43 // Interrupt and stack checks. | 43 // Interrupt and stack checks. |
44 | 44 |
45 void Builtins::Generate_InterruptCheck(MacroAssembler* masm) { | 45 void Builtins::Generate_InterruptCheck(MacroAssembler* masm) { |
46 masm->TailCallRuntime(Runtime::kInterrupt); | 46 masm->TailCallRuntime(Runtime::kInterrupt); |
47 } | 47 } |
48 | 48 |
49 void Builtins::Generate_StackCheck(MacroAssembler* masm) { | 49 void Builtins::Generate_StackCheck(MacroAssembler* masm) { |
50 masm->TailCallRuntime(Runtime::kStackGuard); | 50 masm->TailCallRuntime(Runtime::kStackGuard); |
51 } | 51 } |
52 | 52 |
| 53 // ----------------------------------------------------------------------------- |
| 54 // FixedArray helpers. |
| 55 |
| 56 void Builtins::Generate_CopyFixedArray(CodeStubAssembler* assembler) { |
| 57 typedef CodeStubAssembler::Label Label; |
| 58 typedef compiler::Node Node; |
| 59 typedef CodeStubAssembler::Variable Variable; |
| 60 typedef CopyFixedArrayDescriptor Descriptor; |
| 61 |
| 62 Node* source = assembler->Parameter(Descriptor::kSource); |
| 63 |
| 64 // Load the {source} length. |
| 65 Node* source_length_tagged = |
| 66 assembler->LoadObjectField(source, FixedArray::kLengthOffset); |
| 67 Node* source_length = assembler->SmiToWord(source_length_tagged); |
| 68 |
| 69 // Compute the size of {source} in bytes. |
| 70 Node* source_size = assembler->IntPtrAdd( |
| 71 assembler->WordShl(source_length, |
| 72 assembler->IntPtrConstant(kPointerSizeLog2)), |
| 73 assembler->IntPtrConstant(FixedArray::kHeaderSize)); |
| 74 |
| 75 // Check if we can allocate in new space. |
| 76 Label if_newspace(assembler), if_oldspace(assembler); |
| 77 assembler->Branch(assembler->UintPtrLessThan( |
| 78 source_size, assembler->IntPtrConstant( |
| 79 Page::kMaxRegularHeapObjectSize)), |
| 80 &if_newspace, &if_oldspace); |
| 81 |
| 82 assembler->Bind(&if_newspace); |
| 83 { |
| 84 // Allocate the targeting FixedArray in new space. |
| 85 Node* target = assembler->Allocate(source_size); |
| 86 assembler->StoreMapNoWriteBarrier( |
| 87 target, assembler->LoadRoot(Heap::kFixedArrayMapRootIndex)); |
| 88 assembler->StoreObjectFieldNoWriteBarrier(target, FixedArray::kLengthOffset, |
| 89 source_length_tagged); |
| 90 |
| 91 // Compute the limit. |
| 92 Node* limit = assembler->IntPtrSub( |
| 93 source_size, assembler->IntPtrConstant(kHeapObjectTag)); |
| 94 |
| 95 // Copy the {source} to the {target}. |
| 96 Variable var_offset(assembler, MachineType::PointerRepresentation()); |
| 97 Label loop(assembler, &var_offset), done_loop(assembler); |
| 98 var_offset.Bind( |
| 99 assembler->IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 100 assembler->Goto(&loop); |
| 101 assembler->Bind(&loop); |
| 102 { |
| 103 // Determine the current {offset}. |
| 104 Node* offset = var_offset.value(); |
| 105 |
| 106 // Check if we are done. |
| 107 assembler->GotoUnless(assembler->UintPtrLessThan(offset, limit), |
| 108 &done_loop); |
| 109 |
| 110 // Load the value from {source}. |
| 111 Node* value = assembler->Load(MachineType::AnyTagged(), source, offset); |
| 112 |
| 113 // Store the {value} to the {target} without a write barrier, since we |
| 114 // know that the {target} is allocated in new space. |
| 115 assembler->StoreNoWriteBarrier(MachineRepresentation::kTagged, target, |
| 116 offset, value); |
| 117 |
| 118 // Increment {offset} and continue. |
| 119 var_offset.Bind(assembler->IntPtrAdd( |
| 120 offset, assembler->IntPtrConstant(kPointerSize))); |
| 121 assembler->Goto(&loop); |
| 122 } |
| 123 |
| 124 assembler->Bind(&done_loop); |
| 125 assembler->Return(target); |
| 126 } |
| 127 |
| 128 assembler->Bind(&if_oldspace); |
| 129 { |
| 130 // Allocate the targeting FixedArray in old space |
| 131 // (maybe even in large object space). |
| 132 Node* flags = assembler->SmiConstant( |
| 133 Smi::FromInt(AllocateDoubleAlignFlag::encode(false) | |
| 134 AllocateTargetSpace::encode(AllocationSpace::OLD_SPACE))); |
| 135 Node* source_size_tagged = assembler->SmiFromWord(source_size); |
| 136 Node* target = assembler->CallRuntime(Runtime::kAllocateInTargetSpace, |
| 137 assembler->NoContextConstant(), |
| 138 source_size_tagged, flags); |
| 139 assembler->StoreMapNoWriteBarrier( |
| 140 target, assembler->LoadRoot(Heap::kFixedArrayMapRootIndex)); |
| 141 assembler->StoreObjectFieldNoWriteBarrier(target, FixedArray::kLengthOffset, |
| 142 source_length_tagged); |
| 143 |
| 144 // Compute the limit. |
| 145 Node* limit = assembler->IntPtrSub( |
| 146 source_size, assembler->IntPtrConstant(kHeapObjectTag)); |
| 147 |
| 148 // Copy the {source} to the {target}. |
| 149 Variable var_offset(assembler, MachineType::PointerRepresentation()); |
| 150 Label loop(assembler, &var_offset), done_loop(assembler); |
| 151 var_offset.Bind( |
| 152 assembler->IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 153 assembler->Goto(&loop); |
| 154 assembler->Bind(&loop); |
| 155 { |
| 156 // Determine the current {offset}. |
| 157 Node* offset = var_offset.value(); |
| 158 |
| 159 // Check if we are done. |
| 160 assembler->GotoUnless(assembler->UintPtrLessThan(offset, limit), |
| 161 &done_loop); |
| 162 |
| 163 // Load the value from {source}. |
| 164 Node* value = assembler->Load(MachineType::AnyTagged(), source, offset); |
| 165 |
| 166 // Store the {value} to the {target} with a proper write barrier. |
| 167 assembler->Store(MachineRepresentation::kTagged, target, offset, value); |
| 168 |
| 169 // Increment {offset} and continue. |
| 170 var_offset.Bind(assembler->IntPtrAdd( |
| 171 offset, assembler->IntPtrConstant(kPointerSize))); |
| 172 assembler->Goto(&loop); |
| 173 } |
| 174 |
| 175 assembler->Bind(&done_loop); |
| 176 assembler->Return(target); |
| 177 } |
| 178 } |
| 179 |
53 } // namespace internal | 180 } // namespace internal |
54 } // namespace v8 | 181 } // namespace v8 |
OLD | NEW |