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

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

Issue 2796343002: [builtins] Implement %TypedArray%.prototype.{reduce,reduceRight} in the CSA (Closed)
Patch Set: Created 3 years, 8 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/bootstrapper.cc ('k') | src/builtins/builtins-definitions.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 k_(this, MachineRepresentation::kTagged, SmiConstant(0)), 16 k_(this, MachineRepresentation::kTagged),
17 a_(this, MachineRepresentation::kTagged, SmiConstant(0)), 17 a_(this, MachineRepresentation::kTagged),
Tobias Tebbi 2017/04/05 11:53:05 I removed these defaults because we should never r
18 to_(this, MachineRepresentation::kTagged, SmiConstant(0)) {} 18 to_(this, MachineRepresentation::kTagged, SmiConstant(0)) {}
19 19
20 typedef std::function<Node*(ArrayBuiltinCodeStubAssembler* masm)> 20 typedef std::function<Node*(ArrayBuiltinCodeStubAssembler* masm)>
21 BuiltinResultGenerator; 21 BuiltinResultGenerator;
22 22
23 typedef std::function<void(ArrayBuiltinCodeStubAssembler* masm)> 23 typedef std::function<void(ArrayBuiltinCodeStubAssembler* masm)>
24 BuiltinResultIndexInitializer; 24 BuiltinResultIndexInitializer;
25 25
26 typedef std::function<Node*(ArrayBuiltinCodeStubAssembler* masm, 26 typedef std::function<Node*(ArrayBuiltinCodeStubAssembler* masm,
27 Node* k_value, Node* k)> 27 Node* k_value, Node* k)>
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 Node* a() { return a_.value(); } 179 Node* a() { return a_.value(); }
180 180
181 void InitIteratingArrayBuiltinBody(Node* context, Node* receiver, 181 void InitIteratingArrayBuiltinBody(Node* context, Node* receiver,
182 Node* callbackfn, Node* this_arg, 182 Node* callbackfn, Node* this_arg,
183 Node* new_target) { 183 Node* new_target) {
184 context_ = context; 184 context_ = context;
185 receiver_ = receiver; 185 receiver_ = receiver;
186 new_target_ = new_target; 186 new_target_ = new_target;
187 callbackfn_ = callbackfn; 187 callbackfn_ = callbackfn;
188 this_arg_ = this_arg; 188 this_arg_ = this_arg;
189
190 k_.Bind(SmiConstant(0));
191 a_.Bind(UndefinedConstant());
Tobias Tebbi 2017/04/05 11:53:05 Same here.
192 } 189 }
193 190
194 void GenerateIteratingArrayBuiltinBody( 191 void GenerateIteratingArrayBuiltinBody(
195 const char* name, const BuiltinResultGenerator& generator, 192 const char* name, const BuiltinResultGenerator& generator,
196 const CallResultProcessor& processor, const PostLoopAction& action, 193 const CallResultProcessor& processor, const PostLoopAction& action,
197 const Callable& slow_case_continuation, 194 const Callable& slow_case_continuation,
198 ForEachDirection direction = ForEachDirection::kForward) { 195 ForEachDirection direction = ForEachDirection::kForward) {
199 Label non_array(this), slow(this, {&k_, &a_, &to_}), 196 Label non_array(this), slow(this, {&k_, &a_, &to_}),
200 array_changes(this, {&k_, &a_, &to_}); 197 array_changes(this, {&k_, &a_, &to_});
201 198
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 251
255 Bind(&done); 252 Bind(&done);
256 253
257 // 6. If thisArg was supplied, let T be thisArg; else let T be undefined. 254 // 6. If thisArg was supplied, let T be thisArg; else let T be undefined.
258 // [Already done by the arguments adapter] 255 // [Already done by the arguments adapter]
259 256
260 if (direction == ForEachDirection::kForward) { 257 if (direction == ForEachDirection::kForward) {
261 // 7. Let k be 0. 258 // 7. Let k be 0.
262 k_.Bind(SmiConstant(0)); 259 k_.Bind(SmiConstant(0));
263 } else { 260 } else {
264 k_.Bind(len()); 261 k_.Bind(NumberDec(len()));
265 k_.Bind(NumberDec(k_.value()));
266 } 262 }
267 263
268 a_.Bind(generator(this)); 264 a_.Bind(generator(this));
269 265
270 HandleFastElements(processor, action, &slow, direction); 266 HandleFastElements(processor, action, &slow, direction);
271 267
272 Bind(&slow); 268 Bind(&slow);
273 269
274 Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset, 270 Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
275 MachineType::TaggedPointer()); 271 MachineType::TaggedPointer());
(...skipping 14 matching lines...) Expand all
290 callbackfn_ = callbackfn; 286 callbackfn_ = callbackfn;
291 a_.Bind(a); 287 a_.Bind(a);
292 k_.Bind(initial_k); 288 k_.Bind(initial_k);
293 o_ = o; 289 o_ = o;
294 len_ = len; 290 len_ = len;
295 to_.Bind(to); 291 to_.Bind(to);
296 } 292 }
297 293
298 void GenerateIteratingTypedArrayBuiltinBody( 294 void GenerateIteratingTypedArrayBuiltinBody(
299 const char* name, const BuiltinResultGenerator& generator, 295 const char* name, const BuiltinResultGenerator& generator,
300 const CallResultProcessor& processor, const PostLoopAction& action) { 296 const CallResultProcessor& processor, const PostLoopAction& action,
297 ForEachDirection direction = ForEachDirection::kForward) {
301 Node* name_string = 298 Node* name_string =
302 HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(name)); 299 HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(name));
303 300
304 // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray 301 // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray
305 302
306 Label throw_not_typed_array(this, Label::kDeferred), 303 Label throw_not_typed_array(this, Label::kDeferred),
307 throw_detached(this, Label::kDeferred); 304 throw_detached(this, Label::kDeferred);
308 305
309 GotoIf(TaggedIsSmi(receiver_), &throw_not_typed_array); 306 GotoIf(TaggedIsSmi(receiver_), &throw_not_typed_array);
310 GotoIfNot(HasInstanceType(receiver_, JS_TYPED_ARRAY_TYPE), 307 GotoIfNot(HasInstanceType(receiver_, JS_TYPED_ARRAY_TYPE),
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 std::vector<Label> labels; 354 std::vector<Label> labels;
358 for (size_t i = 0; i < instance_types.size(); ++i) { 355 for (size_t i = 0; i < instance_types.size(); ++i) {
359 labels.push_back(Label(this)); 356 labels.push_back(Label(this));
360 } 357 }
361 std::vector<Label*> label_ptrs; 358 std::vector<Label*> label_ptrs;
362 for (Label& label : labels) { 359 for (Label& label : labels) {
363 label_ptrs.push_back(&label); 360 label_ptrs.push_back(&label);
364 } 361 }
365 362
366 Bind(&distinguish_types); 363 Bind(&distinguish_types);
364
365 if (direction == ForEachDirection::kForward) {
366 k_.Bind(SmiConstant(0));
367 } else {
368 k_.Bind(NumberDec(len()));
369 }
367 a_.Bind(generator(this)); 370 a_.Bind(generator(this));
368 Node* elements_type = LoadInstanceType(LoadElements(o_)); 371 Node* elements_type = LoadInstanceType(LoadElements(o_));
369 Switch(elements_type, &unexpected_instance_type, instance_types.data(), 372 Switch(elements_type, &unexpected_instance_type, instance_types.data(),
370 label_ptrs.data(), labels.size()); 373 label_ptrs.data(), labels.size());
371 374
372 for (size_t i = 0; i < labels.size(); ++i) { 375 for (size_t i = 0; i < labels.size(); ++i) {
373 Bind(&labels[i]); 376 Bind(&labels[i]);
374 Label done(this); 377 Label done(this);
375 // TODO(tebbi): Silently cancelling the loop on buffer detachment is a 378 // TODO(tebbi): Silently cancelling the loop on buffer detachment is a
376 // spec violation. Should go to &detached and throw a TypeError instead. 379 // spec violation. Should go to &detached and throw a TypeError instead.
377 VisitAllTypedArrayElements( 380 VisitAllTypedArrayElements(
378 ElementsKindForInstanceType( 381 ElementsKindForInstanceType(
379 static_cast<InstanceType>(instance_types[i])), 382 static_cast<InstanceType>(instance_types[i])),
380 array_buffer, processor, &done); 383 array_buffer, processor, &done, direction);
381 Goto(&done); 384 Goto(&done);
382 action(this);
383 // No exception, return success 385 // No exception, return success
384 Bind(&done); 386 Bind(&done);
387 action(this);
385 Return(a_.value()); 388 Return(a_.value());
386 } 389 }
387 } 390 }
388 391
389 void GenerateIteratingArrayBuiltinLoopContinuation( 392 void GenerateIteratingArrayBuiltinLoopContinuation(
390 const CallResultProcessor& processor, const PostLoopAction& action, 393 const CallResultProcessor& processor, const PostLoopAction& action,
391 ForEachDirection direction = ForEachDirection::kForward) { 394 ForEachDirection direction = ForEachDirection::kForward) {
392 Label loop(this, {&k_, &a_, &to_}); 395 Label loop(this, {&k_, &a_, &to_});
393 Label after_loop(this); 396 Label after_loop(this);
394 Goto(&loop); 397 Goto(&loop);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 #undef INSTANCE_TYPE_TO_ELEMENTS_KIND 454 #undef INSTANCE_TYPE_TO_ELEMENTS_KIND
452 455
453 default: 456 default:
454 UNREACHABLE(); 457 UNREACHABLE();
455 return static_cast<ElementsKind>(-1); 458 return static_cast<ElementsKind>(-1);
456 } 459 }
457 } 460 }
458 461
459 void VisitAllTypedArrayElements(ElementsKind kind, Node* array_buffer, 462 void VisitAllTypedArrayElements(ElementsKind kind, Node* array_buffer,
460 const CallResultProcessor& processor, 463 const CallResultProcessor& processor,
461 Label* detached) { 464 Label* detached, ForEachDirection direction) {
462 VariableList list({&a_, &k_, &to_}, zone()); 465 VariableList list({&a_, &k_, &to_}, zone());
463 466
464 FastLoopBody body = [&](Node* index) { 467 FastLoopBody body = [&](Node* index) {
465 GotoIf(IsDetachedBuffer(array_buffer), detached); 468 GotoIf(IsDetachedBuffer(array_buffer), detached);
466 Node* elements = LoadElements(o_); 469 Node* elements = LoadElements(o_);
467 Node* base_ptr = 470 Node* base_ptr =
468 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset); 471 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset);
469 Node* external_ptr = 472 Node* external_ptr =
470 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset, 473 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset,
471 MachineType::Pointer()); 474 MachineType::Pointer());
472 Node* data_ptr = IntPtrAdd(BitcastTaggedToWord(base_ptr), external_ptr); 475 Node* data_ptr = IntPtrAdd(BitcastTaggedToWord(base_ptr), external_ptr);
473 Node* value = LoadFixedTypedArrayElementAsTagged(data_ptr, index, kind, 476 Node* value = LoadFixedTypedArrayElementAsTagged(data_ptr, index, kind,
474 SMI_PARAMETERS); 477 SMI_PARAMETERS);
475 k_.Bind(index); 478 k_.Bind(index);
476 a_.Bind(processor(this, value, index)); 479 a_.Bind(processor(this, value, index));
477 }; 480 };
478 BuildFastLoop(list, SmiConstant(0), len_, body, 1, 481 Node* start = SmiConstant(0);
479 ParameterMode::SMI_PARAMETERS, IndexAdvanceMode::kPost); 482 Node* end = len_;
483 IndexAdvanceMode advance_mode = IndexAdvanceMode::kPost;
484 int incr = 1;
485 if (direction == ForEachDirection::kReverse) {
486 std::swap(start, end);
487 advance_mode = IndexAdvanceMode::kPre;
488 incr = -1;
489 }
490 BuildFastLoop(list, start, end, body, incr, ParameterMode::SMI_PARAMETERS,
491 advance_mode);
480 } 492 }
481 493
482 void VisitAllFastElementsOneKind(ElementsKind kind, 494 void VisitAllFastElementsOneKind(ElementsKind kind,
483 const CallResultProcessor& processor, 495 const CallResultProcessor& processor,
484 Label* array_changed, ParameterMode mode, 496 Label* array_changed, ParameterMode mode,
485 ForEachDirection direction) { 497 ForEachDirection direction) {
486 Comment("begin VisitAllFastElementsOneKind"); 498 Comment("begin VisitAllFastElementsOneKind");
487 Variable original_map(this, MachineRepresentation::kTagged); 499 Variable original_map(this, MachineRepresentation::kTagged);
488 original_map.Bind(LoadMap(o())); 500 original_map.Bind(LoadMap(o()));
489 VariableList list({&original_map, &a_, &k_, &to_}, zone()); 501 VariableList list({&original_map, &a_, &k_, &to_}, zone());
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 new_target); 953 new_target);
942 954
943 GenerateIteratingArrayBuiltinBody( 955 GenerateIteratingArrayBuiltinBody(
944 "Array.prototype.reduce", 956 "Array.prototype.reduce",
945 &ArrayBuiltinCodeStubAssembler::ReduceResultGenerator, 957 &ArrayBuiltinCodeStubAssembler::ReduceResultGenerator,
946 &ArrayBuiltinCodeStubAssembler::ReduceProcessor, 958 &ArrayBuiltinCodeStubAssembler::ReduceProcessor,
947 &ArrayBuiltinCodeStubAssembler::ReducePostLoopAction, 959 &ArrayBuiltinCodeStubAssembler::ReducePostLoopAction,
948 CodeFactory::ArrayReduceLoopContinuation(isolate())); 960 CodeFactory::ArrayReduceLoopContinuation(isolate()));
949 } 961 }
950 962
963 TF_BUILTIN(TypedArrayPrototypeReduce, ArrayBuiltinCodeStubAssembler) {
964 Node* context = Parameter(Descriptor::kContext);
965 Node* receiver = Parameter(Descriptor::kReceiver);
966 Node* callbackfn = Parameter(Descriptor::kCallbackFn);
967 Node* initial_value = Parameter(Descriptor::kInitialValue);
968 Node* new_target = Parameter(Descriptor::kNewTarget);
969
970 InitIteratingArrayBuiltinBody(context, receiver, callbackfn, initial_value,
971 new_target);
972
973 GenerateIteratingTypedArrayBuiltinBody(
974 "%TypedArray%.prototype.reduce",
975 &ArrayBuiltinCodeStubAssembler::ReduceResultGenerator,
976 &ArrayBuiltinCodeStubAssembler::ReduceProcessor,
977 &ArrayBuiltinCodeStubAssembler::ReducePostLoopAction);
978 }
979
951 TF_BUILTIN(ArrayReduceRightLoopContinuation, ArrayBuiltinCodeStubAssembler) { 980 TF_BUILTIN(ArrayReduceRightLoopContinuation, ArrayBuiltinCodeStubAssembler) {
952 Node* context = Parameter(Descriptor::kContext); 981 Node* context = Parameter(Descriptor::kContext);
953 Node* receiver = Parameter(Descriptor::kReceiver); 982 Node* receiver = Parameter(Descriptor::kReceiver);
954 Node* callbackfn = Parameter(Descriptor::kCallbackFn); 983 Node* callbackfn = Parameter(Descriptor::kCallbackFn);
955 Node* this_arg = Parameter(Descriptor::kThisArg); 984 Node* this_arg = Parameter(Descriptor::kThisArg);
956 Node* accumulator = Parameter(Descriptor::kAccumulator); 985 Node* accumulator = Parameter(Descriptor::kAccumulator);
957 Node* object = Parameter(Descriptor::kObject); 986 Node* object = Parameter(Descriptor::kObject);
958 Node* initial_k = Parameter(Descriptor::kInitialK); 987 Node* initial_k = Parameter(Descriptor::kInitialK);
959 Node* len = Parameter(Descriptor::kLength); 988 Node* len = Parameter(Descriptor::kLength);
960 Node* to = Parameter(Descriptor::kTo); 989 Node* to = Parameter(Descriptor::kTo);
(...skipping 20 matching lines...) Expand all
981 1010
982 GenerateIteratingArrayBuiltinBody( 1011 GenerateIteratingArrayBuiltinBody(
983 "Array.prototype.reduceRight", 1012 "Array.prototype.reduceRight",
984 &ArrayBuiltinCodeStubAssembler::ReduceResultGenerator, 1013 &ArrayBuiltinCodeStubAssembler::ReduceResultGenerator,
985 &ArrayBuiltinCodeStubAssembler::ReduceProcessor, 1014 &ArrayBuiltinCodeStubAssembler::ReduceProcessor,
986 &ArrayBuiltinCodeStubAssembler::ReducePostLoopAction, 1015 &ArrayBuiltinCodeStubAssembler::ReducePostLoopAction,
987 CodeFactory::ArrayReduceRightLoopContinuation(isolate()), 1016 CodeFactory::ArrayReduceRightLoopContinuation(isolate()),
988 ForEachDirection::kReverse); 1017 ForEachDirection::kReverse);
989 } 1018 }
990 1019
1020 TF_BUILTIN(TypedArrayPrototypeReduceRight, ArrayBuiltinCodeStubAssembler) {
1021 Node* context = Parameter(Descriptor::kContext);
1022 Node* receiver = Parameter(Descriptor::kReceiver);
1023 Node* callbackfn = Parameter(Descriptor::kCallbackFn);
1024 Node* initial_value = Parameter(Descriptor::kInitialValue);
1025 Node* new_target = Parameter(Descriptor::kNewTarget);
1026
1027 InitIteratingArrayBuiltinBody(context, receiver, callbackfn, initial_value,
1028 new_target);
1029
1030 GenerateIteratingTypedArrayBuiltinBody(
1031 "%TypedArray%.prototype.reduceRight",
1032 &ArrayBuiltinCodeStubAssembler::ReduceResultGenerator,
1033 &ArrayBuiltinCodeStubAssembler::ReduceProcessor,
1034 &ArrayBuiltinCodeStubAssembler::ReducePostLoopAction,
1035 ForEachDirection::kReverse);
1036 }
1037
991 TF_BUILTIN(ArrayFilterLoopContinuation, ArrayBuiltinCodeStubAssembler) { 1038 TF_BUILTIN(ArrayFilterLoopContinuation, ArrayBuiltinCodeStubAssembler) {
992 Node* context = Parameter(Descriptor::kContext); 1039 Node* context = Parameter(Descriptor::kContext);
993 Node* receiver = Parameter(Descriptor::kReceiver); 1040 Node* receiver = Parameter(Descriptor::kReceiver);
994 Node* callbackfn = Parameter(Descriptor::kCallbackFn); 1041 Node* callbackfn = Parameter(Descriptor::kCallbackFn);
995 Node* this_arg = Parameter(Descriptor::kThisArg); 1042 Node* this_arg = Parameter(Descriptor::kThisArg);
996 Node* array = Parameter(Descriptor::kArray); 1043 Node* array = Parameter(Descriptor::kArray);
997 Node* object = Parameter(Descriptor::kObject); 1044 Node* object = Parameter(Descriptor::kObject);
998 Node* initial_k = Parameter(Descriptor::kInitialK); 1045 Node* initial_k = Parameter(Descriptor::kInitialK);
999 Node* len = Parameter(Descriptor::kLength); 1046 Node* len = Parameter(Descriptor::kLength);
1000 Node* to = Parameter(Descriptor::kTo); 1047 Node* to = Parameter(Descriptor::kTo);
(...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2117 { 2164 {
2118 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); 2165 Node* message = SmiConstant(MessageTemplate::kDetachedOperation);
2119 CallRuntime(Runtime::kThrowTypeError, context, message, 2166 CallRuntime(Runtime::kThrowTypeError, context, message,
2120 HeapConstant(operation)); 2167 HeapConstant(operation));
2121 Unreachable(); 2168 Unreachable();
2122 } 2169 }
2123 } 2170 }
2124 2171
2125 } // namespace internal 2172 } // namespace internal
2126 } // namespace v8 2173 } // namespace v8
OLDNEW
« no previous file with comments | « src/bootstrapper.cc ('k') | src/builtins/builtins-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698