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

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

Issue 1877263002: Revert of [builtins] Migrate String.prototype.charCodeAt and String.prototype.charAt to TurboFan. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 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/compiler/code-stub-assembler.h ('k') | src/js/messages.js » ('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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/compiler/code-stub-assembler.h" 5 #include "src/compiler/code-stub-assembler.h"
6 6
7 #include <ostream> 7 #include <ostream>
8 8
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/compiler/graph.h" 10 #include "src/compiler/graph.h"
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 } 107 }
108 108
109 Node* CodeStubAssembler::Float64Constant(double value) { 109 Node* CodeStubAssembler::Float64Constant(double value) {
110 return raw_assembler_->Float64Constant(value); 110 return raw_assembler_->Float64Constant(value);
111 } 111 }
112 112
113 Node* CodeStubAssembler::BooleanMapConstant() { 113 Node* CodeStubAssembler::BooleanMapConstant() {
114 return HeapConstant(isolate()->factory()->boolean_map()); 114 return HeapConstant(isolate()->factory()->boolean_map());
115 } 115 }
116 116
117 Node* CodeStubAssembler::EmptyStringConstant() {
118 return LoadRoot(Heap::kempty_stringRootIndex);
119 }
120
121 Node* CodeStubAssembler::HeapNumberMapConstant() { 117 Node* CodeStubAssembler::HeapNumberMapConstant() {
122 return HeapConstant(isolate()->factory()->heap_number_map()); 118 return HeapConstant(isolate()->factory()->heap_number_map());
123 } 119 }
124 120
125 Node* CodeStubAssembler::NaNConstant() {
126 return LoadRoot(Heap::kNanValueRootIndex);
127 }
128
129 Node* CodeStubAssembler::NoContextConstant() {
130 return SmiConstant(Smi::FromInt(0));
131 }
132
133 Node* CodeStubAssembler::NullConstant() { 121 Node* CodeStubAssembler::NullConstant() {
134 return LoadRoot(Heap::kNullValueRootIndex); 122 return LoadRoot(Heap::kNullValueRootIndex);
135 } 123 }
136 124
137 Node* CodeStubAssembler::UndefinedConstant() { 125 Node* CodeStubAssembler::UndefinedConstant() {
138 return LoadRoot(Heap::kUndefinedValueRootIndex); 126 return LoadRoot(Heap::kUndefinedValueRootIndex);
139 } 127 }
140 128
141 Node* CodeStubAssembler::Parameter(int value) { 129 Node* CodeStubAssembler::Parameter(int value) {
142 return raw_assembler_->Parameter(value); 130 return raw_assembler_->Parameter(value);
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 } 342 }
355 343
356 Node* CodeStubAssembler::SmiTag(Node* value) { 344 Node* CodeStubAssembler::SmiTag(Node* value) {
357 return raw_assembler_->WordShl(value, SmiShiftBitsConstant()); 345 return raw_assembler_->WordShl(value, SmiShiftBitsConstant());
358 } 346 }
359 347
360 Node* CodeStubAssembler::SmiUntag(Node* value) { 348 Node* CodeStubAssembler::SmiUntag(Node* value) {
361 return raw_assembler_->WordSar(value, SmiShiftBitsConstant()); 349 return raw_assembler_->WordSar(value, SmiShiftBitsConstant());
362 } 350 }
363 351
364 Node* CodeStubAssembler::SmiFromWord32(Node* value) {
365 if (raw_assembler_->machine()->Is64()) {
366 value = raw_assembler_->ChangeInt32ToInt64(value);
367 }
368 return raw_assembler_->WordShl(value, SmiShiftBitsConstant());
369 }
370
371 Node* CodeStubAssembler::SmiToWord32(Node* value) { 352 Node* CodeStubAssembler::SmiToWord32(Node* value) {
372 Node* result = raw_assembler_->WordSar(value, SmiShiftBitsConstant()); 353 Node* result = raw_assembler_->WordSar(value, SmiShiftBitsConstant());
373 if (raw_assembler_->machine()->Is64()) { 354 if (raw_assembler_->machine()->Is64()) {
374 result = raw_assembler_->TruncateInt64ToInt32(result); 355 result = raw_assembler_->TruncateInt64ToInt32(result);
375 } 356 }
376 return result; 357 return result;
377 } 358 }
378 359
379 Node* CodeStubAssembler::SmiToFloat64(Node* value) { 360 Node* CodeStubAssembler::SmiToFloat64(Node* value) {
380 return ChangeInt32ToFloat64(SmiUntag(value)); 361 return ChangeInt32ToFloat64(SmiUntag(value));
381 } 362 }
382 363
383 Node* CodeStubAssembler::SmiAdd(Node* a, Node* b) { return IntPtrAdd(a, b); } 364 Node* CodeStubAssembler::SmiAdd(Node* a, Node* b) { return IntPtrAdd(a, b); }
384 365
385 Node* CodeStubAssembler::SmiAddWithOverflow(Node* a, Node* b) { 366 Node* CodeStubAssembler::SmiAddWithOverflow(Node* a, Node* b) {
386 return IntPtrAddWithOverflow(a, b); 367 return IntPtrAddWithOverflow(a, b);
387 } 368 }
388 369
389 Node* CodeStubAssembler::SmiSub(Node* a, Node* b) { return IntPtrSub(a, b); } 370 Node* CodeStubAssembler::SmiSub(Node* a, Node* b) { return IntPtrSub(a, b); }
390 371
391 Node* CodeStubAssembler::SmiSubWithOverflow(Node* a, Node* b) { 372 Node* CodeStubAssembler::SmiSubWithOverflow(Node* a, Node* b) {
392 return IntPtrSubWithOverflow(a, b); 373 return IntPtrSubWithOverflow(a, b);
393 } 374 }
394 375
395 Node* CodeStubAssembler::SmiEqual(Node* a, Node* b) { return WordEqual(a, b); } 376 Node* CodeStubAssembler::SmiEqual(Node* a, Node* b) { return WordEqual(a, b); }
396 377
397 Node* CodeStubAssembler::SmiAboveOrEqual(Node* a, Node* b) {
398 return UintPtrGreaterThanOrEqual(a, b);
399 }
400
401 Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) { 378 Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) {
402 return IntPtrLessThan(a, b); 379 return IntPtrLessThan(a, b);
403 } 380 }
404 381
405 Node* CodeStubAssembler::SmiLessThanOrEqual(Node* a, Node* b) { 382 Node* CodeStubAssembler::SmiLessThanOrEqual(Node* a, Node* b) {
406 return IntPtrLessThanOrEqual(a, b); 383 return IntPtrLessThanOrEqual(a, b);
407 } 384 }
408 385
409 Node* CodeStubAssembler::SmiMin(Node* a, Node* b) { 386 Node* CodeStubAssembler::SmiMin(Node* a, Node* b) {
410 // TODO(bmeurer): Consider using Select once available. 387 // TODO(bmeurer): Consider using Select once available.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 MachineType rep) { 429 MachineType rep) {
453 return raw_assembler_->Load(rep, buffer, IntPtrConstant(offset)); 430 return raw_assembler_->Load(rep, buffer, IntPtrConstant(offset));
454 } 431 }
455 432
456 Node* CodeStubAssembler::LoadObjectField(Node* object, int offset, 433 Node* CodeStubAssembler::LoadObjectField(Node* object, int offset,
457 MachineType rep) { 434 MachineType rep) {
458 return raw_assembler_->Load(rep, object, 435 return raw_assembler_->Load(rep, object,
459 IntPtrConstant(offset - kHeapObjectTag)); 436 IntPtrConstant(offset - kHeapObjectTag));
460 } 437 }
461 438
462 Node* CodeStubAssembler::StoreObjectFieldNoWriteBarrier(
463 Node* object, int offset, Node* value, MachineRepresentation rep) {
464 return StoreNoWriteBarrier(rep, object,
465 IntPtrConstant(offset - kHeapObjectTag), value);
466 }
467
468 Node* CodeStubAssembler::LoadHeapNumberValue(Node* object) { 439 Node* CodeStubAssembler::LoadHeapNumberValue(Node* object) {
469 return Load(MachineType::Float64(), object, 440 return Load(MachineType::Float64(), object,
470 IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag)); 441 IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag));
471 } 442 }
472 443
473 Node* CodeStubAssembler::StoreHeapNumberValue(Node* object, Node* value) { 444 Node* CodeStubAssembler::StoreHeapNumberValue(Node* object, Node* value) {
474 return StoreNoWriteBarrier( 445 return StoreNoWriteBarrier(
475 MachineRepresentation::kFloat64, object, 446 MachineRepresentation::kFloat64, object,
476 IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag), value); 447 IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag), value);
477 } 448 }
(...skipping 27 matching lines...) Expand all
505 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) { 476 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) {
506 return LoadObjectField(map, Map::kDescriptorsOffset); 477 return LoadObjectField(map, Map::kDescriptorsOffset);
507 } 478 }
508 479
509 Node* CodeStubAssembler::LoadNameHash(Node* name) { 480 Node* CodeStubAssembler::LoadNameHash(Node* name) {
510 return Load(MachineType::Uint32(), name, 481 return Load(MachineType::Uint32(), name,
511 IntPtrConstant(Name::kHashFieldOffset - kHeapObjectTag)); 482 IntPtrConstant(Name::kHashFieldOffset - kHeapObjectTag));
512 } 483 }
513 484
514 Node* CodeStubAssembler::LoadFixedArrayElementInt32Index( 485 Node* CodeStubAssembler::LoadFixedArrayElementInt32Index(
515 Node* object, Node* index, int additional_offset) { 486 Node* object, Node* int32_index, int additional_offset) {
516 Node* header_size = IntPtrConstant(additional_offset + 487 Node* header_size = IntPtrConstant(additional_offset +
517 FixedArray::kHeaderSize - kHeapObjectTag); 488 FixedArray::kHeaderSize - kHeapObjectTag);
518 if (raw_assembler_->machine()->Is64()) { 489 Node* scaled_index = WordShl(int32_index, IntPtrConstant(kPointerSizeLog2));
519 index = ChangeInt32ToInt64(index);
520 }
521 Node* scaled_index = WordShl(index, IntPtrConstant(kPointerSizeLog2));
522 Node* offset = IntPtrAdd(scaled_index, header_size); 490 Node* offset = IntPtrAdd(scaled_index, header_size);
523 return Load(MachineType::AnyTagged(), object, offset); 491 return Load(MachineType::AnyTagged(), object, offset);
524 } 492 }
525 493
526 Node* CodeStubAssembler::LoadFixedArrayElementSmiIndex(Node* object, 494 Node* CodeStubAssembler::LoadFixedArrayElementSmiIndex(Node* object,
527 Node* smi_index, 495 Node* smi_index,
528 int additional_offset) { 496 int additional_offset) {
529 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; 497 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize;
530 Node* header_size = IntPtrConstant(additional_offset + 498 Node* header_size = IntPtrConstant(additional_offset +
531 FixedArray::kHeaderSize - kHeapObjectTag); 499 FixedArray::kHeaderSize - kHeapObjectTag);
(...skipping 16 matching lines...) Expand all
548 Node* CodeStubAssembler::StoreFixedArrayElementNoWriteBarrier(Node* object, 516 Node* CodeStubAssembler::StoreFixedArrayElementNoWriteBarrier(Node* object,
549 Node* index, 517 Node* index,
550 Node* value) { 518 Node* value) {
551 Node* offset = 519 Node* offset =
552 IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)), 520 IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)),
553 IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag)); 521 IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag));
554 return StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset, 522 return StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset,
555 value); 523 value);
556 } 524 }
557 525
558 Node* CodeStubAssembler::StoreFixedArrayElementInt32Index(Node* object,
559 Node* index,
560 Node* value) {
561 if (raw_assembler_->machine()->Is64()) {
562 index = ChangeInt32ToInt64(index);
563 }
564 Node* offset =
565 IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)),
566 IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag));
567 return Store(MachineRepresentation::kTagged, object, offset, value);
568 }
569
570 Node* CodeStubAssembler::LoadRoot(Heap::RootListIndex root_index) { 526 Node* CodeStubAssembler::LoadRoot(Heap::RootListIndex root_index) {
571 if (isolate()->heap()->RootCanBeTreatedAsConstant(root_index)) { 527 if (isolate()->heap()->RootCanBeTreatedAsConstant(root_index)) {
572 Handle<Object> root = isolate()->heap()->root_handle(root_index); 528 Handle<Object> root = isolate()->heap()->root_handle(root_index);
573 if (root->IsSmi()) { 529 if (root->IsSmi()) {
574 return SmiConstant(Smi::cast(*root)); 530 return SmiConstant(Smi::cast(*root));
575 } else { 531 } else {
576 return HeapConstant(Handle<HeapObject>::cast(root)); 532 return HeapConstant(Handle<HeapObject>::cast(root));
577 } 533 }
578 } 534 }
579 535
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 StoreMapNoWriteBarrier(result, HeapNumberMapConstant()); 665 StoreMapNoWriteBarrier(result, HeapNumberMapConstant());
710 return result; 666 return result;
711 } 667 }
712 668
713 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value) { 669 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value) {
714 Node* result = AllocateHeapNumber(); 670 Node* result = AllocateHeapNumber();
715 StoreHeapNumberValue(result, value); 671 StoreHeapNumberValue(result, value);
716 return result; 672 return result;
717 } 673 }
718 674
719 Node* CodeStubAssembler::AllocateSeqOneByteString(int length) {
720 Node* result = Allocate(SeqOneByteString::SizeFor(length));
721 StoreMapNoWriteBarrier(result, LoadRoot(Heap::kOneByteStringMapRootIndex));
722 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset,
723 SmiConstant(Smi::FromInt(length)));
724 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldOffset,
725 IntPtrConstant(String::kEmptyHashField));
726 return result;
727 }
728
729 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length) {
730 Node* result = Allocate(SeqTwoByteString::SizeFor(length));
731 StoreMapNoWriteBarrier(result, LoadRoot(Heap::kStringMapRootIndex));
732 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset,
733 SmiConstant(Smi::FromInt(length)));
734 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldOffset,
735 IntPtrConstant(String::kEmptyHashField));
736 return result;
737 }
738
739 Node* CodeStubAssembler::Load(MachineType rep, Node* base) { 675 Node* CodeStubAssembler::Load(MachineType rep, Node* base) {
740 return raw_assembler_->Load(rep, base); 676 return raw_assembler_->Load(rep, base);
741 } 677 }
742 678
743 Node* CodeStubAssembler::Load(MachineType rep, Node* base, Node* index) { 679 Node* CodeStubAssembler::Load(MachineType rep, Node* base, Node* index) {
744 return raw_assembler_->Load(rep, base, index); 680 return raw_assembler_->Load(rep, base, index);
745 } 681 }
746 682
747 Node* CodeStubAssembler::Store(MachineRepresentation rep, Node* base, 683 Node* CodeStubAssembler::Store(MachineRepresentation rep, Node* base,
748 Node* value) { 684 Node* value) {
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 914 Callable callable = CodeFactory::NonNumberToNumber(isolate());
979 var_value.Bind(CallStub(callable, context, value)); 915 var_value.Bind(CallStub(callable, context, value));
980 Goto(&loop); 916 Goto(&loop);
981 } 917 }
982 } 918 }
983 } 919 }
984 Bind(&done_loop); 920 Bind(&done_loop);
985 return var_result.value(); 921 return var_result.value();
986 } 922 }
987 923
988 Node* CodeStubAssembler::ToThisString(Node* context, Node* value,
989 char const* method_name) {
990 Variable var_value(this, MachineRepresentation::kTagged);
991 var_value.Bind(value);
992
993 // Check if the {value} is a Smi or a HeapObject.
994 Label if_valueissmi(this, Label::kDeferred), if_valueisnotsmi(this),
995 if_valueisstring(this);
996 Branch(WordIsSmi(value), &if_valueissmi, &if_valueisnotsmi);
997 Bind(&if_valueisnotsmi);
998 {
999 // Load the instance type of the {value}.
1000 Node* value_instance_type = LoadInstanceType(value);
1001
1002 // Check if the {value} is already String.
1003 Label if_valueisnotstring(this, Label::kDeferred);
1004 Branch(
1005 Int32LessThan(value_instance_type, Int32Constant(FIRST_NONSTRING_TYPE)),
1006 &if_valueisstring, &if_valueisnotstring);
1007 Bind(&if_valueisnotstring);
1008 {
1009 // Check if the {value} is null.
1010 Label if_valueisnullorundefined(this, Label::kDeferred),
1011 if_valueisnotnullorundefined(this, Label::kDeferred),
1012 if_valueisnotnull(this, Label::kDeferred);
1013 Branch(WordEqual(value, NullConstant()), &if_valueisnullorundefined,
1014 &if_valueisnotnull);
1015 Bind(&if_valueisnotnull);
1016 {
1017 // Check if the {value} is undefined.
1018 Branch(WordEqual(value, UndefinedConstant()),
1019 &if_valueisnullorundefined, &if_valueisnotnullorundefined);
1020 Bind(&if_valueisnotnullorundefined);
1021 {
1022 // Convert the {value} to a String.
1023 Callable callable = CodeFactory::ToString(isolate());
1024 var_value.Bind(CallStub(callable, context, value));
1025 Goto(&if_valueisstring);
1026 }
1027 }
1028
1029 Bind(&if_valueisnullorundefined);
1030 {
1031 // The {value} is either null or undefined.
1032 CallRuntime(Runtime::kThrowCalledOnNullOrUndefined, context,
1033 HeapConstant(factory()->NewStringFromAsciiChecked(
1034 "String.prototype.charCodeAt", TENURED)));
1035 Goto(&if_valueisstring); // Never reached.
1036 }
1037 }
1038 }
1039 Bind(&if_valueissmi);
1040 {
1041 // The {value} is a Smi, convert it to a String.
1042 Callable callable = CodeFactory::NumberToString(isolate());
1043 var_value.Bind(CallStub(callable, context, value));
1044 Goto(&if_valueisstring);
1045 }
1046 Bind(&if_valueisstring);
1047 return var_value.value();
1048 }
1049
1050 Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index) {
1051 // Translate the {index} into a Word.
1052 index = SmiToWord(index);
1053
1054 // We may need to loop in case of cons or sliced strings.
1055 Variable var_index(this, MachineType::PointerRepresentation());
1056 Variable var_result(this, MachineRepresentation::kWord32);
1057 Variable var_string(this, MachineRepresentation::kTagged);
1058 Variable* loop_vars[] = {&var_index, &var_string};
1059 Label done_loop(this, &var_result), loop(this, 2, loop_vars);
1060 var_string.Bind(string);
1061 var_index.Bind(index);
1062 Goto(&loop);
1063 Bind(&loop);
1064 {
1065 // Load the current {index}.
1066 index = var_index.value();
1067
1068 // Load the current {string}.
1069 string = var_string.value();
1070
1071 // Load the instance type of the {string}.
1072 Node* string_instance_type = LoadInstanceType(string);
1073
1074 // Check if the {string} is a SeqString.
1075 Label if_stringissequential(this), if_stringisnotsequential(this);
1076 Branch(Word32Equal(Word32And(string_instance_type,
1077 Int32Constant(kStringRepresentationMask)),
1078 Int32Constant(kSeqStringTag)),
1079 &if_stringissequential, &if_stringisnotsequential);
1080
1081 Bind(&if_stringissequential);
1082 {
1083 // Check if the {string} is a TwoByteSeqString or a OneByteSeqString.
1084 Label if_stringistwobyte(this), if_stringisonebyte(this);
1085 Branch(Word32Equal(Word32And(string_instance_type,
1086 Int32Constant(kStringEncodingMask)),
1087 Int32Constant(kTwoByteStringTag)),
1088 &if_stringistwobyte, &if_stringisonebyte);
1089
1090 Bind(&if_stringisonebyte);
1091 {
1092 var_result.Bind(
1093 Load(MachineType::Uint8(), string,
1094 IntPtrAdd(index, IntPtrConstant(SeqOneByteString::kHeaderSize -
1095 kHeapObjectTag))));
1096 Goto(&done_loop);
1097 }
1098
1099 Bind(&if_stringistwobyte);
1100 {
1101 var_result.Bind(
1102 Load(MachineType::Uint16(), string,
1103 IntPtrAdd(WordShl(index, IntPtrConstant(1)),
1104 IntPtrConstant(SeqTwoByteString::kHeaderSize -
1105 kHeapObjectTag))));
1106 Goto(&done_loop);
1107 }
1108 }
1109
1110 Bind(&if_stringisnotsequential);
1111 {
1112 // Check if the {string} is a ConsString.
1113 Label if_stringiscons(this), if_stringisnotcons(this);
1114 Branch(Word32Equal(Word32And(string_instance_type,
1115 Int32Constant(kStringRepresentationMask)),
1116 Int32Constant(kConsStringTag)),
1117 &if_stringiscons, &if_stringisnotcons);
1118
1119 Bind(&if_stringiscons);
1120 {
1121 // Check whether the right hand side is the empty string (i.e. if
1122 // this is really a flat string in a cons string). If that is not
1123 // the case we flatten the string first.
1124 Label if_rhsisempty(this), if_rhsisnotempty(this, Label::kDeferred);
1125 Node* rhs = LoadObjectField(string, ConsString::kSecondOffset);
1126 Branch(WordEqual(rhs, EmptyStringConstant()), &if_rhsisempty,
1127 &if_rhsisnotempty);
1128
1129 Bind(&if_rhsisempty);
1130 {
1131 // Just operate on the left hand side of the {string}.
1132 var_string.Bind(LoadObjectField(string, ConsString::kFirstOffset));
1133 Goto(&loop);
1134 }
1135
1136 Bind(&if_rhsisnotempty);
1137 {
1138 // Flatten the {string} and lookup in the resulting string.
1139 var_string.Bind(CallRuntime(Runtime::kFlattenString,
1140 NoContextConstant(), string));
1141 Goto(&loop);
1142 }
1143 }
1144
1145 Bind(&if_stringisnotcons);
1146 {
1147 // Check if the {string} is an ExternalString.
1148 Label if_stringisexternal(this), if_stringisnotexternal(this);
1149 Branch(Word32Equal(Word32And(string_instance_type,
1150 Int32Constant(kStringRepresentationMask)),
1151 Int32Constant(kExternalStringTag)),
1152 &if_stringisexternal, &if_stringisnotexternal);
1153
1154 Bind(&if_stringisexternal);
1155 {
1156 // Check if the {string} is a short external string.
1157 Label if_stringisshort(this),
1158 if_stringisnotshort(this, Label::kDeferred);
1159 Branch(Word32Equal(Word32And(string_instance_type,
1160 Int32Constant(kShortExternalStringMask)),
1161 Int32Constant(0)),
1162 &if_stringisshort, &if_stringisnotshort);
1163
1164 Bind(&if_stringisshort);
1165 {
1166 // Load the actual resource data from the {string}.
1167 Node* string_resource_data =
1168 LoadObjectField(string, ExternalString::kResourceDataOffset,
1169 MachineType::Pointer());
1170
1171 // Check if the {string} is a TwoByteExternalString or a
1172 // OneByteExternalString.
1173 Label if_stringistwobyte(this), if_stringisonebyte(this);
1174 Branch(Word32Equal(Word32And(string_instance_type,
1175 Int32Constant(kStringEncodingMask)),
1176 Int32Constant(kTwoByteStringTag)),
1177 &if_stringistwobyte, &if_stringisonebyte);
1178
1179 Bind(&if_stringisonebyte);
1180 {
1181 var_result.Bind(
1182 Load(MachineType::Uint8(), string_resource_data, index));
1183 Goto(&done_loop);
1184 }
1185
1186 Bind(&if_stringistwobyte);
1187 {
1188 var_result.Bind(Load(MachineType::Uint16(), string_resource_data,
1189 WordShl(index, IntPtrConstant(1))));
1190 Goto(&done_loop);
1191 }
1192 }
1193
1194 Bind(&if_stringisnotshort);
1195 {
1196 // The {string} might be compressed, call the runtime.
1197 var_result.Bind(SmiToWord32(
1198 CallRuntime(Runtime::kExternalStringGetChar,
1199 NoContextConstant(), string, SmiTag(index))));
1200 Goto(&done_loop);
1201 }
1202 }
1203
1204 Bind(&if_stringisnotexternal);
1205 {
1206 // The {string} is a SlicedString, continue with its parent.
1207 Node* string_offset =
1208 SmiToWord(LoadObjectField(string, SlicedString::kOffsetOffset));
1209 Node* string_parent =
1210 LoadObjectField(string, SlicedString::kParentOffset);
1211 var_index.Bind(IntPtrAdd(index, string_offset));
1212 var_string.Bind(string_parent);
1213 Goto(&loop);
1214 }
1215 }
1216 }
1217 }
1218
1219 Bind(&done_loop);
1220 return var_result.value();
1221 }
1222
1223 Node* CodeStubAssembler::StringFromCharCode(Node* code) {
1224 Variable var_result(this, MachineRepresentation::kTagged);
1225
1226 // Check if the {code} is a one-byte char code.
1227 Label if_codeisonebyte(this), if_codeistwobyte(this, Label::kDeferred),
1228 if_done(this);
1229 Branch(Int32LessThanOrEqual(code, Int32Constant(String::kMaxOneByteCharCode)),
1230 &if_codeisonebyte, &if_codeistwobyte);
1231 Bind(&if_codeisonebyte);
1232 {
1233 // Load the isolate wide single character string cache.
1234 Node* cache = LoadRoot(Heap::kSingleCharacterStringCacheRootIndex);
1235
1236 // Check if we have an entry for the {code} in the single character string
1237 // cache already.
1238 Label if_entryisundefined(this, Label::kDeferred),
1239 if_entryisnotundefined(this);
1240 Node* entry = LoadFixedArrayElementInt32Index(cache, code);
1241 Branch(WordEqual(entry, UndefinedConstant()), &if_entryisundefined,
1242 &if_entryisnotundefined);
1243
1244 Bind(&if_entryisundefined);
1245 {
1246 // Allocate a new SeqOneByteString for {code} and store it in the {cache}.
1247 Node* result = AllocateSeqOneByteString(1);
1248 StoreNoWriteBarrier(
1249 MachineRepresentation::kWord8, result,
1250 IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag), code);
1251 StoreFixedArrayElementInt32Index(cache, code, result);
1252 var_result.Bind(result);
1253 Goto(&if_done);
1254 }
1255
1256 Bind(&if_entryisnotundefined);
1257 {
1258 // Return the entry from the {cache}.
1259 var_result.Bind(entry);
1260 Goto(&if_done);
1261 }
1262 }
1263
1264 Bind(&if_codeistwobyte);
1265 {
1266 // Allocate a new SeqTwoByteString for {code}.
1267 Node* result = AllocateSeqTwoByteString(1);
1268 StoreNoWriteBarrier(
1269 MachineRepresentation::kWord16, result,
1270 IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), code);
1271 var_result.Bind(result);
1272 Goto(&if_done);
1273 }
1274
1275 Bind(&if_done);
1276 return var_result.value();
1277 }
1278
1279 void CodeStubAssembler::BranchIf(Node* condition, Label* if_true, 924 void CodeStubAssembler::BranchIf(Node* condition, Label* if_true,
1280 Label* if_false) { 925 Label* if_false) {
1281 Label if_condition_is_true(this), if_condition_is_false(this); 926 Label if_condition_is_true(this), if_condition_is_false(this);
1282 Branch(condition, &if_condition_is_true, &if_condition_is_false); 927 Branch(condition, &if_condition_is_true, &if_condition_is_false);
1283 Bind(&if_condition_is_true); 928 Bind(&if_condition_is_true);
1284 Goto(if_true); 929 Goto(if_true);
1285 Bind(&if_condition_is_false); 930 Bind(&if_condition_is_false);
1286 Goto(if_false); 931 Goto(if_false);
1287 } 932 }
1288 933
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1714 } 1359 }
1715 } 1360 }
1716 } 1361 }
1717 1362
1718 bound_ = true; 1363 bound_ = true;
1719 } 1364 }
1720 1365
1721 } // namespace compiler 1366 } // namespace compiler
1722 } // namespace internal 1367 } // namespace internal
1723 } // namespace v8 1368 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/code-stub-assembler.h ('k') | src/js/messages.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698