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 // Copy the {source} to the {target}. | |
92 Variable var_index(assembler, MachineType::PointerRepresentation()); | |
93 Label loop(assembler, &var_index), done_loop(assembler); | |
94 var_index.Bind(assembler->IntPtrConstant(0)); | |
epertoso
2016/08/05 10:21:41
nit: if you bind this to FixedArray::kHeaderSize -
Benedikt Meurer
2016/08/05 10:30:25
Nice idea! Done.
| |
95 assembler->Goto(&loop); | |
96 assembler->Bind(&loop); | |
97 { | |
98 // Determine the current {index}. | |
99 Node* index = var_index.value(); | |
100 | |
101 // Check if we are done. | |
102 assembler->GotoUnless(assembler->UintPtrLessThan(index, source_length), | |
103 &done_loop); | |
104 | |
105 // Load the value from {source}. | |
106 Node* value = assembler->Load( | |
107 MachineType::AnyTagged(), source, | |
108 assembler->IntPtrAdd( | |
109 assembler->WordShl(index, | |
110 assembler->IntPtrConstant(kPointerSizeLog2)), | |
111 assembler->IntPtrConstant(FixedArray::kHeaderSize - | |
112 kHeapObjectTag))); | |
113 | |
114 // Store the {value} to the {target} without a write barrier, since we | |
115 // know that the {target} is allocated in new space. | |
116 assembler->StoreNoWriteBarrier( | |
117 MachineRepresentation::kTagged, target, | |
118 assembler->IntPtrAdd( | |
119 assembler->WordShl(index, | |
120 assembler->IntPtrConstant(kPointerSizeLog2)), | |
121 assembler->IntPtrConstant(FixedArray::kHeaderSize - | |
122 kHeapObjectTag)), | |
123 value); | |
124 | |
125 // Increment {index} and continue. | |
126 var_index.Bind(assembler->IntPtrAdd(index, assembler->IntPtrConstant(1))); | |
127 assembler->Goto(&loop); | |
128 } | |
129 | |
130 assembler->Bind(&done_loop); | |
131 assembler->Return(target); | |
132 } | |
133 | |
134 assembler->Bind(&if_oldspace); | |
135 { | |
136 // Allocate the targeting FixedArray in old space | |
137 // (maybe even in large object space). | |
138 Node* flags = assembler->SmiConstant( | |
139 Smi::FromInt(AllocateDoubleAlignFlag::encode(false) | | |
140 AllocateTargetSpace::encode(AllocationSpace::OLD_SPACE))); | |
141 Node* source_size_tagged = assembler->SmiFromWord(source_size); | |
142 Node* target = assembler->CallRuntime(Runtime::kAllocateInTargetSpace, | |
143 assembler->NoContextConstant(), | |
144 source_size_tagged, flags); | |
145 assembler->StoreMapNoWriteBarrier( | |
146 target, assembler->LoadRoot(Heap::kFixedArrayMapRootIndex)); | |
147 assembler->StoreObjectFieldNoWriteBarrier(target, FixedArray::kLengthOffset, | |
148 source_length_tagged); | |
149 | |
150 // Copy the {source} to the {target}. | |
151 Variable var_index(assembler, MachineType::PointerRepresentation()); | |
152 Label loop(assembler, &var_index), done_loop(assembler); | |
153 var_index.Bind(assembler->IntPtrConstant(0)); | |
154 assembler->Goto(&loop); | |
155 assembler->Bind(&loop); | |
156 { | |
157 // Determine the current {index}. | |
158 Node* index = var_index.value(); | |
159 | |
160 // Check if we are done. | |
161 assembler->GotoUnless(assembler->UintPtrLessThan(index, source_length), | |
162 &done_loop); | |
163 | |
164 // Load the value from {source}. | |
165 Node* value = assembler->Load( | |
166 MachineType::AnyTagged(), source, | |
167 assembler->IntPtrAdd( | |
168 assembler->WordShl(index, | |
169 assembler->IntPtrConstant(kPointerSizeLog2)), | |
170 assembler->IntPtrConstant(FixedArray::kHeaderSize - | |
171 kHeapObjectTag))); | |
172 | |
173 // Store the {value} to the {target} with an appropriate write barrier. | |
174 assembler->Store(MachineRepresentation::kTagged, target, | |
175 assembler->IntPtrAdd( | |
176 assembler->WordShl(index, assembler->IntPtrConstant( | |
177 kPointerSizeLog2)), | |
178 assembler->IntPtrConstant(FixedArray::kHeaderSize - | |
179 kHeapObjectTag)), | |
180 value); | |
181 | |
182 // Increment {index} and continue. | |
183 var_index.Bind(assembler->IntPtrAdd(index, assembler->IntPtrConstant(1))); | |
184 assembler->Goto(&loop); | |
185 } | |
186 | |
187 assembler->Bind(&done_loop); | |
188 assembler->Return(target); | |
189 } | |
190 } | |
191 | |
53 } // namespace internal | 192 } // namespace internal |
54 } // namespace v8 | 193 } // namespace v8 |
OLD | NEW |