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

Side by Side Diff: src/x64/codegen-x64.cc

Issue 555049: Ported SubStringStub to X64. (Closed)
Patch Set: Created 10 years, 11 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/x64/codegen-x64.h ('k') | src/x64/disasm-x64.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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3924 matching lines...) Expand 10 before | Expand all | Expand 10 after
3935 } 3935 }
3936 3936
3937 3937
3938 void CodeGenerator::GenerateSubString(ZoneList<Expression*>* args) { 3938 void CodeGenerator::GenerateSubString(ZoneList<Expression*>* args) {
3939 ASSERT_EQ(3, args->length()); 3939 ASSERT_EQ(3, args->length());
3940 3940
3941 Load(args->at(0)); 3941 Load(args->at(0));
3942 Load(args->at(1)); 3942 Load(args->at(1));
3943 Load(args->at(2)); 3943 Load(args->at(2));
3944 3944
3945 Result answer = frame_->CallRuntime(Runtime::kSubString, 3); 3945 SubStringStub stub;
3946 Result answer = frame_->CallStub(&stub, 3);
3946 frame_->Push(&answer); 3947 frame_->Push(&answer);
3947 } 3948 }
3948 3949
3949 3950
3950 void CodeGenerator::GenerateStringCompare(ZoneList<Expression*>* args) { 3951 void CodeGenerator::GenerateStringCompare(ZoneList<Expression*>* args) {
3951 ASSERT_EQ(2, args->length()); 3952 ASSERT_EQ(2, args->length());
3952 3953
3953 Load(args->at(0)); 3954 Load(args->at(0));
3954 Load(args->at(1)); 3955 Load(args->at(1));
3955 3956
(...skipping 4175 matching lines...) Expand 10 before | Expand all | Expand 10 after
8131 __ movq(rax, rbx); 8132 __ movq(rax, rbx);
8132 __ IncrementCounter(&Counters::string_add_native, 1); 8133 __ IncrementCounter(&Counters::string_add_native, 1);
8133 __ ret(2 * kPointerSize); 8134 __ ret(2 * kPointerSize);
8134 8135
8135 // Just jump to runtime to add the two strings. 8136 // Just jump to runtime to add the two strings.
8136 __ bind(&string_add_runtime); 8137 __ bind(&string_add_runtime);
8137 __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1); 8138 __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1);
8138 } 8139 }
8139 8140
8140 8141
8141 void StringAddStub::GenerateCopyCharacters(MacroAssembler* masm, 8142 void StringStubBase::GenerateCopyCharacters(MacroAssembler* masm,
8142 Register dest, 8143 Register dest,
8143 Register src, 8144 Register src,
8144 Register count, 8145 Register count,
8145 bool ascii) { 8146 bool ascii) {
8146 Label loop; 8147 Label loop;
8147 __ bind(&loop); 8148 __ bind(&loop);
8148 // This loop just copies one character at a time, as it is only used for very 8149 // This loop just copies one character at a time, as it is only used for very
8149 // short strings. 8150 // short strings.
8150 if (ascii) { 8151 if (ascii) {
8151 __ movb(kScratchRegister, Operand(src, 0)); 8152 __ movb(kScratchRegister, Operand(src, 0));
8152 __ movb(Operand(dest, 0), kScratchRegister); 8153 __ movb(Operand(dest, 0), kScratchRegister);
8153 __ addq(src, Immediate(1)); 8154 __ addq(src, Immediate(1));
8154 __ addq(dest, Immediate(1)); 8155 __ addq(dest, Immediate(1));
8155 } else { 8156 } else {
8156 __ movzxwl(kScratchRegister, Operand(src, 0)); 8157 __ movzxwl(kScratchRegister, Operand(src, 0));
8157 __ movw(Operand(dest, 0), kScratchRegister); 8158 __ movw(Operand(dest, 0), kScratchRegister);
8158 __ addq(src, Immediate(2)); 8159 __ addq(src, Immediate(2));
8159 __ addq(dest, Immediate(2)); 8160 __ addq(dest, Immediate(2));
8160 } 8161 }
8161 __ subl(count, Immediate(1)); 8162 __ subl(count, Immediate(1));
8162 __ j(not_zero, &loop); 8163 __ j(not_zero, &loop);
8163 } 8164 }
8164 8165
8165 8166
8167 void StringStubBase::GenerateCopyCharactersREP(MacroAssembler* masm,
8168 Register dest,
8169 Register src,
8170 Register count,
8171 bool ascii) {
8172 // Copy characters using rep movs of doublewords. Align destination on 4 byte
8173 // boundary before starting rep movs. Copy remaining characters after running
8174 // rep movs.
8175 ASSERT(dest.is(rdi)); // rep movs destination
8176 ASSERT(src.is(rsi)); // rep movs source
8177 ASSERT(count.is(rcx)); // rep movs count
8178
8179 // Nothing to do for zero characters.
8180 Label done;
8181 __ testq(count, count);
8182 __ j(zero, &done);
8183
8184 // Make count the number of bytes to copy.
8185 if (!ascii) {
Søren Thygesen Gjesse 2010/01/25 08:31:33 ASSERT(kShortSize == 2);
Lasse Reichstein 2010/01/25 08:47:20 It's not really the size of short ints that matter
8186 __ addq(count, count);
8187 }
8188
8189 // Don't enter the rep movs if there are less than 4 bytes to copy.
8190 Label last_bytes;
8191 __ testq(count, Immediate(~3));
8192 __ j(zero, &last_bytes);
8193
8194 // Copy from edi to esi using rep movs instruction.
8195 __ movq(kScratchRegister, count);
8196 __ sar(count, Immediate(2)); // Number of doublewords to copy.
8197 __ repmovsl();
Søren Thygesen Gjesse 2010/01/25 08:31:33 It is not better to use repmovsq?
Lasse Reichstein 2010/01/25 08:47:20 Probably, since we expect long strings, the tine s
8198
8199 // Find number of bytes left.
8200 __ movq(count, kScratchRegister);
8201 __ and_(count, Immediate(3));
8202
8203 // Check if there are more bytes to copy.
8204 __ bind(&last_bytes);
8205 __ testq(count, count);
8206 __ j(zero, &done);
8207
8208 // Copy remaining characters.
8209 Label loop;
8210 __ bind(&loop);
8211 __ movb(kScratchRegister, Operand(src, 0));
8212 __ movb(Operand(dest, 0), kScratchRegister);
8213 __ addq(src, Immediate(1));
8214 __ addq(dest, Immediate(1));
8215 __ subq(count, Immediate(1));
8216 __ j(not_zero, &loop);
8217
8218 __ bind(&done);
8219 }
8220
8221
8222 void SubStringStub::Generate(MacroAssembler* masm) {
8223 Label runtime;
8224
8225 // Stack frame on entry.
8226 // rsp[0]: return address
8227 // rsp[8]: to
8228 // rsp[16]: from
8229 // rsp[24]: string
8230
8231 const int kToOffset = 1 * kPointerSize;
8232 const int kFromOffset = 2 * kPointerSize;
8233 const int kStringOffset = 3 * kPointerSize;
Søren Thygesen Gjesse 2010/01/25 08:31:33 Now that you have these constants, why not add
Lasse Reichstein 2010/01/25 08:47:20 Done.
8234
8235 // Make sure first argument is a string.
8236 __ movq(rax, Operand(rsp, kStringOffset));
8237 ASSERT_EQ(0, kSmiTag);
8238 __ testl(rax, Immediate(kSmiTagMask));
8239 __ j(zero, &runtime);
8240 Condition is_string = masm->IsObjectStringType(rax, rbx, rbx);
8241 __ j(NegateCondition(is_string), &runtime);
8242
8243 // rax: string
8244 // rbx: instance type
8245 // Calculate length of sub string using the smi values.
8246 __ movq(rcx, Operand(rsp, kToOffset));
8247 __ movq(rdx, Operand(rsp, kFromOffset));
8248 __ JumpIfNotBothPositiveSmi(rcx, rdx, &runtime);
8249
8250 __ SmiSub(rcx, rcx, rdx, NULL); // Overflow doesn't happen.
8251 __ j(negative, &runtime);
8252 // Handle sub-strings of length 2 and less in the runtime system.
8253 __ SmiToInteger32(rcx, rcx);
8254 __ cmpl(rcx, Immediate(2));
8255 __ j(below_equal, &runtime);
8256
8257 // rax: string
8258 // rbx: instance type
8259 // rcx: result string length
8260 // Check for flat ascii string
8261 Label non_ascii_flat;
8262 __ and_(rbx, Immediate(kStringRepresentationMask | kStringEncodingMask));
8263 __ cmpb(rbx, Immediate(kSeqStringTag | kAsciiStringTag));
8264 __ j(not_equal, &non_ascii_flat);
8265
8266 // Allocate the result.
8267 __ AllocateAsciiString(rax, rcx, rbx, rdx, rdi, &runtime);
8268
8269 // rax: result string
8270 // rcx: result string length
8271 __ movq(rdx, rsi); // esi used by following code.
8272 // Locate first character of result.
8273 __ lea(rdi, FieldOperand(rax, SeqAsciiString::kHeaderSize));
8274 // Load string argument and locate character of sub string start.
8275 __ movq(rsi, Operand(rsp, kStringOffset));
8276 __ movq(rbx, Operand(rsp, kFromOffset));
8277 {
8278 SmiIndex smi_as_index = masm->SmiToIndex(rbx, rbx, times_1);
8279 __ lea(rsi, Operand(rsi, smi_as_index.reg, smi_as_index.scale,
Søren Thygesen Gjesse 2010/01/25 08:31:33 Perhaps use FieldOperand, and remove " - kHeapObje
8280 SeqAsciiString::kHeaderSize - kHeapObjectTag));
8281 }
8282
8283 // rax: result string
8284 // rcx: result length
8285 // rdx: original value of rsi
8286 // rdi: first character of result
8287 // rsi: character of sub string start
8288 GenerateCopyCharactersREP(masm, rdi, rsi, rcx, true);
8289 __ movq(rsi, rdx); // Restore rsi.
8290 __ IncrementCounter(&Counters::sub_string_native, 1);
8291 __ ret(3 * kPointerSize);
8292
8293 __ bind(&non_ascii_flat);
8294 // rax: string
8295 // rbx: instance type & kStringRepresentationMask | kStringEncodingMask
8296 // rcx: result string length
8297 // Check for sequential two byte string
8298 __ cmpb(rbx, Immediate(kSeqStringTag | kTwoByteStringTag));
8299 __ j(not_equal, &runtime);
8300
8301 // Allocate the result.
8302 __ AllocateTwoByteString(rax, rcx, rbx, rdx, rdi, &runtime);
8303
8304 // rax: result string
8305 // rcx: result string length
8306 __ movq(rdx, rsi); // esi used by following code.
8307 // Locate first character of result.
8308 __ lea(rdi, FieldOperand(rax, SeqTwoByteString::kHeaderSize));
8309 // Load string argument and locate character of sub string start.
8310 __ movq(rsi, Operand(rsp, kStringOffset));
8311 __ movq(rbx, Operand(rsp, kFromOffset));
8312 {
8313 SmiIndex smi_as_index = masm->SmiToIndex(rbx, rbx, times_2);
8314 __ lea(rsi, Operand(rsi, smi_as_index.reg, smi_as_index.scale,
Søren Thygesen Gjesse 2010/01/25 08:31:33 Operand -> FieldOperand?
8315 SeqAsciiString::kHeaderSize - kHeapObjectTag));
8316 }
8317
8318 // rax: result string
8319 // rcx: result length
8320 // rdx: original value of rsi
8321 // rdi: first character of result
8322 // rsi: character of sub string start
8323 GenerateCopyCharactersREP(masm, rdi, rsi, rcx, false);
8324 __ movq(rsi, rdx); // Restore esi.
8325 __ IncrementCounter(&Counters::sub_string_native, 1);
8326 __ ret(3 * kPointerSize);
8327
8328 // Just jump to runtime to create the sub string.
8329 __ bind(&runtime);
8330 __ TailCallRuntime(ExternalReference(Runtime::kSubString), 3, 1);
8331 }
8332
8166 8333
8167 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, 8334 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
8168 Register left, 8335 Register left,
8169 Register right, 8336 Register right,
8170 Register scratch1, 8337 Register scratch1,
8171 Register scratch2, 8338 Register scratch2,
8172 Register scratch3, 8339 Register scratch3,
8173 Register scratch4) { 8340 Register scratch4) {
8174 // Ensure that you can always subtract a string length from a non-negative 8341 // Ensure that you can always subtract a string length from a non-negative
8175 // number (e.g. another length). 8342 // number (e.g. another length).
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
8373 // Call the function from C++. 8540 // Call the function from C++.
8374 return FUNCTION_CAST<ModuloFunction>(buffer); 8541 return FUNCTION_CAST<ModuloFunction>(buffer);
8375 } 8542 }
8376 8543
8377 #endif 8544 #endif
8378 8545
8379 8546
8380 #undef __ 8547 #undef __
8381 8548
8382 } } // namespace v8::internal 8549 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/codegen-x64.h ('k') | src/x64/disasm-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698