OLD | NEW |
---|---|
1 // Copyright 2017 the V8 project authors. All rights reserved. | 1 // Copyright 2017 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-utils-gen.h" | 5 #include "src/builtins/builtins-utils-gen.h" |
6 #include "src/builtins/builtins.h" | 6 #include "src/builtins/builtins.h" |
7 #include "src/code-stub-assembler.h" | 7 #include "src/code-stub-assembler.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
11 | 11 |
12 class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler { | 12 class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler { |
13 public: | 13 public: |
14 explicit ArrayBuiltinCodeStubAssembler(compiler::CodeAssemblerState* state) | 14 explicit ArrayBuiltinCodeStubAssembler(compiler::CodeAssemblerState* state) |
15 : CodeStubAssembler(state), | 15 : CodeStubAssembler(state), |
16 k_(this, MachineRepresentation::kTagged), | 16 k_(this, MachineRepresentation::kTagged), |
17 a_(this, MachineRepresentation::kTagged), | 17 a_(this, MachineRepresentation::kTagged), |
18 force_slow_(this, MachineRepresentation::kTagged, SmiConstant(0)), | |
18 to_(this, MachineRepresentation::kTagged, SmiConstant(0)) {} | 19 to_(this, MachineRepresentation::kTagged, SmiConstant(0)) {} |
19 | 20 |
20 typedef std::function<Node*(ArrayBuiltinCodeStubAssembler* masm)> | 21 typedef std::function<Node*(ArrayBuiltinCodeStubAssembler* masm)> |
21 BuiltinResultGenerator; | 22 BuiltinResultGenerator; |
22 | 23 |
23 typedef std::function<void(ArrayBuiltinCodeStubAssembler* masm)> | 24 typedef std::function<void(ArrayBuiltinCodeStubAssembler* masm)> |
24 BuiltinResultIndexInitializer; | 25 BuiltinResultIndexInitializer; |
25 | 26 |
26 typedef std::function<Node*(ArrayBuiltinCodeStubAssembler* masm, | 27 typedef std::function<Node*(ArrayBuiltinCodeStubAssembler* masm, |
27 Node* k_value, Node* k)> | 28 Node* k_value, Node* k)> |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 // 2. Increase to by 1. | 189 // 2. Increase to by 1. |
189 to_.Bind(NumberInc(to_.value())); | 190 to_.Bind(NumberInc(to_.value())); |
190 Goto(&false_continue); | 191 Goto(&false_continue); |
191 } | 192 } |
192 } | 193 } |
193 BIND(&false_continue); | 194 BIND(&false_continue); |
194 return a(); | 195 return a(); |
195 } | 196 } |
196 | 197 |
197 Node* MapResultGenerator() { | 198 Node* MapResultGenerator() { |
198 // 5. Let A be ? ArraySpeciesCreate(O, len). | 199 VARIABLE(species_constructor, MachineRepresentation::kTagged); |
199 return ArraySpeciesCreate(context(), o(), len_); | 200 Label slow_path(this), done(this, &species_constructor); |
201 GotoIf(DoesntHaveInstanceType(o(), JS_ARRAY_TYPE), &slow_path); | |
202 Node* o_map = LoadMap(o()); | |
203 Node* const initial_array_prototype = LoadContextElement( | |
204 LoadNativeContext(context()), Context::INITIAL_ARRAY_PROTOTYPE_INDEX); | |
205 Node* proto = LoadMapPrototype(o_map); | |
206 GotoIf(WordNotEqual(proto, initial_array_prototype), &slow_path); | |
207 | |
208 Node* species_protector = SpeciesProtectorConstant(); | |
209 Node* value = LoadObjectField(species_protector, Cell::kValueOffset); | |
210 Node* const protector_invalid = SmiConstant(Isolate::kProtectorInvalid); | |
211 GotoIf(WordEqual(value, protector_invalid), &slow_path); | |
212 | |
213 Node* const initial_array_constructor = LoadContextElement( | |
214 LoadNativeContext(context()), Context::ARRAY_FUNCTION_INDEX); | |
215 species_constructor.Bind(initial_array_constructor); | |
216 Goto(&done); | |
217 | |
218 BIND(&slow_path); | |
219 { | |
220 // 5. Let A be ? ArraySpeciesCreate(O, len). | |
221 Node* constructor = | |
222 CallRuntime(Runtime::kArraySpeciesConstructor, context(), o()); | |
223 species_constructor.Bind(constructor); | |
224 force_slow_.Bind(SmiConstant(1)); | |
danno
2017/04/29 09:27:14
Would it be a little cleaner to just jump to the s
| |
225 Goto(&done); | |
226 } | |
227 BIND(&done); | |
danno
2017/04/29 09:27:14
I am a little surprised this works... you change t
| |
228 return ConstructJS(CodeFactory::Construct(isolate()), context(), | |
229 species_constructor.value(), len_); | |
200 } | 230 } |
201 | 231 |
202 Node* MapProcessor(Node* k_value, Node* k) { | 232 Node* MapProcessor(Node* k_value, Node* k) { |
203 // i. Let kValue be ? Get(O, Pk). Performed by the caller of MapProcessor. | 233 // i. Let kValue be ? Get(O, Pk). Performed by the caller of MapProcessor. |
204 // ii. Let mappedValue be ? Call(callbackfn, T, kValue, k, O). | 234 // ii. Let mappedValue be ? Call(callbackfn, T, kValue, k, O). |
205 Node* mappedValue = CallJS(CodeFactory::Call(isolate()), context(), | 235 Node* mappedValue = CallJS(CodeFactory::Call(isolate()), context(), |
206 callbackfn(), this_arg(), k_value, k, o()); | 236 callbackfn(), this_arg(), k_value, k, o()); |
207 | 237 |
208 Label finished(this); | 238 Label finished(this); |
209 Node* kind = nullptr; | 239 Node* kind = nullptr; |
210 Node* elements = nullptr; | 240 Node* elements = nullptr; |
211 | 241 |
212 // If a() is a JSArray, we can have a fast path. | 242 // If a() is a JSArray, we can have a fast path. |
213 // mode is SMI_PARAMETERS because k has tagged representation. | 243 // mode is SMI_PARAMETERS because k has tagged representation. |
214 ParameterMode mode = SMI_PARAMETERS; | 244 ParameterMode mode = SMI_PARAMETERS; |
215 Label fast(this); | 245 Label fast(this); |
216 Label runtime(this); | 246 Label runtime(this); |
217 Label object_push_pre(this), object_push(this), double_push(this); | 247 Label object_push_pre(this), object_push(this), double_push(this); |
248 GotoIf(WordEqual(force_slow(), SmiConstant(1)), &runtime); | |
218 BranchIfFastJSArray(a(), context(), FastJSArrayAccessMode::ANY_ACCESS, | 249 BranchIfFastJSArray(a(), context(), FastJSArrayAccessMode::ANY_ACCESS, |
219 &fast, &runtime); | 250 &fast, &runtime); |
220 | 251 |
221 BIND(&fast); | 252 BIND(&fast); |
222 { | 253 { |
223 kind = EnsureArrayPushable(a(), &runtime); | 254 kind = EnsureArrayPushable(a(), &runtime); |
224 elements = LoadElements(a()); | 255 elements = LoadElements(a()); |
225 GotoIf(IsElementsKindGreaterThan(kind, FAST_HOLEY_SMI_ELEMENTS), | 256 GotoIf(IsElementsKindGreaterThan(kind, FAST_HOLEY_SMI_ELEMENTS), |
226 &object_push_pre); | 257 &object_push_pre); |
227 TryStoreArrayElement(FAST_SMI_ELEMENTS, mode, &runtime, elements, k, | 258 TryStoreArrayElement(FAST_SMI_ELEMENTS, mode, &runtime, elements, k, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 void NullPostLoopAction() {} | 294 void NullPostLoopAction() {} |
264 | 295 |
265 protected: | 296 protected: |
266 Node* context() { return context_; } | 297 Node* context() { return context_; } |
267 Node* receiver() { return receiver_; } | 298 Node* receiver() { return receiver_; } |
268 Node* new_target() { return new_target_; } | 299 Node* new_target() { return new_target_; } |
269 Node* o() { return o_; } | 300 Node* o() { return o_; } |
270 Node* len() { return len_; } | 301 Node* len() { return len_; } |
271 Node* callbackfn() { return callbackfn_; } | 302 Node* callbackfn() { return callbackfn_; } |
272 Node* this_arg() { return this_arg_; } | 303 Node* this_arg() { return this_arg_; } |
304 Node* force_slow() { return force_slow_.value(); } | |
273 Node* k() { return k_.value(); } | 305 Node* k() { return k_.value(); } |
274 Node* a() { return a_.value(); } | 306 Node* a() { return a_.value(); } |
275 | 307 |
276 void InitIteratingArrayBuiltinBody(Node* context, Node* receiver, | 308 void InitIteratingArrayBuiltinBody(Node* context, Node* receiver, |
277 Node* callbackfn, Node* this_arg, | 309 Node* callbackfn, Node* this_arg, |
278 Node* new_target) { | 310 Node* new_target) { |
279 context_ = context; | 311 context_ = context; |
280 receiver_ = receiver; | 312 receiver_ = receiver; |
281 new_target_ = new_target; | 313 new_target_ = new_target; |
282 callbackfn_ = callbackfn; | 314 callbackfn_ = callbackfn; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
377 Node* o, Node* initial_k, | 409 Node* o, Node* initial_k, |
378 Node* len, Node* to) { | 410 Node* len, Node* to) { |
379 context_ = context; | 411 context_ = context; |
380 this_arg_ = this_arg; | 412 this_arg_ = this_arg; |
381 callbackfn_ = callbackfn; | 413 callbackfn_ = callbackfn; |
382 a_.Bind(a); | 414 a_.Bind(a); |
383 k_.Bind(initial_k); | 415 k_.Bind(initial_k); |
384 o_ = o; | 416 o_ = o; |
385 len_ = len; | 417 len_ = len; |
386 to_.Bind(to); | 418 to_.Bind(to); |
419 force_slow_.Bind(SmiConstant(1)); | |
387 } | 420 } |
388 | 421 |
389 void GenerateIteratingTypedArrayBuiltinBody( | 422 void GenerateIteratingTypedArrayBuiltinBody( |
390 const char* name, const BuiltinResultGenerator& generator, | 423 const char* name, const BuiltinResultGenerator& generator, |
391 const CallResultProcessor& processor, const PostLoopAction& action, | 424 const CallResultProcessor& processor, const PostLoopAction& action, |
392 ForEachDirection direction = ForEachDirection::kForward) { | 425 ForEachDirection direction = ForEachDirection::kForward) { |
393 Node* name_string = | 426 Node* name_string = |
394 HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(name)); | 427 HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(name)); |
395 | 428 |
396 // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray | 429 // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
703 | 736 |
704 Node* callbackfn_ = nullptr; | 737 Node* callbackfn_ = nullptr; |
705 Node* o_ = nullptr; | 738 Node* o_ = nullptr; |
706 Node* this_arg_ = nullptr; | 739 Node* this_arg_ = nullptr; |
707 Node* len_ = nullptr; | 740 Node* len_ = nullptr; |
708 Node* context_ = nullptr; | 741 Node* context_ = nullptr; |
709 Node* receiver_ = nullptr; | 742 Node* receiver_ = nullptr; |
710 Node* new_target_ = nullptr; | 743 Node* new_target_ = nullptr; |
711 Variable k_; | 744 Variable k_; |
712 Variable a_; | 745 Variable a_; |
746 Variable force_slow_; | |
713 Variable to_; | 747 Variable to_; |
714 }; | 748 }; |
715 | 749 |
716 TF_BUILTIN(FastArrayPush, CodeStubAssembler) { | 750 TF_BUILTIN(FastArrayPush, CodeStubAssembler) { |
717 VARIABLE(arg_index, MachineType::PointerRepresentation()); | 751 VARIABLE(arg_index, MachineType::PointerRepresentation()); |
718 Label default_label(this, &arg_index); | 752 Label default_label(this, &arg_index); |
719 Label smi_transition(this); | 753 Label smi_transition(this); |
720 Label object_push_pre(this); | 754 Label object_push_pre(this); |
721 Label object_push(this, &arg_index); | 755 Label object_push(this, &arg_index); |
722 Label double_push(this, &arg_index); | 756 Label double_push(this, &arg_index); |
(...skipping 1509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2232 { | 2266 { |
2233 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); | 2267 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); |
2234 CallRuntime(Runtime::kThrowTypeError, context, message, | 2268 CallRuntime(Runtime::kThrowTypeError, context, message, |
2235 HeapConstant(operation)); | 2269 HeapConstant(operation)); |
2236 Unreachable(); | 2270 Unreachable(); |
2237 } | 2271 } |
2238 } | 2272 } |
2239 | 2273 |
2240 } // namespace internal | 2274 } // namespace internal |
2241 } // namespace v8 | 2275 } // namespace v8 |
OLD | NEW |