Chromium Code Reviews| Index: src/builtins/builtins-array-gen.cc |
| diff --git a/src/builtins/builtins-array-gen.cc b/src/builtins/builtins-array-gen.cc |
| index 21269fdc65bae7854fa2604358c63ee423207902..78074e27513bca2a75833a0a0521d879a09ec6bf 100644 |
| --- a/src/builtins/builtins-array-gen.cc |
| +++ b/src/builtins/builtins-array-gen.cc |
| @@ -15,6 +15,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler { |
| : CodeStubAssembler(state), |
| k_(this, MachineRepresentation::kTagged), |
| a_(this, MachineRepresentation::kTagged), |
| + force_slow_(this, MachineRepresentation::kTagged, SmiConstant(0)), |
| to_(this, MachineRepresentation::kTagged, SmiConstant(0)) {} |
| typedef std::function<Node*(ArrayBuiltinCodeStubAssembler* masm)> |
| @@ -195,8 +196,37 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler { |
| } |
| Node* MapResultGenerator() { |
| - // 5. Let A be ? ArraySpeciesCreate(O, len). |
| - return ArraySpeciesCreate(context(), o(), len_); |
| + VARIABLE(species_constructor, MachineRepresentation::kTagged); |
| + Label slow_path(this), done(this, &species_constructor); |
| + GotoIf(DoesntHaveInstanceType(o(), JS_ARRAY_TYPE), &slow_path); |
| + Node* o_map = LoadMap(o()); |
| + Node* const initial_array_prototype = LoadContextElement( |
| + LoadNativeContext(context()), Context::INITIAL_ARRAY_PROTOTYPE_INDEX); |
| + Node* proto = LoadMapPrototype(o_map); |
| + GotoIf(WordNotEqual(proto, initial_array_prototype), &slow_path); |
| + |
| + Node* species_protector = SpeciesProtectorConstant(); |
| + Node* value = LoadObjectField(species_protector, Cell::kValueOffset); |
| + Node* const protector_invalid = SmiConstant(Isolate::kProtectorInvalid); |
| + GotoIf(WordEqual(value, protector_invalid), &slow_path); |
| + |
| + Node* const initial_array_constructor = LoadContextElement( |
| + LoadNativeContext(context()), Context::ARRAY_FUNCTION_INDEX); |
| + species_constructor.Bind(initial_array_constructor); |
| + Goto(&done); |
| + |
| + BIND(&slow_path); |
| + { |
| + // 5. Let A be ? ArraySpeciesCreate(O, len). |
| + Node* constructor = |
| + CallRuntime(Runtime::kArraySpeciesConstructor, context(), o()); |
| + species_constructor.Bind(constructor); |
| + force_slow_.Bind(SmiConstant(1)); |
|
danno
2017/04/29 09:27:14
Would it be a little cleaner to just jump to the s
|
| + Goto(&done); |
| + } |
| + BIND(&done); |
|
danno
2017/04/29 09:27:14
I am a little surprised this works... you change t
|
| + return ConstructJS(CodeFactory::Construct(isolate()), context(), |
| + species_constructor.value(), len_); |
| } |
| Node* MapProcessor(Node* k_value, Node* k) { |
| @@ -215,6 +245,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler { |
| Label fast(this); |
| Label runtime(this); |
| Label object_push_pre(this), object_push(this), double_push(this); |
| + GotoIf(WordEqual(force_slow(), SmiConstant(1)), &runtime); |
| BranchIfFastJSArray(a(), context(), FastJSArrayAccessMode::ANY_ACCESS, |
| &fast, &runtime); |
| @@ -270,6 +301,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler { |
| Node* len() { return len_; } |
| Node* callbackfn() { return callbackfn_; } |
| Node* this_arg() { return this_arg_; } |
| + Node* force_slow() { return force_slow_.value(); } |
| Node* k() { return k_.value(); } |
| Node* a() { return a_.value(); } |
| @@ -384,6 +416,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler { |
| o_ = o; |
| len_ = len; |
| to_.Bind(to); |
| + force_slow_.Bind(SmiConstant(1)); |
| } |
| void GenerateIteratingTypedArrayBuiltinBody( |
| @@ -710,6 +743,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler { |
| Node* new_target_ = nullptr; |
| Variable k_; |
| Variable a_; |
| + Variable force_slow_; |
| Variable to_; |
| }; |