OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |