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

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

Issue 1868963002: [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
117 Node* CodeStubAssembler::HeapNumberMapConstant() { 121 Node* CodeStubAssembler::HeapNumberMapConstant() {
118 return HeapConstant(isolate()->factory()->heap_number_map()); 122 return HeapConstant(isolate()->factory()->heap_number_map());
119 } 123 }
120 124
125 Node* CodeStubAssembler::NaNConstant() {
126 return LoadRoot(Heap::kNanValueRootIndex);
127 }
128
129 Node* CodeStubAssembler::NoContextConstant() {
130 return SmiConstant(Smi::FromInt(0));
131 }
132
121 Node* CodeStubAssembler::NullConstant() { 133 Node* CodeStubAssembler::NullConstant() {
122 return LoadRoot(Heap::kNullValueRootIndex); 134 return LoadRoot(Heap::kNullValueRootIndex);
123 } 135 }
124 136
125 Node* CodeStubAssembler::UndefinedConstant() { 137 Node* CodeStubAssembler::UndefinedConstant() {
126 return LoadRoot(Heap::kUndefinedValueRootIndex); 138 return LoadRoot(Heap::kUndefinedValueRootIndex);
127 } 139 }
128 140
129 Node* CodeStubAssembler::Parameter(int value) { 141 Node* CodeStubAssembler::Parameter(int value) {
130 return raw_assembler_->Parameter(value); 142 return raw_assembler_->Parameter(value);
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 } 354 }
343 355
344 Node* CodeStubAssembler::SmiTag(Node* value) { 356 Node* CodeStubAssembler::SmiTag(Node* value) {
345 return raw_assembler_->WordShl(value, SmiShiftBitsConstant()); 357 return raw_assembler_->WordShl(value, SmiShiftBitsConstant());
346 } 358 }
347 359
348 Node* CodeStubAssembler::SmiUntag(Node* value) { 360 Node* CodeStubAssembler::SmiUntag(Node* value) {
349 return raw_assembler_->WordSar(value, SmiShiftBitsConstant()); 361 return raw_assembler_->WordSar(value, SmiShiftBitsConstant());
350 } 362 }
351 363
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
352 Node* CodeStubAssembler::SmiToWord32(Node* value) { 371 Node* CodeStubAssembler::SmiToWord32(Node* value) {
353 Node* result = raw_assembler_->WordSar(value, SmiShiftBitsConstant()); 372 Node* result = raw_assembler_->WordSar(value, SmiShiftBitsConstant());
354 if (raw_assembler_->machine()->Is64()) { 373 if (raw_assembler_->machine()->Is64()) {
355 result = raw_assembler_->TruncateInt64ToInt32(result); 374 result = raw_assembler_->TruncateInt64ToInt32(result);
356 } 375 }
357 return result; 376 return result;
358 } 377 }
359 378
360 Node* CodeStubAssembler::SmiToFloat64(Node* value) { 379 Node* CodeStubAssembler::SmiToFloat64(Node* value) {
361 return ChangeInt32ToFloat64(SmiUntag(value)); 380 return ChangeInt32ToFloat64(SmiUntag(value));
362 } 381 }
363 382
364 Node* CodeStubAssembler::SmiAdd(Node* a, Node* b) { return IntPtrAdd(a, b); } 383 Node* CodeStubAssembler::SmiAdd(Node* a, Node* b) { return IntPtrAdd(a, b); }
365 384
366 Node* CodeStubAssembler::SmiAddWithOverflow(Node* a, Node* b) { 385 Node* CodeStubAssembler::SmiAddWithOverflow(Node* a, Node* b) {
367 return IntPtrAddWithOverflow(a, b); 386 return IntPtrAddWithOverflow(a, b);
368 } 387 }
369 388
370 Node* CodeStubAssembler::SmiSub(Node* a, Node* b) { return IntPtrSub(a, b); } 389 Node* CodeStubAssembler::SmiSub(Node* a, Node* b) { return IntPtrSub(a, b); }
371 390
372 Node* CodeStubAssembler::SmiSubWithOverflow(Node* a, Node* b) { 391 Node* CodeStubAssembler::SmiSubWithOverflow(Node* a, Node* b) {
373 return IntPtrSubWithOverflow(a, b); 392 return IntPtrSubWithOverflow(a, b);
374 } 393 }
375 394
376 Node* CodeStubAssembler::SmiEqual(Node* a, Node* b) { return WordEqual(a, b); } 395 Node* CodeStubAssembler::SmiEqual(Node* a, Node* b) { return WordEqual(a, b); }
377 396
397 Node* CodeStubAssembler::SmiAboveOrEqual(Node* a, Node* b) {
398 return UintPtrGreaterThanOrEqual(a, b);
399 }
400
378 Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) { 401 Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) {
379 return IntPtrLessThan(a, b); 402 return IntPtrLessThan(a, b);
380 } 403 }
381 404
382 Node* CodeStubAssembler::SmiLessThanOrEqual(Node* a, Node* b) { 405 Node* CodeStubAssembler::SmiLessThanOrEqual(Node* a, Node* b) {
383 return IntPtrLessThanOrEqual(a, b); 406 return IntPtrLessThanOrEqual(a, b);
384 } 407 }
385 408
386 Node* CodeStubAssembler::SmiMin(Node* a, Node* b) { 409 Node* CodeStubAssembler::SmiMin(Node* a, Node* b) {
387 // TODO(bmeurer): Consider using Select once available. 410 // TODO(bmeurer): Consider using Select once available.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) { 505 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) {
483 return LoadObjectField(map, Map::kDescriptorsOffset); 506 return LoadObjectField(map, Map::kDescriptorsOffset);
484 } 507 }
485 508
486 Node* CodeStubAssembler::LoadNameHash(Node* name) { 509 Node* CodeStubAssembler::LoadNameHash(Node* name) {
487 return Load(MachineType::Uint32(), name, 510 return Load(MachineType::Uint32(), name,
488 IntPtrConstant(Name::kHashFieldOffset - kHeapObjectTag)); 511 IntPtrConstant(Name::kHashFieldOffset - kHeapObjectTag));
489 } 512 }
490 513
491 Node* CodeStubAssembler::LoadFixedArrayElementInt32Index( 514 Node* CodeStubAssembler::LoadFixedArrayElementInt32Index(
492 Node* object, Node* int32_index, int additional_offset) { 515 Node* object, Node* index, int additional_offset) {
493 Node* header_size = IntPtrConstant(additional_offset + 516 Node* header_size = IntPtrConstant(additional_offset +
494 FixedArray::kHeaderSize - kHeapObjectTag); 517 FixedArray::kHeaderSize - kHeapObjectTag);
495 Node* scaled_index = WordShl(int32_index, IntPtrConstant(kPointerSizeLog2)); 518 if (raw_assembler_->machine()->Is64()) {
519 index = ChangeInt32ToInt64(index);
520 }
521 Node* scaled_index = WordShl(index, IntPtrConstant(kPointerSizeLog2));
496 Node* offset = IntPtrAdd(scaled_index, header_size); 522 Node* offset = IntPtrAdd(scaled_index, header_size);
497 return Load(MachineType::AnyTagged(), object, offset); 523 return Load(MachineType::AnyTagged(), object, offset);
498 } 524 }
499 525
500 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) { 526 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) {
501 return Load(MachineType::Uint8(), map, 527 return Load(MachineType::Uint8(), map,
502 IntPtrConstant(Map::kInstanceSizeOffset - kHeapObjectTag)); 528 IntPtrConstant(Map::kInstanceSizeOffset - kHeapObjectTag));
503 } 529 }
504 530
505 Node* CodeStubAssembler::LoadFixedArrayElementSmiIndex(Node* object, 531 Node* CodeStubAssembler::LoadFixedArrayElementSmiIndex(Node* object,
(...skipping 21 matching lines...) Expand all
527 Node* CodeStubAssembler::StoreFixedArrayElementNoWriteBarrier(Node* object, 553 Node* CodeStubAssembler::StoreFixedArrayElementNoWriteBarrier(Node* object,
528 Node* index, 554 Node* index,
529 Node* value) { 555 Node* value) {
530 Node* offset = 556 Node* offset =
531 IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)), 557 IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)),
532 IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag)); 558 IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag));
533 return StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset, 559 return StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset,
534 value); 560 value);
535 } 561 }
536 562
563 Node* CodeStubAssembler::StoreFixedArrayElementInt32Index(Node* object,
564 Node* index,
565 Node* value) {
566 if (raw_assembler_->machine()->Is64()) {
567 index = ChangeInt32ToInt64(index);
568 }
569 Node* offset =
570 IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)),
571 IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag));
572 return Store(MachineRepresentation::kTagged, object, offset, value);
573 }
574
537 Node* CodeStubAssembler::LoadRoot(Heap::RootListIndex root_index) { 575 Node* CodeStubAssembler::LoadRoot(Heap::RootListIndex root_index) {
538 if (isolate()->heap()->RootCanBeTreatedAsConstant(root_index)) { 576 if (isolate()->heap()->RootCanBeTreatedAsConstant(root_index)) {
539 Handle<Object> root = isolate()->heap()->root_handle(root_index); 577 Handle<Object> root = isolate()->heap()->root_handle(root_index);
540 if (root->IsSmi()) { 578 if (root->IsSmi()) {
541 return SmiConstant(Smi::cast(*root)); 579 return SmiConstant(Smi::cast(*root));
542 } else { 580 } else {
543 return HeapConstant(Handle<HeapObject>::cast(root)); 581 return HeapConstant(Handle<HeapObject>::cast(root));
544 } 582 }
545 } 583 }
546 584
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 StoreMapNoWriteBarrier(result, HeapNumberMapConstant()); 718 StoreMapNoWriteBarrier(result, HeapNumberMapConstant());
681 return result; 719 return result;
682 } 720 }
683 721
684 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value) { 722 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value) {
685 Node* result = AllocateHeapNumber(); 723 Node* result = AllocateHeapNumber();
686 StoreHeapNumberValue(result, value); 724 StoreHeapNumberValue(result, value);
687 return result; 725 return result;
688 } 726 }
689 727
728 Node* CodeStubAssembler::AllocateSeqOneByteString(int length) {
729 Node* result = Allocate(SeqOneByteString::SizeFor(length));
730 StoreMapNoWriteBarrier(result, LoadRoot(Heap::kOneByteStringMapRootIndex));
731 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset,
732 SmiConstant(Smi::FromInt(length)));
733 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldOffset,
734 IntPtrConstant(String::kEmptyHashField));
735 return result;
736 }
737
738 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length) {
739 Node* result = Allocate(SeqTwoByteString::SizeFor(length));
740 StoreMapNoWriteBarrier(result, LoadRoot(Heap::kStringMapRootIndex));
741 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset,
742 SmiConstant(Smi::FromInt(length)));
743 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldOffset,
744 IntPtrConstant(String::kEmptyHashField));
745 return result;
746 }
747
690 Node* CodeStubAssembler::Load(MachineType rep, Node* base) { 748 Node* CodeStubAssembler::Load(MachineType rep, Node* base) {
691 return raw_assembler_->Load(rep, base); 749 return raw_assembler_->Load(rep, base);
692 } 750 }
693 751
694 Node* CodeStubAssembler::Load(MachineType rep, Node* base, Node* index) { 752 Node* CodeStubAssembler::Load(MachineType rep, Node* base, Node* index) {
695 return raw_assembler_->Load(rep, base, index); 753 return raw_assembler_->Load(rep, base, index);
696 } 754 }
697 755
698 Node* CodeStubAssembler::Store(MachineRepresentation rep, Node* base, 756 Node* CodeStubAssembler::Store(MachineRepresentation rep, Node* base,
699 Node* value) { 757 Node* value) {
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 987 Callable callable = CodeFactory::NonNumberToNumber(isolate());
930 var_value.Bind(CallStub(callable, context, value)); 988 var_value.Bind(CallStub(callable, context, value));
931 Goto(&loop); 989 Goto(&loop);
932 } 990 }
933 } 991 }
934 } 992 }
935 Bind(&done_loop); 993 Bind(&done_loop);
936 return var_result.value(); 994 return var_result.value();
937 } 995 }
938 996
997 Node* CodeStubAssembler::ToThisString(Node* context, Node* value,
998 char const* method_name) {
999 Variable var_value(this, MachineRepresentation::kTagged);
1000 var_value.Bind(value);
1001
1002 // Check if the {value} is a Smi or a HeapObject.
1003 Label if_valueissmi(this, Label::kDeferred), if_valueisnotsmi(this),
1004 if_valueisstring(this);
1005 Branch(WordIsSmi(value), &if_valueissmi, &if_valueisnotsmi);
1006 Bind(&if_valueisnotsmi);
1007 {
1008 // Load the instance type of the {value}.
1009 Node* value_instance_type = LoadInstanceType(value);
1010
1011 // Check if the {value} is already String.
1012 Label if_valueisnotstring(this, Label::kDeferred);
1013 Branch(
1014 Int32LessThan(value_instance_type, Int32Constant(FIRST_NONSTRING_TYPE)),
1015 &if_valueisstring, &if_valueisnotstring);
1016 Bind(&if_valueisnotstring);
1017 {
1018 // Check if the {value} is null.
1019 Label if_valueisnullorundefined(this, Label::kDeferred),
1020 if_valueisnotnullorundefined(this, Label::kDeferred),
1021 if_valueisnotnull(this, Label::kDeferred);
1022 Branch(WordEqual(value, NullConstant()), &if_valueisnullorundefined,
1023 &if_valueisnotnull);
1024 Bind(&if_valueisnotnull);
1025 {
1026 // Check if the {value} is undefined.
1027 Branch(WordEqual(value, UndefinedConstant()),
1028 &if_valueisnullorundefined, &if_valueisnotnullorundefined);
1029 Bind(&if_valueisnotnullorundefined);
1030 {
1031 // Convert the {value} to a String.
1032 Callable callable = CodeFactory::ToString(isolate());
1033 var_value.Bind(CallStub(callable, context, value));
1034 Goto(&if_valueisstring);
1035 }
1036 }
1037
1038 Bind(&if_valueisnullorundefined);
1039 {
1040 // The {value} is either null or undefined.
1041 CallRuntime(Runtime::kThrowCalledOnNullOrUndefined, context,
1042 HeapConstant(factory()->NewStringFromAsciiChecked(
1043 "String.prototype.charCodeAt", TENURED)));
1044 Goto(&if_valueisstring); // Never reached.
1045 }
1046 }
1047 }
1048 Bind(&if_valueissmi);
1049 {
1050 // The {value} is a Smi, convert it to a String.
1051 Callable callable = CodeFactory::NumberToString(isolate());
1052 var_value.Bind(CallStub(callable, context, value));
1053 Goto(&if_valueisstring);
1054 }
1055 Bind(&if_valueisstring);
1056 return var_value.value();
1057 }
1058
1059 Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index) {
1060 // Translate the {index} into a Word.
1061 index = SmiToWord(index);
1062
1063 // We may need to loop in case of cons or sliced strings.
1064 Variable var_index(this, MachineType::PointerRepresentation());
1065 Variable var_result(this, MachineRepresentation::kWord32);
1066 Variable var_string(this, MachineRepresentation::kTagged);
1067 Variable* loop_vars[] = {&var_index, &var_string};
1068 Label done_loop(this, &var_result), loop(this, 2, loop_vars);
1069 var_string.Bind(string);
1070 var_index.Bind(index);
1071 Goto(&loop);
1072 Bind(&loop);
1073 {
1074 // Load the current {index}.
1075 index = var_index.value();
1076
1077 // Load the current {string}.
1078 string = var_string.value();
1079
1080 // Load the instance type of the {string}.
1081 Node* string_instance_type = LoadInstanceType(string);
1082
1083 // Check if the {string} is a SeqString.
1084 Label if_stringissequential(this), if_stringisnotsequential(this);
1085 Branch(Word32Equal(Word32And(string_instance_type,
1086 Int32Constant(kStringRepresentationMask)),
1087 Int32Constant(kSeqStringTag)),
1088 &if_stringissequential, &if_stringisnotsequential);
1089
1090 Bind(&if_stringissequential);
1091 {
1092 // Check if the {string} is a TwoByteSeqString or a OneByteSeqString.
1093 Label if_stringistwobyte(this), if_stringisonebyte(this);
1094 Branch(Word32Equal(Word32And(string_instance_type,
1095 Int32Constant(kStringEncodingMask)),
1096 Int32Constant(kTwoByteStringTag)),
1097 &if_stringistwobyte, &if_stringisonebyte);
1098
1099 Bind(&if_stringisonebyte);
1100 {
1101 var_result.Bind(
1102 Load(MachineType::Uint8(), string,
1103 IntPtrAdd(index, IntPtrConstant(SeqOneByteString::kHeaderSize -
1104 kHeapObjectTag))));
1105 Goto(&done_loop);
1106 }
1107
1108 Bind(&if_stringistwobyte);
1109 {
1110 var_result.Bind(
1111 Load(MachineType::Uint16(), string,
1112 IntPtrAdd(WordShl(index, IntPtrConstant(1)),
1113 IntPtrConstant(SeqTwoByteString::kHeaderSize -
1114 kHeapObjectTag))));
1115 Goto(&done_loop);
1116 }
1117 }
1118
1119 Bind(&if_stringisnotsequential);
1120 {
1121 // Check if the {string} is a ConsString.
1122 Label if_stringiscons(this), if_stringisnotcons(this);
1123 Branch(Word32Equal(Word32And(string_instance_type,
1124 Int32Constant(kStringRepresentationMask)),
1125 Int32Constant(kConsStringTag)),
1126 &if_stringiscons, &if_stringisnotcons);
1127
1128 Bind(&if_stringiscons);
1129 {
1130 // Check whether the right hand side is the empty string (i.e. if
1131 // this is really a flat string in a cons string). If that is not
1132 // the case we flatten the string first.
1133 Label if_rhsisempty(this), if_rhsisnotempty(this, Label::kDeferred);
1134 Node* rhs = LoadObjectField(string, ConsString::kSecondOffset);
1135 Branch(WordEqual(rhs, EmptyStringConstant()), &if_rhsisempty,
1136 &if_rhsisnotempty);
1137
1138 Bind(&if_rhsisempty);
1139 {
1140 // Just operate on the left hand side of the {string}.
1141 var_string.Bind(LoadObjectField(string, ConsString::kFirstOffset));
1142 Goto(&loop);
1143 }
1144
1145 Bind(&if_rhsisnotempty);
1146 {
1147 // Flatten the {string} and lookup in the resulting string.
1148 var_string.Bind(CallRuntime(Runtime::kFlattenString,
1149 NoContextConstant(), string));
1150 Goto(&loop);
1151 }
1152 }
1153
1154 Bind(&if_stringisnotcons);
1155 {
1156 // Check if the {string} is an ExternalString.
1157 Label if_stringisexternal(this), if_stringisnotexternal(this);
1158 Branch(Word32Equal(Word32And(string_instance_type,
1159 Int32Constant(kStringRepresentationMask)),
1160 Int32Constant(kExternalStringTag)),
1161 &if_stringisexternal, &if_stringisnotexternal);
1162
1163 Bind(&if_stringisexternal);
1164 {
1165 // Check if the {string} is a short external string.
1166 Label if_stringisshort(this),
1167 if_stringisnotshort(this, Label::kDeferred);
1168 Branch(Word32Equal(Word32And(string_instance_type,
1169 Int32Constant(kShortExternalStringMask)),
1170 Int32Constant(0)),
1171 &if_stringisshort, &if_stringisnotshort);
1172
1173 Bind(&if_stringisshort);
1174 {
1175 // Load the actual resource data from the {string}.
1176 Node* string_resource_data =
1177 LoadObjectField(string, ExternalString::kResourceDataOffset,
1178 MachineType::Pointer());
1179
1180 // Check if the {string} is a TwoByteExternalString or a
1181 // OneByteExternalString.
1182 Label if_stringistwobyte(this), if_stringisonebyte(this);
1183 Branch(Word32Equal(Word32And(string_instance_type,
1184 Int32Constant(kStringEncodingMask)),
1185 Int32Constant(kTwoByteStringTag)),
1186 &if_stringistwobyte, &if_stringisonebyte);
1187
1188 Bind(&if_stringisonebyte);
1189 {
1190 var_result.Bind(
1191 Load(MachineType::Uint8(), string_resource_data, index));
1192 Goto(&done_loop);
1193 }
1194
1195 Bind(&if_stringistwobyte);
1196 {
1197 var_result.Bind(Load(MachineType::Uint16(), string_resource_data,
1198 WordShl(index, IntPtrConstant(1))));
1199 Goto(&done_loop);
1200 }
1201 }
1202
1203 Bind(&if_stringisnotshort);
1204 {
1205 // The {string} might be compressed, call the runtime.
1206 var_result.Bind(SmiToWord32(
1207 CallRuntime(Runtime::kExternalStringGetChar,
1208 NoContextConstant(), string, SmiTag(index))));
1209 Goto(&done_loop);
1210 }
1211 }
1212
1213 Bind(&if_stringisnotexternal);
1214 {
1215 // The {string} is a SlicedString, continue with its parent.
1216 Node* string_offset =
1217 SmiToWord(LoadObjectField(string, SlicedString::kOffsetOffset));
1218 Node* string_parent =
1219 LoadObjectField(string, SlicedString::kParentOffset);
1220 var_index.Bind(IntPtrAdd(index, string_offset));
1221 var_string.Bind(string_parent);
1222 Goto(&loop);
1223 }
1224 }
1225 }
1226 }
1227
1228 Bind(&done_loop);
1229 return var_result.value();
1230 }
1231
1232 Node* CodeStubAssembler::StringFromCharCode(Node* code) {
1233 Variable var_result(this, MachineRepresentation::kTagged);
1234
1235 // Check if the {code} is a one-byte char code.
1236 Label if_codeisonebyte(this), if_codeistwobyte(this, Label::kDeferred),
1237 if_done(this);
1238 Branch(Int32LessThanOrEqual(code, Int32Constant(String::kMaxOneByteCharCode)),
1239 &if_codeisonebyte, &if_codeistwobyte);
1240 Bind(&if_codeisonebyte);
1241 {
1242 // Load the isolate wide single character string cache.
1243 Node* cache = LoadRoot(Heap::kSingleCharacterStringCacheRootIndex);
1244
1245 // Check if we have an entry for the {code} in the single character string
1246 // cache already.
1247 Label if_entryisundefined(this, Label::kDeferred),
1248 if_entryisnotundefined(this);
1249 Node* entry = LoadFixedArrayElementInt32Index(cache, code);
1250 Branch(WordEqual(entry, UndefinedConstant()), &if_entryisundefined,
1251 &if_entryisnotundefined);
1252
1253 Bind(&if_entryisundefined);
1254 {
1255 // Allocate a new SeqOneByteString for {code} and store it in the {cache}.
1256 Node* result = AllocateSeqOneByteString(1);
1257 StoreNoWriteBarrier(
1258 MachineRepresentation::kWord8, result,
1259 IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag), code);
1260 StoreFixedArrayElementInt32Index(cache, code, result);
1261 var_result.Bind(result);
1262 Goto(&if_done);
1263 }
1264
1265 Bind(&if_entryisnotundefined);
1266 {
1267 // Allocate a new SeqTwoByteString for {code}.
epertoso 2016/04/07 14:31:10 Is this correct? There's an entry in the cache in
Benedikt Meurer 2016/04/08 04:18:42 Ah, damn copy&paste. It should use the entry obvio
1268 Node* result = AllocateSeqTwoByteString(1);
1269 StoreNoWriteBarrier(
1270 MachineRepresentation::kWord16, result,
1271 IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), code);
1272 var_result.Bind(result);
1273 Goto(&if_done);
1274 }
1275 }
1276
1277 Bind(&if_codeistwobyte);
1278 {
1279 var_result.Bind(CallRuntime(Runtime::kStringCharFromCode,
1280 NoContextConstant(), SmiFromWord32(code)));
1281 Goto(&if_done);
1282 }
1283
1284 Bind(&if_done);
1285 return var_result.value();
1286 }
1287
939 void CodeStubAssembler::BranchIf(Node* condition, Label* if_true, 1288 void CodeStubAssembler::BranchIf(Node* condition, Label* if_true,
940 Label* if_false) { 1289 Label* if_false) {
941 Label if_condition_is_true(this), if_condition_is_false(this); 1290 Label if_condition_is_true(this), if_condition_is_false(this);
942 Branch(condition, &if_condition_is_true, &if_condition_is_false); 1291 Branch(condition, &if_condition_is_true, &if_condition_is_false);
943 Bind(&if_condition_is_true); 1292 Bind(&if_condition_is_true);
944 Goto(if_true); 1293 Goto(if_true);
945 Bind(&if_condition_is_false); 1294 Bind(&if_condition_is_false);
946 Goto(if_false); 1295 Goto(if_false);
947 } 1296 }
948 1297
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 } 1723 }
1375 } 1724 }
1376 } 1725 }
1377 1726
1378 bound_ = true; 1727 bound_ = true;
1379 } 1728 }
1380 1729
1381 } // namespace compiler 1730 } // namespace compiler
1382 } // namespace internal 1731 } // namespace internal
1383 } // namespace v8 1732 } // 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