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

Unified Diff: src/builtins/builtins-string.cc

Issue 2448993002: [turbofan]: Convert StringFromCharCode to var-args style TF builtin (Closed)
Patch Set: Fix comments Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/builtins/builtins.cc ('k') | src/code-factory.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins/builtins-string.cc
diff --git a/src/builtins/builtins-string.cc b/src/builtins/builtins-string.cc
index 7828dd231f1405874ee451211950f874c1562083..f210b8d9b4e666001a000d132a77c4ea35e0b096 100644
--- a/src/builtins/builtins-string.cc
+++ b/src/builtins/builtins-string.cc
@@ -424,181 +424,117 @@ void Builtins::Generate_StringFromCharCode(CodeStubAssembler* assembler) {
typedef compiler::Node Node;
typedef CodeStubAssembler::Variable Variable;
- Node* code = assembler->Parameter(1);
- Node* context = assembler->Parameter(4);
+ Node* argc = assembler->ChangeInt32ToIntPtr(
+ assembler->Parameter(BuiltinDescriptor::kArgumentsCount));
+ Node* context = assembler->Parameter(BuiltinDescriptor::kContext);
+
+ CodeStubArguments arguments(assembler, argc);
// Check if we have exactly one argument (plus the implicit receiver), i.e.
// if the parent frame is not an arguments adaptor frame.
Label if_oneargument(assembler), if_notoneargument(assembler);
- Node* parent_frame_pointer = assembler->LoadParentFramePointer();
- Node* parent_frame_type =
- assembler->Load(MachineType::Pointer(), parent_frame_pointer,
- assembler->IntPtrConstant(
- CommonFrameConstants::kContextOrFrameTypeOffset));
- assembler->Branch(
- assembler->WordEqual(
- parent_frame_type,
- assembler->SmiConstant(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))),
- &if_notoneargument, &if_oneargument);
+ assembler->Branch(assembler->WordEqual(argc, assembler->IntPtrConstant(1)),
+ &if_oneargument, &if_notoneargument);
assembler->Bind(&if_oneargument);
{
// Single argument case, perform fast single character string cache lookup
// for one-byte code units, or fall back to creating a single character
// string on the fly otherwise.
+ Node* code = arguments.AtIndex(0);
Node* code32 = assembler->TruncateTaggedToWord32(context, code);
Node* code16 = assembler->Word32And(
code32, assembler->Int32Constant(String::kMaxUtf16CodeUnit));
Node* result = assembler->StringFromCharCode(code16);
- assembler->Return(result);
+ arguments.PopAndReturn(result);
}
+ Node* code16 = nullptr;
assembler->Bind(&if_notoneargument);
{
- // Determine the resulting string length.
- Node* length = assembler->LoadAndUntagSmi(
- parent_frame_pointer, ArgumentsAdaptorFrameConstants::kLengthOffset);
-
+ Label two_byte(assembler);
// Assume that the resulting string contains only one-byte characters.
- Node* result = assembler->AllocateSeqOneByteString(context, length);
-
- // Truncate all input parameters and append them to the resulting string.
- Variable var_offset(assembler, MachineType::PointerRepresentation());
- Label loop(assembler, &var_offset), done_loop(assembler);
- var_offset.Bind(assembler->IntPtrConstant(0));
- assembler->Goto(&loop);
- assembler->Bind(&loop);
- {
- // Load the current {offset}.
- Node* offset = var_offset.value();
-
- // Check if we're done with the string.
- assembler->GotoIf(assembler->WordEqual(offset, length), &done_loop);
-
- // Load the next code point and truncate it to a 16-bit value.
- Node* code = assembler->Load(
- MachineType::AnyTagged(), parent_frame_pointer,
- assembler->IntPtrAdd(
- assembler->WordShl(assembler->IntPtrSub(length, offset),
- assembler->IntPtrConstant(kPointerSizeLog2)),
- assembler->IntPtrConstant(
- CommonFrameConstants::kFixedFrameSizeAboveFp -
- kPointerSize)));
- Node* code32 = assembler->TruncateTaggedToWord32(context, code);
- Node* code16 = assembler->Word32And(
+ Node* one_byte_result = assembler->AllocateSeqOneByteString(context, argc);
+
+ Variable max_index(assembler, MachineType::PointerRepresentation());
+ max_index.Bind(assembler->IntPtrConstant(0));
+
+ // Iterate over the incoming arguments, converting them to 8-bit character
+ // codes. Stop if any of the conversions generates a code that doesn't fit
+ // in 8 bits.
+ CodeStubAssembler::VariableList vars({&max_index}, assembler->zone());
+ arguments.ForEach(vars, [context, &two_byte, &max_index, &code16,
+ one_byte_result](CodeStubAssembler* assembler,
+ Node* arg) {
+ Node* code32 = assembler->TruncateTaggedToWord32(context, arg);
+ code16 = assembler->Word32And(
code32, assembler->Int32Constant(String::kMaxUtf16CodeUnit));
- // Check if {code16} fits into a one-byte string.
- Label if_codeisonebyte(assembler), if_codeistwobyte(assembler);
- assembler->Branch(
- assembler->Int32LessThanOrEqual(
+ assembler->GotoIf(
+ assembler->Int32GreaterThan(
code16, assembler->Int32Constant(String::kMaxOneByteCharCode)),
- &if_codeisonebyte, &if_codeistwobyte);
-
- assembler->Bind(&if_codeisonebyte);
- {
- // The {code16} fits into the SeqOneByteString {result}.
- assembler->StoreNoWriteBarrier(
- MachineRepresentation::kWord8, result,
- assembler->IntPtrAdd(
- assembler->IntPtrConstant(SeqOneByteString::kHeaderSize -
- kHeapObjectTag),
- offset),
- code16);
- var_offset.Bind(
- assembler->IntPtrAdd(offset, assembler->IntPtrConstant(1)));
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_codeistwobyte);
- {
- // Allocate a SeqTwoByteString to hold the resulting string.
- Node* cresult = assembler->AllocateSeqTwoByteString(context, length);
-
- // Copy all characters that were previously written to the
- // SeqOneByteString in {result} over to the new {cresult}.
- Variable var_coffset(assembler, MachineType::PointerRepresentation());
- Label cloop(assembler, &var_coffset), done_cloop(assembler);
- var_coffset.Bind(assembler->IntPtrConstant(0));
- assembler->Goto(&cloop);
- assembler->Bind(&cloop);
- {
- Node* coffset = var_coffset.value();
- assembler->GotoIf(assembler->WordEqual(coffset, offset), &done_cloop);
- Node* ccode = assembler->Load(
- MachineType::Uint8(), result,
- assembler->IntPtrAdd(
- assembler->IntPtrConstant(SeqOneByteString::kHeaderSize -
- kHeapObjectTag),
- coffset));
- assembler->StoreNoWriteBarrier(
- MachineRepresentation::kWord16, cresult,
- assembler->IntPtrAdd(
- assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize -
- kHeapObjectTag),
- assembler->WordShl(coffset, 1)),
- ccode);
- var_coffset.Bind(
- assembler->IntPtrAdd(coffset, assembler->IntPtrConstant(1)));
- assembler->Goto(&cloop);
- }
+ &two_byte);
+
+ // The {code16} fits into the SeqOneByteString {one_byte_result}.
+ Node* offset = assembler->ElementOffsetFromIndex(
+ max_index.value(), UINT8_ELEMENTS,
+ CodeStubAssembler::INTPTR_PARAMETERS,
+ SeqOneByteString::kHeaderSize - kHeapObjectTag);
+ assembler->StoreNoWriteBarrier(MachineRepresentation::kWord8,
+ one_byte_result, offset, code16);
+ max_index.Bind(assembler->IntPtrAdd(max_index.value(),
+ assembler->IntPtrConstant(1)));
+ });
+ arguments.PopAndReturn(one_byte_result);
+
+ assembler->Bind(&two_byte);
+
+ // At least one of the characters in the string requires a 16-bit
+ // representation. Allocate a SeqTwoByteString to hold the resulting
+ // string.
+ Node* two_byte_result = assembler->AllocateSeqTwoByteString(context, argc);
+
+ // Copy the characters that have already been put in the 8-bit string into
+ // their corresponding positions in the new 16-bit string.
+ Node* zero = assembler->IntPtrConstant(0);
+ assembler->CopyStringCharacters(
+ one_byte_result, two_byte_result, zero, zero, max_index.value(),
+ String::ONE_BYTE_ENCODING, String::TWO_BYTE_ENCODING,
+ CodeStubAssembler::INTPTR_PARAMETERS);
- // Write the pending {code16} to {offset}.
- assembler->Bind(&done_cloop);
- assembler->StoreNoWriteBarrier(
- MachineRepresentation::kWord16, cresult,
- assembler->IntPtrAdd(
- assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize -
- kHeapObjectTag),
- assembler->WordShl(offset, 1)),
- code16);
-
- // Copy the remaining parameters to the SeqTwoByteString {cresult}.
- Label floop(assembler, &var_offset), done_floop(assembler);
- assembler->Goto(&floop);
- assembler->Bind(&floop);
- {
- // Compute the next {offset}.
- Node* offset = assembler->IntPtrAdd(var_offset.value(),
- assembler->IntPtrConstant(1));
-
- // Check if we're done with the string.
- assembler->GotoIf(assembler->WordEqual(offset, length), &done_floop);
-
- // Load the next code point and truncate it to a 16-bit value.
- Node* code = assembler->Load(
- MachineType::AnyTagged(), parent_frame_pointer,
- assembler->IntPtrAdd(
- assembler->WordShl(
- assembler->IntPtrSub(length, offset),
- assembler->IntPtrConstant(kPointerSizeLog2)),
- assembler->IntPtrConstant(
- CommonFrameConstants::kFixedFrameSizeAboveFp -
- kPointerSize)));
- Node* code32 = assembler->TruncateTaggedToWord32(context, code);
+ // Write the character that caused the 8-bit to 16-bit fault.
+ Node* max_index_offset = assembler->ElementOffsetFromIndex(
+ max_index.value(), UINT16_ELEMENTS,
+ CodeStubAssembler::INTPTR_PARAMETERS,
+ SeqTwoByteString::kHeaderSize - kHeapObjectTag);
+ assembler->StoreNoWriteBarrier(MachineRepresentation::kWord16,
+ two_byte_result, max_index_offset, code16);
+ max_index.Bind(
+ assembler->IntPtrAdd(max_index.value(), assembler->IntPtrConstant(1)));
+
+ // Resume copying the passed-in arguments from the same place where the
+ // 8-bit copy stopped, but this time copying over all of the characters
+ // using a 16-bit representation.
+ arguments.ForEach(
+ vars,
+ [context, two_byte_result, &max_index](CodeStubAssembler* assembler,
+ Node* arg) {
+ Node* code32 = assembler->TruncateTaggedToWord32(context, arg);
Node* code16 = assembler->Word32And(
code32, assembler->Int32Constant(String::kMaxUtf16CodeUnit));
- // Store the truncated {code} point at the next offset.
- assembler->StoreNoWriteBarrier(
- MachineRepresentation::kWord16, cresult,
- assembler->IntPtrAdd(
- assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize -
- kHeapObjectTag),
- assembler->WordShl(offset, 1)),
- code16);
- var_offset.Bind(offset);
- assembler->Goto(&floop);
- }
-
- // Return the SeqTwoByteString.
- assembler->Bind(&done_floop);
- assembler->Return(cresult);
- }
- }
-
- assembler->Bind(&done_loop);
- assembler->Return(result);
+ Node* offset = assembler->ElementOffsetFromIndex(
+ max_index.value(), UINT16_ELEMENTS,
+ CodeStubAssembler::INTPTR_PARAMETERS,
+ SeqTwoByteString::kHeaderSize - kHeapObjectTag);
+ assembler->StoreNoWriteBarrier(MachineRepresentation::kWord16,
+ two_byte_result, offset, code16);
+ max_index.Bind(assembler->IntPtrAdd(max_index.value(),
+ assembler->IntPtrConstant(1)));
+ },
+ max_index.value());
+
+ arguments.PopAndReturn(two_byte_result);
}
}
« no previous file with comments | « src/builtins/builtins.cc ('k') | src/code-factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698