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

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

Issue 2738413002: [regexp] Port RegExpExecStub to CSA (mostly) (Closed)
Patch Set: Rebase 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/code-stub-assembler.h ('k') | src/ia32/code-stubs-ia32.cc » ('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 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 2872 matching lines...) Expand 10 before | Expand all | Expand 10 after
2883 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); 2883 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE);
2884 return Int32LessThanOrEqual(instance_type, 2884 return Int32LessThanOrEqual(instance_type,
2885 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)); 2885 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE));
2886 } 2886 }
2887 2887
2888 Node* CodeStubAssembler::IsStringInstanceType(Node* instance_type) { 2888 Node* CodeStubAssembler::IsStringInstanceType(Node* instance_type) {
2889 STATIC_ASSERT(INTERNALIZED_STRING_TYPE == FIRST_TYPE); 2889 STATIC_ASSERT(INTERNALIZED_STRING_TYPE == FIRST_TYPE);
2890 return Int32LessThan(instance_type, Int32Constant(FIRST_NONSTRING_TYPE)); 2890 return Int32LessThan(instance_type, Int32Constant(FIRST_NONSTRING_TYPE));
2891 } 2891 }
2892 2892
2893 Node* CodeStubAssembler::IsOneByteStringInstanceType(Node* instance_type) {
2894 CSA_ASSERT(this, IsStringInstanceType(instance_type));
2895 return Word32Equal(
2896 Word32And(instance_type, Int32Constant(kStringEncodingMask)),
2897 Int32Constant(kOneByteStringTag));
2898 }
2899
2900 Node* CodeStubAssembler::IsSequentialStringInstanceType(Node* instance_type) {
2901 CSA_ASSERT(this, IsStringInstanceType(instance_type));
2902 return Word32Equal(
2903 Word32And(instance_type, Int32Constant(kStringRepresentationMask)),
2904 Int32Constant(kSeqStringTag));
2905 }
2906
2893 Node* CodeStubAssembler::IsJSReceiverInstanceType(Node* instance_type) { 2907 Node* CodeStubAssembler::IsJSReceiverInstanceType(Node* instance_type) {
2894 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); 2908 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
2895 return Int32GreaterThanOrEqual(instance_type, 2909 return Int32GreaterThanOrEqual(instance_type,
2896 Int32Constant(FIRST_JS_RECEIVER_TYPE)); 2910 Int32Constant(FIRST_JS_RECEIVER_TYPE));
2897 } 2911 }
2898 2912
2899 Node* CodeStubAssembler::IsJSReceiver(Node* object) { 2913 Node* CodeStubAssembler::IsJSReceiver(Node* object) {
2900 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); 2914 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
2901 return IsJSReceiverInstanceType(LoadInstanceType(object)); 2915 return IsJSReceiverInstanceType(LoadInstanceType(object));
2902 } 2916 }
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
3248 // given character range using CopyStringCharacters. 3262 // given character range using CopyStringCharacters.
3249 // |from_string| must be a sequential string. |from_index| and 3263 // |from_string| must be a sequential string. |from_index| and
3250 // |character_count| must be Smis s.t. 3264 // |character_count| must be Smis s.t.
3251 // 0 <= |from_index| <= |from_index| + |character_count| < from_string.length. 3265 // 0 <= |from_index| <= |from_index| + |character_count| < from_string.length.
3252 Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context, 3266 Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context,
3253 Node* from, Node* from_instance_type, 3267 Node* from, Node* from_instance_type,
3254 Node* from_index, Node* character_count) { 3268 Node* from_index, Node* character_count) {
3255 typedef CodeStubAssembler::Label Label; 3269 typedef CodeStubAssembler::Label Label;
3256 typedef CodeStubAssembler::Variable Variable; 3270 typedef CodeStubAssembler::Variable Variable;
3257 3271
3258 Label end(a), two_byte_sequential(a); 3272 Label end(a), one_byte_sequential(a), two_byte_sequential(a);
3259 Variable var_result(a, MachineRepresentation::kTagged); 3273 Variable var_result(a, MachineRepresentation::kTagged);
3260 3274
3261 Node* const smi_zero = a->SmiConstant(Smi::kZero); 3275 Node* const smi_zero = a->SmiConstant(Smi::kZero);
3262 3276
3263 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0); 3277 a->Branch(a->IsOneByteStringInstanceType(from_instance_type),
3264 a->GotoIf(a->Word32Equal(a->Word32And(from_instance_type, 3278 &one_byte_sequential, &two_byte_sequential);
3265 a->Int32Constant(kStringEncodingMask)),
3266 a->Int32Constant(0)),
3267 &two_byte_sequential);
3268 3279
3269 // The subject string is a sequential one-byte string. 3280 // The subject string is a sequential one-byte string.
3281 a->Bind(&one_byte_sequential);
3270 { 3282 {
3271 Node* result = 3283 Node* result =
3272 a->AllocateSeqOneByteString(context, a->SmiToWord(character_count)); 3284 a->AllocateSeqOneByteString(context, a->SmiToWord(character_count));
3273 a->CopyStringCharacters(from, result, from_index, smi_zero, character_count, 3285 a->CopyStringCharacters(from, result, from_index, smi_zero, character_count,
3274 String::ONE_BYTE_ENCODING, 3286 String::ONE_BYTE_ENCODING,
3275 String::ONE_BYTE_ENCODING, 3287 String::ONE_BYTE_ENCODING,
3276 CodeStubAssembler::SMI_PARAMETERS); 3288 CodeStubAssembler::SMI_PARAMETERS);
3277 var_result.Bind(result); 3289 var_result.Bind(result);
3278 3290
3279 a->Goto(&end); 3291 a->Goto(&end);
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
3544 Node* const instance_type) { 3556 Node* const instance_type) {
3545 CSA_ASSERT(a, a->IsStringInstanceType(instance_type)); 3557 CSA_ASSERT(a, a->IsStringInstanceType(instance_type));
3546 STATIC_ASSERT(kShortExternalStringTag != 0); 3558 STATIC_ASSERT(kShortExternalStringTag != 0);
3547 return a->Word32NotEqual( 3559 return a->Word32NotEqual(
3548 a->Word32And(instance_type, a->Int32Constant(kShortExternalStringMask)), 3560 a->Word32And(instance_type, a->Int32Constant(kShortExternalStringMask)),
3549 a->Int32Constant(0)); 3561 a->Int32Constant(0));
3550 } 3562 }
3551 3563
3552 } // namespace 3564 } // namespace
3553 3565
3566 void CodeStubAssembler::TryUnpackString(Variable* var_string,
3567 Variable* var_offset,
3568 Variable* var_instance_type,
3569 Label* if_bailout) {
3570 DCHECK_EQ(var_string->rep(), MachineType::PointerRepresentation());
3571 DCHECK_EQ(var_offset->rep(), MachineType::PointerRepresentation());
3572 DCHECK_EQ(var_instance_type->rep(), MachineRepresentation::kWord32);
3573 CSA_ASSERT(this, IsString(var_string->value()));
3574
3575 Label out(this);
3576
3577 VariableList vars({var_string, var_offset, var_instance_type}, zone());
3578 Label dispatch(this, vars);
3579 Label if_isdirect(this);
3580 Label if_iscons(this, Label::kDeferred);
3581 Label if_isexternal(this, Label::kDeferred);
3582 Label if_issliced(this, Label::kDeferred);
3583 Label if_isthin(this, Label::kDeferred);
3584
3585 Goto(&dispatch);
3586
3587 // Dispatch based on string representation.
3588 Bind(&dispatch);
3589 {
3590 int32_t values[] = {
3591 kSeqStringTag, kConsStringTag, kExternalStringTag,
3592 kSlicedStringTag, kThinStringTag,
3593 };
3594 Label* labels[] = {
3595 &if_isdirect, &if_iscons, &if_isexternal, &if_issliced, &if_isthin,
3596 };
3597 STATIC_ASSERT(arraysize(values) == arraysize(labels));
3598
3599 Node* const representation = Word32And(
3600 var_instance_type->value(), Int32Constant(kStringRepresentationMask));
3601 Switch(representation, if_bailout, values, labels, arraysize(values));
3602 }
3603
3604 // Cons string. Check whether it is flat, then fetch first part.
3605 // Flat cons strings have an empty second part.
3606 Bind(&if_iscons);
3607 {
3608 Node* const string = var_string->value();
3609 GotoIfNot(IsEmptyString(LoadObjectField(string, ConsString::kSecondOffset)),
3610 if_bailout);
3611
3612 Node* const lhs = LoadObjectField(string, ConsString::kFirstOffset);
3613 var_string->Bind(BitcastTaggedToWord(lhs));
3614 var_instance_type->Bind(LoadInstanceType(lhs));
3615
3616 Goto(&dispatch);
3617 }
3618
3619 // Sliced string. Fetch parent and correct start index by offset.
3620 Bind(&if_issliced);
3621 {
3622 Node* const string = var_string->value();
3623 Node* const sliced_offset =
3624 LoadObjectField(string, SlicedString::kOffsetOffset);
3625 var_offset->Bind(IntPtrAdd(var_offset->value(), SmiUntag(sliced_offset)));
3626
3627 Node* const parent = LoadObjectField(string, SlicedString::kParentOffset);
3628 var_string->Bind(BitcastTaggedToWord(parent));
3629 var_instance_type->Bind(LoadInstanceType(parent));
3630
3631 Goto(&dispatch);
3632 }
3633
3634 // Thin string. Fetch the actual string.
3635 Bind(&if_isthin);
3636 {
3637 Node* const string = var_string->value();
3638 Node* const actual_string =
3639 LoadObjectField(string, ThinString::kActualOffset);
3640 Node* const actual_instance_type = LoadInstanceType(actual_string);
3641
3642 var_string->Bind(BitcastTaggedToWord(actual_string));
3643 var_instance_type->Bind(actual_instance_type);
3644
3645 Goto(&dispatch);
3646 }
3647
3648 // External string.
3649 Bind(&if_isexternal);
3650 {
3651 Node* const string = var_string->value();
3652 Node* const faked_seq_string =
3653 TryDerefExternalString(string, var_instance_type->value(), if_bailout);
3654
3655 STATIC_ASSERT(kSeqStringTag == 0x0);
3656 Node* const faked_seq_instance_type = Word32Xor(
3657 var_instance_type->value(), Int32Constant(kExternalStringTag));
3658 CSA_ASSERT(this, IsSequentialStringInstanceType(faked_seq_instance_type));
3659
3660 var_string->Bind(faked_seq_string);
3661 var_instance_type->Bind(faked_seq_instance_type);
3662
3663 Goto(&if_isdirect);
3664 }
3665
3666 Bind(&if_isdirect);
3667 }
3668
3554 Node* CodeStubAssembler::TryDerefExternalString(Node* const string, 3669 Node* CodeStubAssembler::TryDerefExternalString(Node* const string,
3555 Node* const instance_type, 3670 Node* const instance_type,
3556 Label* if_bailout) { 3671 Label* if_bailout) {
3557 Label out(this); 3672 Label out(this);
3558 3673
3559 USE(IsExternalStringInstanceType); 3674 USE(IsExternalStringInstanceType);
3560 CSA_ASSERT(this, IsExternalStringInstanceType(this, instance_type)); 3675 CSA_ASSERT(this, IsExternalStringInstanceType(this, instance_type));
3561 GotoIf(IsShortExternalStringInstanceType(this, instance_type), if_bailout); 3676 GotoIf(IsShortExternalStringInstanceType(this, instance_type), if_bailout);
3562 3677
3563 // Move the pointer so that offset-wise, it looks like a sequential string. 3678 // Move the pointer so that offset-wise, it looks like a sequential string.
(...skipping 2047 matching lines...) Expand 10 before | Expand all | Expand 10 after
5611 // This method is used for binary op and compare feedback. These 5726 // This method is used for binary op and compare feedback. These
5612 // vector nodes are initialized with a smi 0, so we can simply OR 5727 // vector nodes are initialized with a smi 0, so we can simply OR
5613 // our new feedback in place. 5728 // our new feedback in place.
5614 Node* previous_feedback = LoadFixedArrayElement(feedback_vector, slot_id); 5729 Node* previous_feedback = LoadFixedArrayElement(feedback_vector, slot_id);
5615 Node* combined_feedback = SmiOr(previous_feedback, feedback); 5730 Node* combined_feedback = SmiOr(previous_feedback, feedback);
5616 StoreFixedArrayElement(feedback_vector, slot_id, combined_feedback, 5731 StoreFixedArrayElement(feedback_vector, slot_id, combined_feedback,
5617 SKIP_WRITE_BARRIER); 5732 SKIP_WRITE_BARRIER);
5618 } 5733 }
5619 5734
5620 Node* CodeStubAssembler::LoadReceiverMap(Node* receiver) { 5735 Node* CodeStubAssembler::LoadReceiverMap(Node* receiver) {
5621 Variable var_receiver_map(this, MachineRepresentation::kTagged); 5736 return Select(TaggedIsSmi(receiver),
5622 Label load_smi_map(this, Label::kDeferred), load_receiver_map(this), 5737 [=] { return LoadRoot(Heap::kHeapNumberMapRootIndex); },
5623 if_result(this); 5738 [=] { return LoadMap(receiver); },
5624 5739 MachineRepresentation::kTagged);
5625 Branch(TaggedIsSmi(receiver), &load_smi_map, &load_receiver_map);
5626 Bind(&load_smi_map);
5627 {
5628 var_receiver_map.Bind(LoadRoot(Heap::kHeapNumberMapRootIndex));
5629 Goto(&if_result);
5630 }
5631 Bind(&load_receiver_map);
5632 {
5633 var_receiver_map.Bind(LoadMap(receiver));
5634 Goto(&if_result);
5635 }
5636 Bind(&if_result);
5637 return var_receiver_map.value();
5638 } 5740 }
5639 5741
5640 Node* CodeStubAssembler::TryToIntptr(Node* key, Label* miss) { 5742 Node* CodeStubAssembler::TryToIntptr(Node* key, Label* miss) {
5641 Variable var_intptr_key(this, MachineType::PointerRepresentation()); 5743 Variable var_intptr_key(this, MachineType::PointerRepresentation());
5642 Label done(this, &var_intptr_key), key_is_smi(this); 5744 Label done(this, &var_intptr_key), key_is_smi(this);
5643 GotoIf(TaggedIsSmi(key), &key_is_smi); 5745 GotoIf(TaggedIsSmi(key), &key_is_smi);
5644 // Try to convert a heap number to a Smi. 5746 // Try to convert a heap number to a Smi.
5645 GotoIfNot(IsHeapNumberMap(LoadMap(key)), miss); 5747 GotoIfNot(IsHeapNumberMap(LoadMap(key)), miss);
5646 { 5748 {
5647 Node* value = LoadHeapNumberValue(key); 5749 Node* value = LoadHeapNumberValue(key);
(...skipping 2697 matching lines...) Expand 10 before | Expand all | Expand 10 after
8345 formatted.c_str(), TENURED); 8447 formatted.c_str(), TENURED);
8346 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), 8448 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(),
8347 HeapConstant(string)); 8449 HeapConstant(string));
8348 } 8450 }
8349 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); 8451 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value);
8350 #endif 8452 #endif
8351 } 8453 }
8352 8454
8353 } // namespace internal 8455 } // namespace internal
8354 } // namespace v8 8456 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698