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

Side by Side Diff: src/arm/code-stubs-arm.cc

Issue 7477045: Tentative implementation of string slices (hidden under the flag --string-slices). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Some more suggested changes. Created 9 years, 3 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 | « no previous file | src/arm/lithium-arm.cc » ('j') | src/ia32/code-stubs-ia32.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 4321 matching lines...) Expand 10 before | Expand all | Expand 10 after
4332 __ cmp(r0, ip); 4332 __ cmp(r0, ip);
4333 __ b(ne, &runtime); 4333 __ b(ne, &runtime);
4334 // Check that the last match info has space for the capture registers and the 4334 // Check that the last match info has space for the capture registers and the
4335 // additional information. 4335 // additional information.
4336 __ ldr(r0, 4336 __ ldr(r0,
4337 FieldMemOperand(last_match_info_elements, FixedArray::kLengthOffset)); 4337 FieldMemOperand(last_match_info_elements, FixedArray::kLengthOffset));
4338 __ add(r2, r2, Operand(RegExpImpl::kLastMatchOverhead)); 4338 __ add(r2, r2, Operand(RegExpImpl::kLastMatchOverhead));
4339 __ cmp(r2, Operand(r0, ASR, kSmiTagSize)); 4339 __ cmp(r2, Operand(r0, ASR, kSmiTagSize));
4340 __ b(gt, &runtime); 4340 __ b(gt, &runtime);
4341 4341
4342 // Reset offset for possibly sliced string.
4343 __ mov(r9, Operand(0));
4342 // subject: Subject string 4344 // subject: Subject string
4343 // regexp_data: RegExp data (FixedArray) 4345 // regexp_data: RegExp data (FixedArray)
4344 // Check the representation and encoding of the subject string. 4346 // Check the representation and encoding of the subject string.
4345 Label seq_string; 4347 Label seq_string;
4346 __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset)); 4348 __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset));
4347 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset)); 4349 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset));
4348 // First check for flat string. 4350 // First check for flat string.
4349 __ tst(r0, Operand(kIsNotStringMask | kStringRepresentationMask)); 4351 __ and_(r1, r0, Operand(kIsNotStringMask | kStringRepresentationMask), SetCC);
4350 STATIC_ASSERT((kStringTag | kSeqStringTag) == 0); 4352 STATIC_ASSERT((kStringTag | kSeqStringTag) == 0);
4351 __ b(eq, &seq_string); 4353 __ b(eq, &seq_string);
4352 4354
4353 // subject: Subject string 4355 // subject: Subject string
4354 // regexp_data: RegExp data (FixedArray) 4356 // regexp_data: RegExp data (FixedArray)
4355 // Check for flat cons string. 4357 // Check for flat cons string or sliced string.
4356 // A flat cons string is a cons string where the second part is the empty 4358 // A flat cons string is a cons string where the second part is the empty
4357 // string. In that case the subject string is just the first part of the cons 4359 // string. In that case the subject string is just the first part of the cons
4358 // string. Also in this case the first part of the cons string is known to be 4360 // string. Also in this case the first part of the cons string is known to be
4359 // a sequential string or an external string. 4361 // a sequential string or an external string.
4360 STATIC_ASSERT(kExternalStringTag !=0); 4362 // In the case of a sliced string its offset has to be taken into account.
4361 STATIC_ASSERT((kConsStringTag & kExternalStringTag) == 0); 4363 Label cons_string, check_encoding;
4362 __ tst(r0, Operand(kIsNotStringMask | kExternalStringTag)); 4364 STATIC_ASSERT((kConsStringTag < kExternalStringTag));
4363 __ b(ne, &runtime); 4365 STATIC_ASSERT((kSlicedStringTag > kExternalStringTag));
4366 __ cmp(r1, Operand(kExternalStringTag));
4367 __ b(lt, &cons_string);
4368 __ b(eq, &runtime);
4369
4370 // String is sliced.
4371 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset));
4372 __ mov(r9, Operand(r9, ASR, kSmiTagSize));
4373 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset));
4374 // r9: offset of sliced string, smi-tagged.
4375 __ jmp(&check_encoding);
4376 // String is a cons string, check whether it is flat.
4377 __ bind(&cons_string);
4364 __ ldr(r0, FieldMemOperand(subject, ConsString::kSecondOffset)); 4378 __ ldr(r0, FieldMemOperand(subject, ConsString::kSecondOffset));
4365 __ LoadRoot(r1, Heap::kEmptyStringRootIndex); 4379 __ LoadRoot(r1, Heap::kEmptyStringRootIndex);
4366 __ cmp(r0, r1); 4380 __ cmp(r0, r1);
4367 __ b(ne, &runtime); 4381 __ b(ne, &runtime);
4368 __ ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset)); 4382 __ ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
4383 // Is first part of cons or parent of slice a flat string?
4384 __ bind(&check_encoding);
4369 __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset)); 4385 __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset));
4370 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset)); 4386 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset));
4371 // Is first part a flat string?
4372 STATIC_ASSERT(kSeqStringTag == 0); 4387 STATIC_ASSERT(kSeqStringTag == 0);
4373 __ tst(r0, Operand(kStringRepresentationMask)); 4388 __ tst(r0, Operand(kStringRepresentationMask));
4374 __ b(ne, &runtime); 4389 __ b(ne, &runtime);
4375
4376 __ bind(&seq_string); 4390 __ bind(&seq_string);
4377 // subject: Subject string 4391 // subject: Subject string
4378 // regexp_data: RegExp data (FixedArray) 4392 // regexp_data: RegExp data (FixedArray)
4379 // r0: Instance type of subject string 4393 // r0: Instance type of subject string
4380 STATIC_ASSERT(4 == kAsciiStringTag); 4394 STATIC_ASSERT(4 == kAsciiStringTag);
4381 STATIC_ASSERT(kTwoByteStringTag == 0); 4395 STATIC_ASSERT(kTwoByteStringTag == 0);
4382 // Find the code object based on the assumptions above. 4396 // Find the code object based on the assumptions above.
4383 __ and_(r0, r0, Operand(kStringEncodingMask)); 4397 __ and_(r0, r0, Operand(kStringEncodingMask));
4384 __ mov(r3, Operand(r0, ASR, 2), SetCC); 4398 __ mov(r3, Operand(r0, ASR, 2), SetCC);
4385 __ ldr(r7, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset), ne); 4399 __ ldr(r7, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset), ne);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
4431 __ add(r0, r0, Operand(r2)); 4445 __ add(r0, r0, Operand(r2));
4432 __ str(r0, MemOperand(sp, 2 * kPointerSize)); 4446 __ str(r0, MemOperand(sp, 2 * kPointerSize));
4433 4447
4434 // Argument 5 (sp[4]): static offsets vector buffer. 4448 // Argument 5 (sp[4]): static offsets vector buffer.
4435 __ mov(r0, 4449 __ mov(r0,
4436 Operand(ExternalReference::address_of_static_offsets_vector(isolate))); 4450 Operand(ExternalReference::address_of_static_offsets_vector(isolate)));
4437 __ str(r0, MemOperand(sp, 1 * kPointerSize)); 4451 __ str(r0, MemOperand(sp, 1 * kPointerSize));
4438 4452
4439 // For arguments 4 and 3 get string length, calculate start of string data and 4453 // For arguments 4 and 3 get string length, calculate start of string data and
4440 // calculate the shift of the index (0 for ASCII and 1 for two byte). 4454 // calculate the shift of the index (0 for ASCII and 1 for two byte).
4441 __ ldr(r0, FieldMemOperand(subject, String::kLengthOffset));
4442 __ mov(r0, Operand(r0, ASR, kSmiTagSize));
4443 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize); 4455 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize);
4444 __ add(r9, subject, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 4456 __ add(r8, subject, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
4445 __ eor(r3, r3, Operand(1)); 4457 __ eor(r3, r3, Operand(1));
4446 // Argument 4 (r3): End of string data 4458 // Load the length from the original subject string from the previous stack
4447 // Argument 3 (r2): Start of string data 4459 // frame. Therefore we have to use fp, which points exactly to two pointer
4460 // sizes below the previous sp. (Because creating a new stack frame pushes
4461 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.)
4462 __ ldr(r0, MemOperand(fp, kSubjectOffset + 2 * kPointerSize));
4463 // If slice offset is not 0, load the length from the original sliced string.
4464 // Argument 4, r3: End of string data
4465 // Argument 3, r2: Start of string data
4466 // Prepare start and end index of the input.
4467 __ add(r9, r8, Operand(r9, LSL, r3));
4448 __ add(r2, r9, Operand(r1, LSL, r3)); 4468 __ add(r2, r9, Operand(r1, LSL, r3));
4449 __ add(r3, r9, Operand(r0, LSL, r3)); 4469
4470 __ ldr(r8, FieldMemOperand(r0, String::kLengthOffset));
4471 __ mov(r8, Operand(r8, ASR, kSmiTagSize));
4472 __ add(r3, r9, Operand(r8, LSL, r3));
4450 4473
4451 // Argument 2 (r1): Previous index. 4474 // Argument 2 (r1): Previous index.
4452 // Already there 4475 // Already there
4453 4476
4454 // Argument 1 (r0): Subject string. 4477 // Argument 1 (r0): Subject string.
4455 __ mov(r0, subject); 4478 // Already there
4456 4479
4457 // Locate the code entry and call it. 4480 // Locate the code entry and call it.
4458 __ add(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag)); 4481 __ add(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag));
4459 DirectCEntryStub stub; 4482 DirectCEntryStub stub;
4460 stub.GenerateCall(masm, r7); 4483 stub.GenerateCall(masm, r7);
4461 4484
4462 __ LeaveExitFrame(false, no_reg); 4485 __ LeaveExitFrame(false, no_reg);
4463 4486
4464 // r0: result 4487 // r0: result
4465 // subject: subject string (callee saved) 4488 // subject: subject string (callee saved)
4466 // regexp_data: RegExp data (callee saved) 4489 // regexp_data: RegExp data (callee saved)
4467 // last_match_info_elements: Last match info elements (callee saved) 4490 // last_match_info_elements: Last match info elements (callee saved)
4468 4491
4469 // Check the result. 4492 // Check the result.
4470 Label success; 4493 Label success;
4471 4494
4472 __ cmp(r0, Operand(NativeRegExpMacroAssembler::SUCCESS)); 4495 __ cmp(subject, Operand(NativeRegExpMacroAssembler::SUCCESS));
4473 __ b(eq, &success); 4496 __ b(eq, &success);
4474 Label failure; 4497 Label failure;
4475 __ cmp(r0, Operand(NativeRegExpMacroAssembler::FAILURE)); 4498 __ cmp(subject, Operand(NativeRegExpMacroAssembler::FAILURE));
4476 __ b(eq, &failure); 4499 __ b(eq, &failure);
4477 __ cmp(r0, Operand(NativeRegExpMacroAssembler::EXCEPTION)); 4500 __ cmp(subject, Operand(NativeRegExpMacroAssembler::EXCEPTION));
4478 // If not exception it can only be retry. Handle that in the runtime system. 4501 // If not exception it can only be retry. Handle that in the runtime system.
4479 __ b(ne, &runtime); 4502 __ b(ne, &runtime);
4480 // Result must now be exception. If there is no pending exception already a 4503 // Result must now be exception. If there is no pending exception already a
4481 // stack overflow (on the backtrack stack) was detected in RegExp code but 4504 // stack overflow (on the backtrack stack) was detected in RegExp code but
4482 // haven't created the exception yet. Handle that in the runtime system. 4505 // haven't created the exception yet. Handle that in the runtime system.
4483 // TODO(592): Rerunning the RegExp to get the stack overflow exception. 4506 // TODO(592): Rerunning the RegExp to get the stack overflow exception.
4484 __ mov(r1, Operand(ExternalReference::the_hole_value_location(isolate))); 4507 __ mov(r1, Operand(ExternalReference::the_hole_value_location(isolate)));
4485 __ ldr(r1, MemOperand(r1, 0)); 4508 __ ldr(r1, MemOperand(r1, 0));
4486 __ mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address, 4509 __ mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address,
4487 isolate))); 4510 isolate)));
4488 __ ldr(r0, MemOperand(r2, 0)); 4511 __ ldr(r0, MemOperand(r2, 0));
4489 __ cmp(r0, r1); 4512 __ cmp(subject, r1);
4490 __ b(eq, &runtime); 4513 __ b(eq, &runtime);
4491 4514
4492 __ str(r1, MemOperand(r2, 0)); // Clear pending exception. 4515 __ str(r1, MemOperand(r2, 0)); // Clear pending exception.
4493 4516
4494 // Check if the exception is a termination. If so, throw as uncatchable. 4517 // Check if the exception is a termination. If so, throw as uncatchable.
4495 __ LoadRoot(ip, Heap::kTerminationExceptionRootIndex); 4518 __ LoadRoot(ip, Heap::kTerminationExceptionRootIndex);
4496 __ cmp(r0, ip); 4519 __ cmp(subject, ip);
4497 Label termination_exception; 4520 Label termination_exception;
4498 __ b(eq, &termination_exception); 4521 __ b(eq, &termination_exception);
4499 4522
4500 __ Throw(r0); // Expects thrown value in r0. 4523 __ Throw(subject); // Expects thrown value in r0.
4501 4524
4502 __ bind(&termination_exception); 4525 __ bind(&termination_exception);
4503 __ ThrowUncatchable(TERMINATION, r0); // Expects thrown value in r0. 4526 __ ThrowUncatchable(TERMINATION, r0); // Expects thrown value in r0.
4504 4527
4505 __ bind(&failure); 4528 __ bind(&failure);
4506 // For failure and exception return null. 4529 // For failure and exception return null.
4507 __ mov(r0, Operand(masm->isolate()->factory()->null_value())); 4530 __ mov(r0, Operand(masm->isolate()->factory()->null_value()));
4508 __ add(sp, sp, Operand(4 * kPointerSize)); 4531 __ add(sp, sp, Operand(4 * kPointerSize));
4509 __ Ret(); 4532 __ Ret();
4510 4533
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
4768 | IncludeNumberCompareField::encode(include_number_compare_) 4791 | IncludeNumberCompareField::encode(include_number_compare_)
4769 | IncludeSmiCompareField::encode(include_smi_compare_); 4792 | IncludeSmiCompareField::encode(include_smi_compare_);
4770 } 4793 }
4771 4794
4772 4795
4773 // StringCharCodeAtGenerator 4796 // StringCharCodeAtGenerator
4774 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 4797 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
4775 Label flat_string; 4798 Label flat_string;
4776 Label ascii_string; 4799 Label ascii_string;
4777 Label got_char_code; 4800 Label got_char_code;
4801 Label sliced_string;
4778 4802
4779 // If the receiver is a smi trigger the non-string case. 4803 // If the receiver is a smi trigger the non-string case.
4780 __ JumpIfSmi(object_, receiver_not_string_); 4804 __ JumpIfSmi(object_, receiver_not_string_);
4781 4805
4782 // Fetch the instance type of the receiver into result register. 4806 // Fetch the instance type of the receiver into result register.
4783 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); 4807 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
4784 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); 4808 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
4785 // If the receiver is not a string trigger the non-string case. 4809 // If the receiver is not a string trigger the non-string case.
4786 __ tst(result_, Operand(kIsNotStringMask)); 4810 __ tst(result_, Operand(kIsNotStringMask));
4787 __ b(ne, receiver_not_string_); 4811 __ b(ne, receiver_not_string_);
4788 4812
4789 // If the index is non-smi trigger the non-smi case. 4813 // If the index is non-smi trigger the non-smi case.
4790 __ JumpIfNotSmi(index_, &index_not_smi_); 4814 __ JumpIfNotSmi(index_, &index_not_smi_);
4791 4815
4792 // Put smi-tagged index into scratch register. 4816 // Put smi-tagged index into scratch register.
4793 __ mov(scratch_, index_); 4817 __ mov(scratch_, index_);
4794 __ bind(&got_smi_index_); 4818 __ bind(&got_smi_index_);
4795 4819
4796 // Check for index out of range. 4820 // Check for index out of range.
4797 __ ldr(ip, FieldMemOperand(object_, String::kLengthOffset)); 4821 __ ldr(ip, FieldMemOperand(object_, String::kLengthOffset));
4798 __ cmp(ip, Operand(scratch_)); 4822 __ cmp(ip, Operand(scratch_));
4799 __ b(ls, index_out_of_range_); 4823 __ b(ls, index_out_of_range_);
4800 4824
4801 // We need special handling for non-flat strings. 4825 // We need special handling for non-flat strings.
4802 STATIC_ASSERT(kSeqStringTag == 0); 4826 STATIC_ASSERT(kSeqStringTag == 0);
4803 __ tst(result_, Operand(kStringRepresentationMask)); 4827 __ tst(result_, Operand(kStringRepresentationMask));
4804 __ b(eq, &flat_string); 4828 __ b(eq, &flat_string);
4805 4829
4806 // Handle non-flat strings. 4830 // Handle non-flat strings.
4807 __ tst(result_, Operand(kIsConsStringMask)); 4831 __ and_(result_, result_, Operand(kStringRepresentationMask));
4832 STATIC_ASSERT((kConsStringTag < kExternalStringTag));
4833 STATIC_ASSERT((kSlicedStringTag > kExternalStringTag));
4834 __ cmp(result_, Operand(kExternalStringTag));
4835 __ b(gt, &sliced_string);
4808 __ b(eq, &call_runtime_); 4836 __ b(eq, &call_runtime_);
4809 4837
4810 // ConsString. 4838 // ConsString.
4811 // Check whether the right hand side is the empty string (i.e. if 4839 // Check whether the right hand side is the empty string (i.e. if
4812 // this is really a flat string in a cons string). If that is not 4840 // this is really a flat string in a cons string). If that is not
4813 // the case we would rather go to the runtime system now to flatten 4841 // the case we would rather go to the runtime system now to flatten
4814 // the string. 4842 // the string.
4843 Label assure_seq_string;
4815 __ ldr(result_, FieldMemOperand(object_, ConsString::kSecondOffset)); 4844 __ ldr(result_, FieldMemOperand(object_, ConsString::kSecondOffset));
4816 __ LoadRoot(ip, Heap::kEmptyStringRootIndex); 4845 __ LoadRoot(ip, Heap::kEmptyStringRootIndex);
4817 __ cmp(result_, Operand(ip)); 4846 __ cmp(result_, Operand(ip));
4818 __ b(ne, &call_runtime_); 4847 __ b(ne, &call_runtime_);
4819 // Get the first of the two strings and load its instance type. 4848 // Get the first of the two strings and load its instance type.
4820 __ ldr(object_, FieldMemOperand(object_, ConsString::kFirstOffset)); 4849 __ ldr(object_, FieldMemOperand(object_, ConsString::kFirstOffset));
4850 __ jmp(&assure_seq_string);
4851
4852 // SlicedString, unpack and add offset.
4853 __ bind(&sliced_string);
4854 __ ldr(result_, FieldMemOperand(object_, SlicedString::kOffsetOffset));
4855 __ add(scratch_, scratch_, result_);
4856 __ ldr(object_, FieldMemOperand(object_, SlicedString::kParentOffset));
4857
4858 // Assure that we are dealing with a sequential string. Go to runtime if not.
4859 __ bind(&assure_seq_string);
4821 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); 4860 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
4822 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); 4861 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
4823 // If the first cons component is also non-flat, then go to runtime. 4862 // Check that parent is not an external string. Go to runtime otherwise.
4824 STATIC_ASSERT(kSeqStringTag == 0); 4863 STATIC_ASSERT(kSeqStringTag == 0);
4825 __ tst(result_, Operand(kStringRepresentationMask)); 4864 __ tst(result_, Operand(kStringRepresentationMask));
4826 __ b(ne, &call_runtime_); 4865 __ b(ne, &call_runtime_);
4827 4866
4828 // Check for 1-byte or 2-byte string. 4867 // Check for 1-byte or 2-byte string.
4829 __ bind(&flat_string); 4868 __ bind(&flat_string);
4830 STATIC_ASSERT(kAsciiStringTag != 0); 4869 STATIC_ASSERT(kAsciiStringTag != 0);
4831 __ tst(result_, Operand(kStringEncodingMask)); 4870 __ tst(result_, Operand(kStringEncodingMask));
4832 __ b(ne, &ascii_string); 4871 __ b(ne, &ascii_string);
4833 4872
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
5393 // 0 <= from <= to <= string.length. 5432 // 0 <= from <= to <= string.length.
5394 // If any of these assumptions fail, we call the runtime system. 5433 // If any of these assumptions fail, we call the runtime system.
5395 5434
5396 static const int kToOffset = 0 * kPointerSize; 5435 static const int kToOffset = 0 * kPointerSize;
5397 static const int kFromOffset = 1 * kPointerSize; 5436 static const int kFromOffset = 1 * kPointerSize;
5398 static const int kStringOffset = 2 * kPointerSize; 5437 static const int kStringOffset = 2 * kPointerSize;
5399 5438
5400 // Check bounds and smi-ness. 5439 // Check bounds and smi-ness.
5401 Register to = r6; 5440 Register to = r6;
5402 Register from = r7; 5441 Register from = r7;
5442
5443 if (FLAG_string_slices) {
5444 __ nop(0); // Jumping as first instruction would crash the code generation.
Vitaly Repeshko 2011/08/26 22:29:05 Is this a bug?
5445 __ jmp(&runtime);
5446 }
5447
5403 __ Ldrd(to, from, MemOperand(sp, kToOffset)); 5448 __ Ldrd(to, from, MemOperand(sp, kToOffset));
5404 STATIC_ASSERT(kFromOffset == kToOffset + 4); 5449 STATIC_ASSERT(kFromOffset == kToOffset + 4);
5405 STATIC_ASSERT(kSmiTag == 0); 5450 STATIC_ASSERT(kSmiTag == 0);
5406 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); 5451 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
5452
5407 // I.e., arithmetic shift right by one un-smi-tags. 5453 // I.e., arithmetic shift right by one un-smi-tags.
5408 __ mov(r2, Operand(to, ASR, 1), SetCC); 5454 __ mov(r2, Operand(to, ASR, 1), SetCC);
5409 __ mov(r3, Operand(from, ASR, 1), SetCC, cc); 5455 __ mov(r3, Operand(from, ASR, 1), SetCC, cc);
5410 // If either to or from had the smi tag bit set, then carry is set now. 5456 // If either to or from had the smi tag bit set, then carry is set now.
5411 __ b(cs, &runtime); // Either "from" or "to" is not a smi. 5457 __ b(cs, &runtime); // Either "from" or "to" is not a smi.
5412 __ b(mi, &runtime); // From is negative. 5458 __ b(mi, &runtime); // From is negative.
5413 5459
5414 // Both to and from are smis. 5460 // Both to and from are smis.
5415
5416 __ sub(r2, r2, Operand(r3), SetCC); 5461 __ sub(r2, r2, Operand(r3), SetCC);
5417 __ b(mi, &runtime); // Fail if from > to. 5462 __ b(mi, &runtime); // Fail if from > to.
5418 // Special handling of sub-strings of length 1 and 2. One character strings 5463 // Special handling of sub-strings of length 1 and 2. One character strings
5419 // are handled in the runtime system (looked up in the single character 5464 // are handled in the runtime system (looked up in the single character
5420 // cache). Two character strings are looked for in the symbol cache. 5465 // cache). Two character strings are looked for in the symbol cache.
5421 __ cmp(r2, Operand(2)); 5466 __ cmp(r2, Operand(2));
5422 __ b(lt, &runtime); 5467 __ b(lt, &runtime);
5423 5468
5424 // r2: length 5469 // r2: length
5425 // r3: from index (untaged smi) 5470 // r3: from index (untaged smi)
(...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after
6535 __ mov(result, Operand(0)); 6580 __ mov(result, Operand(0));
6536 __ Ret(); 6581 __ Ret();
6537 } 6582 }
6538 6583
6539 6584
6540 #undef __ 6585 #undef __
6541 6586
6542 } } // namespace v8::internal 6587 } } // namespace v8::internal
6543 6588
6544 #endif // V8_TARGET_ARCH_ARM 6589 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm/lithium-arm.cc » ('j') | src/ia32/code-stubs-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698