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

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

Issue 525085: Use generated code to create sub strings (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
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 | Annotate | Revision Log
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/runtime.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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-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 5264 matching lines...) Expand 10 before | Expand all | Expand 10 after
5275 5275
5276 Load(args->at(0)); 5276 Load(args->at(0));
5277 Load(args->at(1)); 5277 Load(args->at(1));
5278 5278
5279 StringAddStub stub(NO_STRING_ADD_FLAGS); 5279 StringAddStub stub(NO_STRING_ADD_FLAGS);
5280 Result answer = frame_->CallStub(&stub, 2); 5280 Result answer = frame_->CallStub(&stub, 2);
5281 frame_->Push(&answer); 5281 frame_->Push(&answer);
5282 } 5282 }
5283 5283
5284 5284
5285 void CodeGenerator::GenerateSubString(ZoneList<Expression*>* args) {
5286 ASSERT_EQ(3, args->length());
5287
5288 Load(args->at(0));
5289 Load(args->at(1));
5290 Load(args->at(2));
5291
5292 SubStringStub stub;
5293 Result answer = frame_->CallStub(&stub, 3);
5294 frame_->Push(&answer);
5295 }
5296
5297
5285 void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) { 5298 void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) {
5286 ASSERT_EQ(args->length(), 4); 5299 ASSERT_EQ(args->length(), 4);
5287 5300
5288 // Load the arguments on the stack and call the stub. 5301 // Load the arguments on the stack and call the stub.
5289 Load(args->at(0)); 5302 Load(args->at(0));
5290 Load(args->at(1)); 5303 Load(args->at(1));
5291 Load(args->at(2)); 5304 Load(args->at(2));
5292 Load(args->at(3)); 5305 Load(args->at(3));
5293 RegExpExecStub stub; 5306 RegExpExecStub stub;
5294 Result result = frame_->CallStub(&stub, 4); 5307 Result result = frame_->CallStub(&stub, 4);
(...skipping 3866 matching lines...) Expand 10 before | Expand all | Expand 10 after
9161 GenerateCopyCharacters(masm, ecx, edx, edi, ebx, false); 9174 GenerateCopyCharacters(masm, ecx, edx, edi, ebx, false);
9162 __ IncrementCounter(&Counters::string_add_native, 1); 9175 __ IncrementCounter(&Counters::string_add_native, 1);
9163 __ ret(2 * kPointerSize); 9176 __ ret(2 * kPointerSize);
9164 9177
9165 // Just jump to runtime to add the two strings. 9178 // Just jump to runtime to add the two strings.
9166 __ bind(&string_add_runtime); 9179 __ bind(&string_add_runtime);
9167 __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1); 9180 __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1);
9168 } 9181 }
9169 9182
9170 9183
9171 void StringAddStub::GenerateCopyCharacters(MacroAssembler* masm, 9184 void StringStubBase::GenerateCopyCharacters(MacroAssembler* masm,
9172 Register dest, 9185 Register dest,
9173 Register src, 9186 Register src,
9174 Register count, 9187 Register count,
9175 Register scratch, 9188 Register scratch,
9176 bool ascii) { 9189 bool ascii) {
9177 Label loop; 9190 Label loop;
9178 __ bind(&loop); 9191 __ bind(&loop);
9179 // This loop just copies one character at a time, as it is only used for very 9192 // This loop just copies one character at a time, as it is only used for very
9180 // short strings. 9193 // short strings.
9181 if (ascii) { 9194 if (ascii) {
9182 __ mov_b(scratch, Operand(src, 0)); 9195 __ mov_b(scratch, Operand(src, 0));
9183 __ mov_b(Operand(dest, 0), scratch); 9196 __ mov_b(Operand(dest, 0), scratch);
9184 __ add(Operand(src), Immediate(1)); 9197 __ add(Operand(src), Immediate(1));
9185 __ add(Operand(dest), Immediate(1)); 9198 __ add(Operand(dest), Immediate(1));
9186 } else { 9199 } else {
9187 __ mov_w(scratch, Operand(src, 0)); 9200 __ mov_w(scratch, Operand(src, 0));
9188 __ mov_w(Operand(dest, 0), scratch); 9201 __ mov_w(Operand(dest, 0), scratch);
9189 __ add(Operand(src), Immediate(2)); 9202 __ add(Operand(src), Immediate(2));
9190 __ add(Operand(dest), Immediate(2)); 9203 __ add(Operand(dest), Immediate(2));
9191 } 9204 }
9192 __ sub(Operand(count), Immediate(1)); 9205 __ sub(Operand(count), Immediate(1));
9193 __ j(not_zero, &loop); 9206 __ j(not_zero, &loop);
9194 } 9207 }
9195 9208
9196 9209
9210 void StringStubBase::GenerateCopyCharactersREP(MacroAssembler* masm,
9211 Register dest,
9212 Register src,
9213 Register count,
9214 Register scratch,
9215 bool ascii) {
9216 // Copy characters using rep movs of doublewords. Align destination on 4 byte
9217 // boundary before starting rep movs. Copy remaining characters after running
9218 // rep movs.
9219 ASSERT(dest.is(edi)); // rep movs destination
9220 ASSERT(src.is(esi)); // rep movs source
9221 ASSERT(count.is(ecx)); // rep movs count
9222 ASSERT(!scratch.is(dest));
9223 ASSERT(!scratch.is(src));
9224 ASSERT(!scratch.is(count));
9225
9226 // Nothing to do for zero characters.
9227 Label done;
9228 __ test(count, Operand(count));
9229 __ j(zero, &done);
9230
9231 // Make count the number of bytes to copy.
9232 if (!ascii) {
9233 __ shl(count, 1);
9234 }
9235
9236 // Don't enter the rep movs if there are less than 4 bytes to copy.
9237 Label last_bytes;
9238 __ test(count, Immediate(~3));
9239 __ j(zero, &last_bytes);
9240
9241 // Copy from edi to esi using rep movs instruction.
9242 __ mov(scratch, count);
9243 __ sar(count, 2); // Number of doublewords to copy.
9244 __ rep_movs();
9245
9246 // Find number of bytes left.
9247 __ mov(count, scratch);
9248 __ and_(count, 3);
9249
9250 // Check if there are more bytes to copy.
9251 __ bind(&last_bytes);
9252 __ test(count, Operand(count));
9253 __ j(zero, &done);
9254
9255 // Copy remaining characters.
9256 Label loop;
9257 __ bind(&loop);
9258 __ mov_b(scratch, Operand(src, 0));
9259 __ mov_b(Operand(dest, 0), scratch);
9260 __ add(Operand(src), Immediate(1));
9261 __ add(Operand(dest), Immediate(1));
9262 __ sub(Operand(count), Immediate(1));
9263 __ j(not_zero, &loop);
9264
9265 __ bind(&done);
9266 }
9267
9268
9269 void SubStringStub::Generate(MacroAssembler* masm) {
9270 Label runtime;
9271
9272 // Stack frame on entry.
9273 // esp[0]: return address
9274 // esp[4]: to
9275 // esp[8]: from
9276 // esp[12]: string
9277
9278 // Make sure first argument is a string.
9279 __ mov(eax, Operand(esp, 3 * kPointerSize));
9280 ASSERT_EQ(0, kSmiTag);
9281 __ test(eax, Immediate(kSmiTagMask));
9282 __ j(zero, &runtime);
9283 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx);
9284 __ j(NegateCondition(is_string), &runtime);
9285
9286 // eax: string
9287 // ebx: instance type
9288 // Calculate length of sub string using the smi values.
9289 __ mov(ecx, Operand(esp, 1 * kPointerSize)); // to
9290 __ test(ecx, Immediate(kSmiTagMask));
9291 __ j(not_zero, &runtime);
9292 __ mov(edx, Operand(esp, 2 * kPointerSize)); // from
9293 __ test(edx, Immediate(kSmiTagMask));
9294 __ j(not_zero, &runtime);
9295 __ sub(ecx, Operand(edx));
9296 // Handle sub-strings of length 2 and less in the runtime system.
9297 __ SmiUntag(ecx); // Result length is no longer smi.
9298 __ cmp(ecx, 2);
9299 __ j(below_equal, &runtime);
9300
9301 // eax: string
9302 // ebx: instance type
9303 // ecx: result string length
9304 // Check for flat ascii string
9305 Label non_ascii_flat;
9306 __ and_(ebx, kStringRepresentationMask | kStringEncodingMask);
9307 __ cmp(ebx, kSeqStringTag | kAsciiStringTag);
9308 __ j(not_equal, &non_ascii_flat);
9309
9310 // Allocate the result.
9311 __ AllocateAsciiString(eax, ecx, ebx, edx, edi, &runtime);
9312
9313 // eax: result string
9314 // ecx: result string length
9315 __ mov(edx, esi); // esi used by following code.
9316 // Locate first character of result.
9317 __ mov(edi, eax);
9318 __ add(Operand(edi), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
9319 // Load string argument and locate character of sub string start.
9320 __ mov(esi, Operand(esp, 3 * kPointerSize));
9321 __ add(Operand(esi), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
9322 __ mov(ebx, Operand(esp, 2 * kPointerSize)); // from
9323 __ SmiUntag(ebx);
9324 __ add(esi, Operand(ebx));
9325
9326 // eax: result string
9327 // ecx: result length
9328 // edx: original value of esi
9329 // edi: first character of result
9330 // esi: character of sub string start
9331 GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, true);
9332 __ mov(esi, edx); // Restore esi.
9333 __ IncrementCounter(&Counters::sub_string_native, 1);
9334 __ ret(3 * kPointerSize);
9335
9336 __ bind(&non_ascii_flat);
9337 // eax: string
9338 // ebx: instance type & kStringRepresentationMask | kStringEncodingMask
9339 // ecx: result string length
9340 // Check for flat two byte string
9341 __ cmp(ebx, kSeqStringTag | kTwoByteStringTag);
9342 __ j(not_equal, &runtime);
9343
9344 // Allocate the result.
9345 __ AllocateTwoByteString(eax, ecx, ebx, edx, edi, &runtime);
9346
9347 // eax: result string
9348 // ecx: result string length
9349 __ mov(edx, esi); // esi used by following code.
9350 // Locate first character of result.
9351 __ mov(edi, eax);
9352 __ add(Operand(edi),
9353 Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
9354 // Load string argument and locate character of sub string start.
9355 __ mov(esi, Operand(esp, 3 * kPointerSize));
9356 __ add(Operand(esi), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
9357 __ mov(ebx, Operand(esp, 2 * kPointerSize)); // from
9358 // As from is a smi it is 2 times the value which matches the size of a two
9359 // byte character.
9360 ASSERT_EQ(0, kSmiTag);
9361 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
9362 __ add(esi, Operand(ebx));
9363
9364 // eax: result string
9365 // ecx: result length
9366 // edx: original value of esi
9367 // edi: first character of result
9368 // esi: character of sub string start
9369 GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, false);
9370 __ mov(esi, edx); // Restore esi.
9371 __ IncrementCounter(&Counters::sub_string_native, 1);
9372 __ ret(3 * kPointerSize);
9373
9374 // Just jump to runtime to create the sub string.
9375 __ bind(&runtime);
9376 __ TailCallRuntime(ExternalReference(Runtime::kSubString), 3, 1);
9377 }
9378
9197 #undef __ 9379 #undef __
9198 9380
9199 } } // namespace v8::internal 9381 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698