OLD | NEW |
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 3359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3370 (kSlicedStringTag & kConsStringTag & kThinStringTag)); | 3370 (kSlicedStringTag & kConsStringTag & kThinStringTag)); |
3371 STATIC_ASSERT(kIsIndirectStringMask != 0); | 3371 STATIC_ASSERT(kIsIndirectStringMask != 0); |
3372 Label underlying_unpacked(this); | 3372 Label underlying_unpacked(this); |
3373 GotoIf(Word32Equal( | 3373 GotoIf(Word32Equal( |
3374 Word32And(instance_type, Int32Constant(kIsIndirectStringMask)), | 3374 Word32And(instance_type, Int32Constant(kIsIndirectStringMask)), |
3375 Int32Constant(0)), | 3375 Int32Constant(0)), |
3376 &underlying_unpacked); | 3376 &underlying_unpacked); |
3377 | 3377 |
3378 // The subject string is a sliced, cons, or thin string. | 3378 // The subject string is a sliced, cons, or thin string. |
3379 | 3379 |
3380 Label sliced_string(this), thin_or_sliced(this); | 3380 Label thin_string(this), thin_or_sliced(this); |
3381 var_representation.Bind( | 3381 var_representation.Bind( |
3382 Word32And(instance_type, Int32Constant(kStringRepresentationMask))); | 3382 Word32And(instance_type, Int32Constant(kStringRepresentationMask))); |
3383 GotoIf( | 3383 GotoIf( |
3384 Word32NotEqual(var_representation.value(), Int32Constant(kConsStringTag)), | 3384 Word32NotEqual(var_representation.value(), Int32Constant(kConsStringTag)), |
3385 &thin_or_sliced); | 3385 &thin_or_sliced); |
3386 | 3386 |
3387 // Cons string. Check whether it is flat, then fetch first part. | 3387 // Cons string. Check whether it is flat, then fetch first part. |
3388 // Flat cons strings have an empty second part. | 3388 // Flat cons strings have an empty second part. |
3389 { | 3389 { |
3390 GotoIf(WordNotEqual(LoadObjectField(string, ConsString::kSecondOffset), | 3390 GotoIf(WordNotEqual(LoadObjectField(string, ConsString::kSecondOffset), |
3391 EmptyStringConstant()), | 3391 EmptyStringConstant()), |
3392 &runtime); | 3392 &runtime); |
3393 | 3393 |
3394 Node* first_string_part = LoadObjectField(string, ConsString::kFirstOffset); | 3394 Node* first_string_part = LoadObjectField(string, ConsString::kFirstOffset); |
3395 var_string.Bind(first_string_part); | 3395 var_string.Bind(first_string_part); |
3396 var_instance_type.Bind(LoadInstanceType(first_string_part)); | 3396 var_instance_type.Bind(LoadInstanceType(first_string_part)); |
3397 var_representation.Bind(Word32And( | 3397 var_representation.Bind(Word32And( |
3398 var_instance_type.value(), Int32Constant(kStringRepresentationMask))); | 3398 var_instance_type.value(), Int32Constant(kStringRepresentationMask))); |
3399 | 3399 |
3400 // The loaded first part might be a thin string. | 3400 // The loaded first part might be a thin string. |
3401 Branch(Word32Equal(Word32And(var_instance_type.value(), | 3401 Branch(Word32Equal(Word32And(var_instance_type.value(), |
3402 Int32Constant(kIsIndirectStringMask)), | 3402 Int32Constant(kIsIndirectStringMask)), |
3403 Int32Constant(0)), | 3403 Int32Constant(0)), |
3404 &underlying_unpacked, &thin_or_sliced); | 3404 &underlying_unpacked, &thin_string); |
3405 } | 3405 } |
3406 | 3406 |
3407 Bind(&thin_or_sliced); | 3407 Bind(&thin_or_sliced); |
3408 { | 3408 { |
3409 GotoIf(Word32Equal(var_representation.value(), | 3409 GotoIf( |
3410 Int32Constant(kSlicedStringTag)), | 3410 Word32Equal(var_representation.value(), Int32Constant(kThinStringTag)), |
3411 &sliced_string); | 3411 &thin_string); |
3412 Node* actual_string = | 3412 // Otherwise it's a sliced string. |
3413 LoadObjectField(var_string.value(), ThinString::kActualOffset); | |
3414 var_string.Bind(actual_string); | |
3415 var_instance_type.Bind(LoadInstanceType(actual_string)); | |
3416 Goto(&underlying_unpacked); | |
3417 } | |
3418 | |
3419 Bind(&sliced_string); | |
3420 { | |
3421 // Fetch parent and correct start index by offset. | 3413 // Fetch parent and correct start index by offset. |
3422 Node* sliced_offset = | 3414 Node* sliced_offset = |
3423 LoadObjectField(var_string.value(), SlicedString::kOffsetOffset); | 3415 LoadObjectField(var_string.value(), SlicedString::kOffsetOffset); |
3424 var_from.Bind(SmiAdd(from, sliced_offset)); | 3416 var_from.Bind(SmiAdd(from, sliced_offset)); |
3425 | 3417 |
3426 Node* slice_parent = LoadObjectField(string, SlicedString::kParentOffset); | 3418 Node* slice_parent = LoadObjectField(string, SlicedString::kParentOffset); |
3427 var_string.Bind(slice_parent); | 3419 var_string.Bind(slice_parent); |
3428 | 3420 |
3429 Node* slice_parent_instance_type = LoadInstanceType(slice_parent); | 3421 Node* slice_parent_instance_type = LoadInstanceType(slice_parent); |
3430 var_instance_type.Bind(slice_parent_instance_type); | 3422 var_instance_type.Bind(slice_parent_instance_type); |
3431 | 3423 |
| 3424 // The loaded parent might be a thin string. |
| 3425 Branch(Word32Equal(Word32And(var_instance_type.value(), |
| 3426 Int32Constant(kIsIndirectStringMask)), |
| 3427 Int32Constant(0)), |
| 3428 &underlying_unpacked, &thin_string); |
| 3429 } |
| 3430 |
| 3431 Bind(&thin_string); |
| 3432 { |
| 3433 Node* actual_string = |
| 3434 LoadObjectField(var_string.value(), ThinString::kActualOffset); |
| 3435 var_string.Bind(actual_string); |
| 3436 var_instance_type.Bind(LoadInstanceType(actual_string)); |
3432 Goto(&underlying_unpacked); | 3437 Goto(&underlying_unpacked); |
3433 } | 3438 } |
3434 | 3439 |
3435 // The subject string can only be external or sequential string of either | 3440 // The subject string can only be external or sequential string of either |
3436 // encoding at this point. | 3441 // encoding at this point. |
3437 Label external_string(this); | 3442 Label external_string(this); |
3438 Bind(&underlying_unpacked); | 3443 Bind(&underlying_unpacked); |
3439 { | 3444 { |
3440 if (FLAG_string_slices) { | 3445 if (FLAG_string_slices) { |
3441 Label copy_routine(this); | 3446 Label copy_routine(this); |
(...skipping 4946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8388 formatted.c_str(), TENURED); | 8393 formatted.c_str(), TENURED); |
8389 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), | 8394 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), |
8390 HeapConstant(string)); | 8395 HeapConstant(string)); |
8391 } | 8396 } |
8392 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), tagged_value); | 8397 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), tagged_value); |
8393 #endif | 8398 #endif |
8394 } | 8399 } |
8395 | 8400 |
8396 } // namespace internal | 8401 } // namespace internal |
8397 } // namespace v8 | 8402 } // namespace v8 |
OLD | NEW |