Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: src/builtins/builtins-array-gen.cc

Issue 2753793002: [builtins] Separate Array.prototype.* CSA builtins into two parts (Closed)
Patch Set: Remove stray changes Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/builtins/builtins.h ('k') | src/code-factory.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 16
17 typedef std::function<Node*(Node* o, Node* len)> BuiltinResultGenerator; 17 typedef std::function<Node*(Node* o, Node* len)> BuiltinResultGenerator;
18 typedef std::function<void(Node* a, Node* pK, Node* value)> 18 typedef std::function<void(Node* a, Node* pK, Node* value)>
19 CallResultProcessor; 19 CallResultProcessor;
20 20
21 void GenerateArrayIteratingBuiltinBody( 21 void GenerateIteratingArrayBuiltinBody(
22 const char* name, Node* receiver, Node* callbackfn, Node* this_arg, 22 const char* name, const BuiltinResultGenerator& generator,
23 Node* context, const BuiltinResultGenerator& generator, 23 const CallResultProcessor& processor,
24 const CallResultProcessor& processor) { 24 const Callable& slow_case_continuation) {
25 Node* receiver = Parameter(IteratingArrayBuiltinDescriptor::kReceiver);
26 Node* callbackfn = Parameter(IteratingArrayBuiltinDescriptor::kCallback);
27 Node* this_arg = Parameter(IteratingArrayBuiltinDescriptor::kThisArg);
28 Node* context = Parameter(IteratingArrayBuiltinDescriptor::kContext);
29 Node* new_target = Parameter(IteratingArrayBuiltinDescriptor::kNewTarget);
30
25 Variable k(this, MachineRepresentation::kTagged, SmiConstant(0)); 31 Variable k(this, MachineRepresentation::kTagged, SmiConstant(0));
26 Label non_array(this), slow(this, &k), array_changes(this, &k); 32 Label non_array(this), slow(this, &k), array_changes(this, &k);
27 33
28 // TODO(danno): Seriously? Do we really need to throw the exact error 34 // TODO(danno): Seriously? Do we really need to throw the exact error
29 // message on null and undefined so that the webkit tests pass? 35 // message on null and undefined so that the webkit tests pass?
30 Label throw_null_undefined_exception(this, Label::kDeferred); 36 Label throw_null_undefined_exception(this, Label::kDeferred);
31 GotoIf(WordEqual(receiver, NullConstant()), 37 GotoIf(WordEqual(receiver, NullConstant()),
32 &throw_null_undefined_exception); 38 &throw_null_undefined_exception);
33 GotoIf(WordEqual(receiver, UndefinedConstant()), 39 GotoIf(WordEqual(receiver, UndefinedConstant()),
34 &throw_null_undefined_exception); 40 &throw_null_undefined_exception);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 // 6. If thisArg was supplied, let T be thisArg; else let T be undefined. 90 // 6. If thisArg was supplied, let T be thisArg; else let T be undefined.
85 // [Already done by the arguments adapter] 91 // [Already done by the arguments adapter]
86 92
87 HandleFastElements(context, this_arg, o, len, callbackfn, processor, a, k, 93 HandleFastElements(context, this_arg, o, len, callbackfn, processor, a, k,
88 &slow); 94 &slow);
89 95
90 // 7. Let k be 0. 96 // 7. Let k be 0.
91 // Already done above in initialization of the Variable k 97 // Already done above in initialization of the Variable k
92 98
93 Bind(&slow); 99 Bind(&slow);
100
101 Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
102 MachineType::TaggedPointer());
103 TailCallStub(
104 slow_case_continuation, context, target, new_target,
105 Int32Constant(IteratingArrayBuiltinLoopContinuationDescriptor::kArity),
106 receiver, callbackfn, this_arg, a, o, k.value(), len);
107 }
108
109 void GenerateIteratingArrayBuiltinLoopContinuation(
110 const CallResultProcessor& processor) {
111 Node* callbackfn =
112 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kCallback);
113 Node* this_arg =
114 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kThisArg);
115 Node* a =
116 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kArray);
117 Node* o =
118 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kObject);
119 Node* initial_k =
120 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kInitialK);
121 Node* len =
122 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kLength);
123 Node* context =
124 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kContext);
125
126 // 8. Repeat, while k < len
127 Variable k(this, MachineRepresentation::kTagged, initial_k);
128 Label loop(this, &k);
129 Label after_loop(this);
130 Goto(&loop);
131 Bind(&loop);
94 { 132 {
95 // 8. Repeat, while k < len 133 GotoUnlessNumberLessThan(k.value(), len, &after_loop);
96 Label loop(this, &k); 134
97 Label after_loop(this); 135 Label done_element(this);
136 // a. Let Pk be ToString(k).
137 Node* p_k = ToString(context, k.value());
138
139 // b. Let kPresent be HasProperty(O, Pk).
140 // c. ReturnIfAbrupt(kPresent).
141 Node* k_present = HasProperty(o, p_k, context);
142
143 // d. If kPresent is true, then
144 GotoIf(WordNotEqual(k_present, TrueConstant()), &done_element);
145
146 // i. Let kValue be Get(O, Pk).
147 // ii. ReturnIfAbrupt(kValue).
148 Node* k_value = GetProperty(context, o, k.value());
149
150 // iii. Let funcResult be Call(callbackfn, T, «kValue, k, O»).
151 // iv. ReturnIfAbrupt(funcResult).
152 Node* result = CallJS(CodeFactory::Call(isolate()), context, callbackfn,
153 this_arg, k_value, k.value(), o);
154
155 processor(a, p_k, result);
156 Goto(&done_element);
157 Bind(&done_element);
158
159 // e. Increase k by 1.
160 k.Bind(NumberInc(k.value()));
98 Goto(&loop); 161 Goto(&loop);
99 Bind(&loop); 162 }
100 { 163 Bind(&after_loop);
101 GotoUnlessNumberLessThan(k.value(), len, &after_loop); 164 Return(a);
165 }
102 166
103 Label done_element(this); 167 void ForEachProcessor(Node* a, Node* p_k, Node* value) {}
104 // a. Let Pk be ToString(k).
105 Node* p_k = ToString(context, k.value());
106 168
107 // b. Let kPresent be HasProperty(O, Pk). 169 void SomeProcessor(Node* a, Node* p_k, Node* value) {
108 // c. ReturnIfAbrupt(kPresent). 170 Label false_continue(this), return_true(this);
109 Node* k_present = 171 BranchIfToBooleanIsTrue(value, &return_true, &false_continue);
110 CallStub(CodeFactory::HasProperty(isolate()), context, p_k, o); 172 Bind(&return_true);
173 Return(TrueConstant());
174 Bind(&false_continue);
175 }
111 176
112 // d. If kPresent is true, then 177 void EveryProcessor(Node* a, Node* p_k, Node* value) {
113 GotoIf(WordNotEqual(k_present, TrueConstant()), &done_element); 178 Label true_continue(this), return_false(this);
114 179 BranchIfToBooleanIsTrue(value, &true_continue, &return_false);
115 // i. Let kValue be Get(O, Pk). 180 Bind(&return_false);
116 // ii. ReturnIfAbrupt(kValue). 181 Return(FalseConstant());
117 Node* k_value = GetProperty(context, o, k.value()); 182 Bind(&true_continue);
118
119 // iii. Let funcResult be Call(callbackfn, T, «kValue, k, O»).
120 // iv. ReturnIfAbrupt(funcResult).
121 Node* result = CallJS(CodeFactory::Call(isolate()), context, callbackfn,
122 this_arg, k_value, k.value(), o);
123
124 processor(a, p_k, result);
125 Goto(&done_element);
126 Bind(&done_element);
127
128 // e. Increase k by 1.
129 k.Bind(NumberInc(k.value()));
130 Goto(&loop);
131 }
132 Bind(&after_loop);
133 Return(a);
134 }
135 } 183 }
136 184
137 private: 185 private:
138 Node* VisitAllFastElementsOneKind(Node* context, ElementsKind kind, 186 Node* VisitAllFastElementsOneKind(Node* context, ElementsKind kind,
139 Node* this_arg, Node* o, Node* len, 187 Node* this_arg, Node* o, Node* len,
140 Node* callbackfn, 188 Node* callbackfn,
141 const CallResultProcessor& processor, 189 const CallResultProcessor& processor,
142 Node* a, Label* array_changed, 190 Node* a, Label* array_changed,
143 ParameterMode mode) { 191 ParameterMode mode) {
144 Comment("begin VisitAllFastElementsOneKind"); 192 Comment("begin VisitAllFastElementsOneKind");
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 455
408 Bind(&runtime); 456 Bind(&runtime);
409 { 457 {
410 Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset, 458 Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
411 MachineType::TaggedPointer()); 459 MachineType::TaggedPointer());
412 TailCallStub(CodeFactory::ArrayPush(isolate()), context, target, new_target, 460 TailCallStub(CodeFactory::ArrayPush(isolate()), context, target, new_target,
413 argc); 461 argc);
414 } 462 }
415 } 463 }
416 464
417 TF_BUILTIN(ArrayForEach, ArrayBuiltinCodeStubAssembler) { 465 TF_BUILTIN(ArrayForEachLoopContinuation, ArrayBuiltinCodeStubAssembler) {
418 Node* receiver = Parameter(ForEachDescriptor::kReceiver); 466 GenerateIteratingArrayBuiltinLoopContinuation(
419 Node* callbackfn = Parameter(ForEachDescriptor::kCallback); 467 [this](Node* a, Node* p_k, Node* value) {
420 Node* this_arg = Parameter(ForEachDescriptor::kThisArg); 468 ForEachProcessor(a, p_k, value);
421 Node* context = Parameter(ForEachDescriptor::kContext); 469 });
422
423 GenerateArrayIteratingBuiltinBody(
424 "Array.prototype.forEach", receiver, callbackfn, this_arg, context,
425 [=](Node*, Node*) { return UndefinedConstant(); },
426 [](Node* a, Node* p_k, Node* value) {});
427 } 470 }
428 471
429 TF_BUILTIN(ArrayEvery, ArrayBuiltinCodeStubAssembler) { 472 TF_BUILTIN(ArrayForEach, ArrayBuiltinCodeStubAssembler) {
430 Node* receiver = Parameter(ForEachDescriptor::kReceiver); 473 GenerateIteratingArrayBuiltinBody(
431 Node* callbackfn = Parameter(ForEachDescriptor::kCallback); 474 "Array.prototype.forEach",
432 Node* this_arg = Parameter(ForEachDescriptor::kThisArg); 475 [=](Node*, Node*) { return UndefinedConstant(); },
433 Node* context = Parameter(ForEachDescriptor::kContext); 476 [this](Node* a, Node* p_k, Node* value) {
477 ForEachProcessor(a, p_k, value);
478 },
479 CodeFactory::ArrayForEachLoopContinuation(isolate()));
480 }
434 481
435 GenerateArrayIteratingBuiltinBody( 482 TF_BUILTIN(ArraySomeLoopContinuation, ArrayBuiltinCodeStubAssembler) {
436 "Array.prototype.every", receiver, callbackfn, this_arg, context, 483 GenerateIteratingArrayBuiltinLoopContinuation(
437 [=](Node*, Node*) { return TrueConstant(); }, 484 [this](Node* a, Node* p_k, Node* value) {
438 [=](Node* a, Node* p_k, Node* value) { 485 SomeProcessor(a, p_k, value);
439 Label true_continue(this), return_false(this);
440 BranchIfToBooleanIsTrue(value, &true_continue, &return_false);
441 Bind(&return_false);
442 Return(FalseConstant());
443 Bind(&true_continue);
444 }); 486 });
445 } 487 }
446 488
447 TF_BUILTIN(ArraySome, ArrayBuiltinCodeStubAssembler) { 489 TF_BUILTIN(ArraySome, ArrayBuiltinCodeStubAssembler) {
448 Node* receiver = Parameter(ForEachDescriptor::kReceiver); 490 GenerateIteratingArrayBuiltinBody(
449 Node* callbackfn = Parameter(ForEachDescriptor::kCallback); 491 "Array.prototype.some", [=](Node*, Node*) { return FalseConstant(); },
450 Node* this_arg = Parameter(ForEachDescriptor::kThisArg); 492 [this](Node* a, Node* p_k, Node* value) { SomeProcessor(a, p_k, value); },
451 Node* context = Parameter(ForEachDescriptor::kContext); 493 CodeFactory::ArraySomeLoopContinuation(isolate()));
494 }
452 495
453 GenerateArrayIteratingBuiltinBody( 496 TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinCodeStubAssembler) {
454 "Array.prototype.some", receiver, callbackfn, this_arg, context, 497 GenerateIteratingArrayBuiltinLoopContinuation(
455 [=](Node*, Node*) { return FalseConstant(); }, 498 [this](Node* a, Node* p_k, Node* value) {
456 [=](Node* a, Node* p_k, Node* value) { 499 EveryProcessor(a, p_k, value);
457 Label false_continue(this), return_true(this);
458 BranchIfToBooleanIsTrue(value, &return_true, &false_continue);
459 Bind(&return_true);
460 Return(TrueConstant());
461 Bind(&false_continue);
462 }); 500 });
463 } 501 }
464 502
503 TF_BUILTIN(ArrayEvery, ArrayBuiltinCodeStubAssembler) {
504 GenerateIteratingArrayBuiltinBody(
505 "Array.prototype.every", [=](Node*, Node*) { return TrueConstant(); },
506 [this](Node* a, Node* p_k, Node* value) {
507 EveryProcessor(a, p_k, value);
508 },
509 CodeFactory::ArrayEveryLoopContinuation(isolate()));
510 }
511
465 TF_BUILTIN(ArrayIsArray, CodeStubAssembler) { 512 TF_BUILTIN(ArrayIsArray, CodeStubAssembler) {
466 Node* object = Parameter(1); 513 Node* object = Parameter(1);
467 Node* context = Parameter(4); 514 Node* context = Parameter(4);
468 515
469 Label call_runtime(this), return_true(this), return_false(this); 516 Label call_runtime(this), return_true(this), return_false(this);
470 517
471 GotoIf(TaggedIsSmi(object), &return_false); 518 GotoIf(TaggedIsSmi(object), &return_false);
472 Node* instance_type = LoadInstanceType(object); 519 Node* instance_type = LoadInstanceType(object);
473 520
474 GotoIf(Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE)), 521 GotoIf(Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE)),
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after
1509 { 1556 {
1510 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); 1557 Node* message = SmiConstant(MessageTemplate::kDetachedOperation);
1511 CallRuntime(Runtime::kThrowTypeError, context, message, 1558 CallRuntime(Runtime::kThrowTypeError, context, message,
1512 HeapConstant(operation)); 1559 HeapConstant(operation));
1513 Unreachable(); 1560 Unreachable();
1514 } 1561 }
1515 } 1562 }
1516 1563
1517 } // namespace internal 1564 } // namespace internal
1518 } // namespace v8 1565 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/code-factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698