Chromium Code Reviews| 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 |