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

Side by Side Diff: src/code-stub-assembler.cc

Issue 2738413002: [regexp] Port RegExpExecStub to CSA (mostly) (Closed)
Patch Set: Fix arm64 cobbled code register 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
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 #include "src/code-stub-assembler.h" 4 #include "src/code-stub-assembler.h"
5 #include "src/code-factory.h" 5 #include "src/code-factory.h"
6 #include "src/frames-inl.h" 6 #include "src/frames-inl.h"
7 #include "src/frames.h" 7 #include "src/frames.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 2880 matching lines...) Expand 10 before | Expand all | Expand 10 after
2891 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); 2891 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE);
2892 return Int32LessThanOrEqual(instance_type, 2892 return Int32LessThanOrEqual(instance_type,
2893 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)); 2893 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE));
2894 } 2894 }
2895 2895
2896 Node* CodeStubAssembler::IsStringInstanceType(Node* instance_type) { 2896 Node* CodeStubAssembler::IsStringInstanceType(Node* instance_type) {
2897 STATIC_ASSERT(INTERNALIZED_STRING_TYPE == FIRST_TYPE); 2897 STATIC_ASSERT(INTERNALIZED_STRING_TYPE == FIRST_TYPE);
2898 return Int32LessThan(instance_type, Int32Constant(FIRST_NONSTRING_TYPE)); 2898 return Int32LessThan(instance_type, Int32Constant(FIRST_NONSTRING_TYPE));
2899 } 2899 }
2900 2900
2901 Node* CodeStubAssembler::IsOneByteStringInstanceType(Node* instance_type) {
2902 CSA_ASSERT(this, IsStringInstanceType(instance_type));
2903 return Word32Equal(
2904 Word32And(instance_type, Int32Constant(kStringEncodingMask)),
2905 Int32Constant(kOneByteStringTag));
2906 }
2907
2908 Node* CodeStubAssembler::IsSequentialStringInstanceType(Node* instance_type) {
2909 CSA_ASSERT(this, IsStringInstanceType(instance_type));
2910 return Word32Equal(
2911 Word32And(instance_type, Int32Constant(kStringRepresentationMask)),
2912 Int32Constant(kSeqStringTag));
2913 }
2914
2901 Node* CodeStubAssembler::IsJSReceiverInstanceType(Node* instance_type) { 2915 Node* CodeStubAssembler::IsJSReceiverInstanceType(Node* instance_type) {
2902 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); 2916 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
2903 return Int32GreaterThanOrEqual(instance_type, 2917 return Int32GreaterThanOrEqual(instance_type,
2904 Int32Constant(FIRST_JS_RECEIVER_TYPE)); 2918 Int32Constant(FIRST_JS_RECEIVER_TYPE));
2905 } 2919 }
2906 2920
2907 Node* CodeStubAssembler::IsJSReceiver(Node* object) { 2921 Node* CodeStubAssembler::IsJSReceiver(Node* object) {
2908 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); 2922 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
2909 return IsJSReceiverInstanceType(LoadInstanceType(object)); 2923 return IsJSReceiverInstanceType(LoadInstanceType(object));
2910 } 2924 }
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
3252 // given character range using CopyStringCharacters. 3266 // given character range using CopyStringCharacters.
3253 // |from_string| must be a sequential string. |from_index| and 3267 // |from_string| must be a sequential string. |from_index| and
3254 // |character_count| must be Smis s.t. 3268 // |character_count| must be Smis s.t.
3255 // 0 <= |from_index| <= |from_index| + |character_count| < from_string.length. 3269 // 0 <= |from_index| <= |from_index| + |character_count| < from_string.length.
3256 Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context, 3270 Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context,
3257 Node* from, Node* from_instance_type, 3271 Node* from, Node* from_instance_type,
3258 Node* from_index, Node* character_count) { 3272 Node* from_index, Node* character_count) {
3259 typedef CodeStubAssembler::Label Label; 3273 typedef CodeStubAssembler::Label Label;
3260 typedef CodeStubAssembler::Variable Variable; 3274 typedef CodeStubAssembler::Variable Variable;
3261 3275
3262 Label end(a), two_byte_sequential(a); 3276 Label end(a), one_byte_sequential(a), two_byte_sequential(a);
3263 Variable var_result(a, MachineRepresentation::kTagged); 3277 Variable var_result(a, MachineRepresentation::kTagged);
3264 3278
3265 Node* const smi_zero = a->SmiConstant(Smi::kZero); 3279 Node* const smi_zero = a->SmiConstant(Smi::kZero);
3266 3280
3267 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0); 3281 a->Branch(a->IsOneByteStringInstanceType(from_instance_type),
jgruber 2017/03/13 12:27:37 Drive-by simplification.
3268 a->GotoIf(a->Word32Equal(a->Word32And(from_instance_type, 3282 &one_byte_sequential, &two_byte_sequential);
3269 a->Int32Constant(kStringEncodingMask)),
3270 a->Int32Constant(0)),
3271 &two_byte_sequential);
3272 3283
3273 // The subject string is a sequential one-byte string. 3284 // The subject string is a sequential one-byte string.
3285 a->Bind(&one_byte_sequential);
3274 { 3286 {
3275 Node* result = 3287 Node* result =
3276 a->AllocateSeqOneByteString(context, a->SmiToWord(character_count)); 3288 a->AllocateSeqOneByteString(context, a->SmiToWord(character_count));
3277 a->CopyStringCharacters(from, result, from_index, smi_zero, character_count, 3289 a->CopyStringCharacters(from, result, from_index, smi_zero, character_count,
3278 String::ONE_BYTE_ENCODING, 3290 String::ONE_BYTE_ENCODING,
3279 String::ONE_BYTE_ENCODING, 3291 String::ONE_BYTE_ENCODING,
3280 CodeStubAssembler::SMI_PARAMETERS); 3292 CodeStubAssembler::SMI_PARAMETERS);
3281 var_result.Bind(result); 3293 var_result.Bind(result);
3282 3294
3283 a->Goto(&end); 3295 a->Goto(&end);
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
3548 Node* const instance_type) { 3560 Node* const instance_type) {
3549 CSA_ASSERT(a, a->IsStringInstanceType(instance_type)); 3561 CSA_ASSERT(a, a->IsStringInstanceType(instance_type));
3550 STATIC_ASSERT(kShortExternalStringTag != 0); 3562 STATIC_ASSERT(kShortExternalStringTag != 0);
3551 return a->Word32NotEqual( 3563 return a->Word32NotEqual(
3552 a->Word32And(instance_type, a->Int32Constant(kShortExternalStringMask)), 3564 a->Word32And(instance_type, a->Int32Constant(kShortExternalStringMask)),
3553 a->Int32Constant(0)); 3565 a->Int32Constant(0));
3554 } 3566 }
3555 3567
3556 } // namespace 3568 } // namespace
3557 3569
3570 void CodeStubAssembler::TryUnpackString(Variable* var_string,
jgruber 2017/03/13 12:27:37 String unpacking is getting messy, planning on ref
3571 Variable* var_offset,
3572 Variable* var_instance_type,
3573 Label* if_bailout) {
3574 DCHECK_EQ(var_string->rep(), MachineType::PointerRepresentation());
3575 DCHECK_EQ(var_offset->rep(), MachineType::PointerRepresentation());
3576 DCHECK_EQ(var_instance_type->rep(), MachineRepresentation::kWord32);
3577 CSA_ASSERT(this, IsString(var_string->value()));
3578
3579 Label out(this);
3580
3581 VariableList vars({var_string, var_offset, var_instance_type}, zone());
3582 Label dispatch(this, vars);
3583 Label if_isdirect(this);
3584 Label if_iscons(this, Label::kDeferred);
3585 Label if_isexternal(this, Label::kDeferred);
3586 Label if_issliced(this, Label::kDeferred);
3587 Label if_isthin(this, Label::kDeferred);
3588
3589 Goto(&dispatch);
3590
3591 // Dispatch based on string representation.
3592 Bind(&dispatch);
3593 {
3594 int32_t values[] = {
3595 kSeqStringTag, kConsStringTag, kExternalStringTag,
3596 kSlicedStringTag, kThinStringTag,
3597 };
3598 Label* labels[] = {
3599 &if_isdirect, &if_iscons, &if_isexternal, &if_issliced, &if_isthin,
3600 };
3601 STATIC_ASSERT(arraysize(values) == arraysize(labels));
3602
3603 Node* const representation = Word32And(
3604 var_instance_type->value(), Int32Constant(kStringRepresentationMask));
3605 Switch(representation, if_bailout, values, labels, arraysize(values));
3606 }
3607
3608 // Cons string. Check whether it is flat, then fetch first part.
3609 // Flat cons strings have an empty second part.
3610 Bind(&if_iscons);
3611 {
3612 Node* const string = var_string->value();
3613 GotoIfNot(IsEmptyString(LoadObjectField(string, ConsString::kSecondOffset)),
3614 if_bailout);
3615
3616 Node* const lhs = LoadObjectField(string, ConsString::kFirstOffset);
3617 var_string->Bind(BitcastTaggedToWord(lhs));
3618 var_instance_type->Bind(LoadInstanceType(lhs));
3619
3620 Goto(&dispatch);
3621 }
3622
3623 // Sliced string. Fetch parent and correct start index by offset.
3624 Bind(&if_issliced);
3625 {
3626 Node* const string = var_string->value();
3627 Node* const sliced_offset =
3628 LoadObjectField(string, SlicedString::kOffsetOffset);
3629 var_offset->Bind(IntPtrAdd(var_offset->value(), SmiUntag(sliced_offset)));
3630
3631 Node* const parent = LoadObjectField(string, SlicedString::kParentOffset);
3632 var_string->Bind(BitcastTaggedToWord(parent));
3633 var_instance_type->Bind(LoadInstanceType(parent));
3634
3635 Goto(&dispatch);
3636 }
3637
3638 // Thin string. Fetch the actual string.
3639 Bind(&if_isthin);
3640 {
3641 Node* const string = var_string->value();
3642 Node* const actual_string =
3643 LoadObjectField(string, ThinString::kActualOffset);
3644 Node* const actual_instance_type = LoadInstanceType(actual_string);
3645 CSA_ASSERT(this, IsSequentialStringInstanceType(actual_instance_type));
3646
3647 var_string->Bind(BitcastTaggedToWord(actual_string));
3648 var_instance_type->Bind(actual_instance_type);
3649
3650 Goto(&if_isdirect);
3651 }
3652
3653 // External string.
3654 Bind(&if_isexternal);
3655 {
3656 Node* const string = var_string->value();
3657 Node* const faked_seq_string =
3658 TryDerefExternalString(string, var_instance_type->value(), if_bailout);
3659
3660 STATIC_ASSERT(kSeqStringTag == 0x0);
3661 Node* const faked_seq_instance_type = Word32Xor(
3662 var_instance_type->value(), Int32Constant(kExternalStringTag));
3663 CSA_ASSERT(this, IsSequentialStringInstanceType(faked_seq_instance_type));
3664
3665 var_string->Bind(faked_seq_string);
3666 var_instance_type->Bind(faked_seq_instance_type);
3667
3668 Goto(&if_isdirect);
3669 }
3670
3671 Bind(&if_isdirect);
3672 }
3673
3558 Node* CodeStubAssembler::TryDerefExternalString(Node* const string, 3674 Node* CodeStubAssembler::TryDerefExternalString(Node* const string,
3559 Node* const instance_type, 3675 Node* const instance_type,
3560 Label* if_bailout) { 3676 Label* if_bailout) {
3561 Label out(this); 3677 Label out(this);
3562 3678
3563 USE(IsExternalStringInstanceType); 3679 USE(IsExternalStringInstanceType);
3564 CSA_ASSERT(this, IsExternalStringInstanceType(this, instance_type)); 3680 CSA_ASSERT(this, IsExternalStringInstanceType(this, instance_type));
3565 GotoIf(IsShortExternalStringInstanceType(this, instance_type), if_bailout); 3681 GotoIf(IsShortExternalStringInstanceType(this, instance_type), if_bailout);
3566 3682
3567 // Move the pointer so that offset-wise, it looks like a sequential string. 3683 // Move the pointer so that offset-wise, it looks like a sequential string.
(...skipping 2018 matching lines...) Expand 10 before | Expand all | Expand 10 after
5586 // This method is used for binary op and compare feedback. These 5702 // This method is used for binary op and compare feedback. These
5587 // vector nodes are initialized with a smi 0, so we can simply OR 5703 // vector nodes are initialized with a smi 0, so we can simply OR
5588 // our new feedback in place. 5704 // our new feedback in place.
5589 Node* previous_feedback = LoadFixedArrayElement(feedback_vector, slot_id); 5705 Node* previous_feedback = LoadFixedArrayElement(feedback_vector, slot_id);
5590 Node* combined_feedback = SmiOr(previous_feedback, feedback); 5706 Node* combined_feedback = SmiOr(previous_feedback, feedback);
5591 StoreFixedArrayElement(feedback_vector, slot_id, combined_feedback, 5707 StoreFixedArrayElement(feedback_vector, slot_id, combined_feedback,
5592 SKIP_WRITE_BARRIER); 5708 SKIP_WRITE_BARRIER);
5593 } 5709 }
5594 5710
5595 Node* CodeStubAssembler::LoadReceiverMap(Node* receiver) { 5711 Node* CodeStubAssembler::LoadReceiverMap(Node* receiver) {
5596 Variable var_receiver_map(this, MachineRepresentation::kTagged); 5712 return Select(TaggedIsSmi(receiver),
jgruber 2017/03/13 12:27:37 Drive-by simplification.
5597 Label load_smi_map(this, Label::kDeferred), load_receiver_map(this), 5713 [=] { return LoadRoot(Heap::kHeapNumberMapRootIndex); },
5598 if_result(this); 5714 [=] { return LoadMap(receiver); },
5599 5715 MachineRepresentation::kTagged);
5600 Branch(TaggedIsSmi(receiver), &load_smi_map, &load_receiver_map);
5601 Bind(&load_smi_map);
5602 {
5603 var_receiver_map.Bind(LoadRoot(Heap::kHeapNumberMapRootIndex));
5604 Goto(&if_result);
5605 }
5606 Bind(&load_receiver_map);
5607 {
5608 var_receiver_map.Bind(LoadMap(receiver));
5609 Goto(&if_result);
5610 }
5611 Bind(&if_result);
5612 return var_receiver_map.value();
5613 } 5716 }
5614 5717
5615 Node* CodeStubAssembler::TryToIntptr(Node* key, Label* miss) { 5718 Node* CodeStubAssembler::TryToIntptr(Node* key, Label* miss) {
5616 Variable var_intptr_key(this, MachineType::PointerRepresentation()); 5719 Variable var_intptr_key(this, MachineType::PointerRepresentation());
5617 Label done(this, &var_intptr_key), key_is_smi(this); 5720 Label done(this, &var_intptr_key), key_is_smi(this);
5618 GotoIf(TaggedIsSmi(key), &key_is_smi); 5721 GotoIf(TaggedIsSmi(key), &key_is_smi);
5619 // Try to convert a heap number to a Smi. 5722 // Try to convert a heap number to a Smi.
5620 GotoIfNot(IsHeapNumberMap(LoadMap(key)), miss); 5723 GotoIfNot(IsHeapNumberMap(LoadMap(key)), miss);
5621 { 5724 {
5622 Node* value = LoadHeapNumberValue(key); 5725 Node* value = LoadHeapNumberValue(key);
(...skipping 2697 matching lines...) Expand 10 before | Expand all | Expand 10 after
8320 formatted.c_str(), TENURED); 8423 formatted.c_str(), TENURED);
8321 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), 8424 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(),
8322 HeapConstant(string)); 8425 HeapConstant(string));
8323 } 8426 }
8324 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); 8427 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value);
8325 #endif 8428 #endif
8326 } 8429 }
8327 8430
8328 } // namespace internal 8431 } // namespace internal
8329 } // namespace v8 8432 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698