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

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

Issue 6677076: Merge up to bleeding_edge r7201 to isolates branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/isolates
Patch Set: Fix lint. Created 9 years, 9 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/arm/assembler-arm.cc ('k') | src/arm/codegen-arm.h » ('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 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 618 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 __ b(ne, not_number); 629 __ b(ne, not_number);
630 __ ConvertToInt32(object, 630 __ ConvertToInt32(object,
631 dst, 631 dst,
632 scratch1, 632 scratch1,
633 scratch2, 633 scratch2,
634 double_scratch, 634 double_scratch,
635 &not_in_int32_range); 635 &not_in_int32_range);
636 __ jmp(&done); 636 __ jmp(&done);
637 637
638 __ bind(&not_in_int32_range); 638 __ bind(&not_in_int32_range);
639 __ ldr(scratch2, FieldMemOperand(object, HeapNumber::kExponentOffset)); 639 __ ldr(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset));
640 __ ldr(scratch1, FieldMemOperand(object, HeapNumber::kMantissaOffset)); 640 __ ldr(scratch2, FieldMemOperand(object, HeapNumber::kMantissaOffset));
641 641
642 // Register scratch1 contains mantissa word, scratch2 contains 642 __ EmitOutOfInt32RangeTruncate(dst,
643 // sign, exponent and mantissa. Extract biased exponent into dst. 643 scratch1,
644 __ Ubfx(dst, 644 scratch2,
645 scratch2, 645 scratch3);
646 HeapNumber::kExponentShift,
647 HeapNumber::kExponentBits);
648
649 // Express exponent as delta to 31.
650 __ sub(dst, dst, Operand(HeapNumber::kExponentBias + 31));
651
652 Label normal_exponent;
653 // If the delta is larger than kMantissaBits plus one, all bits
654 // would be shifted away, which means that we can return 0.
655 __ cmp(dst, Operand(HeapNumber::kMantissaBits + 1));
656 __ b(&normal_exponent, lt);
657 __ mov(dst, Operand(0));
658 __ jmp(&done);
659
660 __ bind(&normal_exponent);
661 const int kShiftBase = HeapNumber::kNonMantissaBitsInTopWord - 1;
662 // Calculate shift.
663 __ add(scratch3, dst, Operand(kShiftBase));
664
665 // Put implicit 1 before the mantissa part in scratch2.
666 __ orr(scratch2,
667 scratch2,
668 Operand(1 << HeapNumber::kMantissaBitsInTopWord));
669
670 // Save sign.
671 Register sign = dst;
672 __ and_(sign, scratch2, Operand(HeapNumber::kSignMask));
673
674 // Shift mantisssa bits the correct position in high word.
675 __ mov(scratch2, Operand(scratch2, LSL, scratch3));
676
677 // Replace the shifted bits with bits from the lower mantissa word.
678 Label pos_shift, shift_done;
679 __ rsb(scratch3, scratch3, Operand(32), SetCC);
680 __ b(&pos_shift, ge);
681
682 // Negate scratch3.
683 __ rsb(scratch3, scratch3, Operand(0));
684 __ mov(scratch1, Operand(scratch1, LSL, scratch3));
685 __ jmp(&shift_done);
686
687 __ bind(&pos_shift);
688 __ mov(scratch1, Operand(scratch1, LSR, scratch3));
689
690 __ bind(&shift_done);
691 __ orr(scratch2, scratch2, Operand(scratch1));
692
693 // Restore sign if necessary.
694 __ cmp(sign, Operand(0));
695 __ rsb(dst, scratch2, Operand(0), LeaveCC, ne);
696 __ mov(dst, scratch2, LeaveCC, eq);
697 __ jmp(&done); 646 __ jmp(&done);
698 647
699 __ bind(&is_smi); 648 __ bind(&is_smi);
700 __ SmiUntag(dst, object); 649 __ SmiUntag(dst, object);
701 __ bind(&done); 650 __ bind(&done);
702 } 651 }
703 652
704 653
705 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, 654 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
706 Register object, 655 Register object,
(...skipping 4381 matching lines...) Expand 10 before | Expand all | Expand 10 after
5088 __ mov(r3, Operand(r0, ASR, 2), SetCC); 5037 __ mov(r3, Operand(r0, ASR, 2), SetCC);
5089 __ ldr(r7, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset), ne); 5038 __ ldr(r7, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset), ne);
5090 __ ldr(r7, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset), eq); 5039 __ ldr(r7, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset), eq);
5091 5040
5092 // Check that the irregexp code has been generated for the actual string 5041 // Check that the irregexp code has been generated for the actual string
5093 // encoding. If it has, the field contains a code object otherwise it contains 5042 // encoding. If it has, the field contains a code object otherwise it contains
5094 // the hole. 5043 // the hole.
5095 __ CompareObjectType(r7, r0, r0, CODE_TYPE); 5044 __ CompareObjectType(r7, r0, r0, CODE_TYPE);
5096 __ b(ne, &runtime); 5045 __ b(ne, &runtime);
5097 5046
5098 // r3: encoding of subject string (1 if ascii, 0 if two_byte); 5047 // r3: encoding of subject string (1 if ASCII, 0 if two_byte);
5099 // r7: code 5048 // r7: code
5100 // subject: Subject string 5049 // subject: Subject string
5101 // regexp_data: RegExp data (FixedArray) 5050 // regexp_data: RegExp data (FixedArray)
5102 // Load used arguments before starting to push arguments for call to native 5051 // Load used arguments before starting to push arguments for call to native
5103 // RegExp code to avoid handling changing stack height. 5052 // RegExp code to avoid handling changing stack height.
5104 __ ldr(r1, MemOperand(sp, kPreviousIndexOffset)); 5053 __ ldr(r1, MemOperand(sp, kPreviousIndexOffset));
5105 __ mov(r1, Operand(r1, ASR, kSmiTagSize)); 5054 __ mov(r1, Operand(r1, ASR, kSmiTagSize));
5106 5055
5107 // r1: previous index 5056 // r1: previous index
5108 // r3: encoding of subject string (1 if ascii, 0 if two_byte); 5057 // r3: encoding of subject string (1 if ASCII, 0 if two_byte);
5109 // r7: code 5058 // r7: code
5110 // subject: Subject string 5059 // subject: Subject string
5111 // regexp_data: RegExp data (FixedArray) 5060 // regexp_data: RegExp data (FixedArray)
5112 // All checks done. Now push arguments for native regexp code. 5061 // All checks done. Now push arguments for native regexp code.
5113 __ IncrementCounter(COUNTERS->regexp_entry_native(), 1, r0, r2); 5062 __ IncrementCounter(COUNTERS->regexp_entry_native(), 1, r0, r2);
5114 5063
5115 // Isolates: note we add an additional parameter here (isolate pointer). 5064 // Isolates: note we add an additional parameter here (isolate pointer).
5116 static const int kRegExpExecuteArguments = 8; 5065 static const int kRegExpExecuteArguments = 8;
5117 static const int kParameterRegisters = 4; 5066 static const int kParameterRegisters = 4;
5118 __ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters); 5067 __ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
5637 // Fast case of Heap::LookupSingleCharacterStringFromCode. 5586 // Fast case of Heap::LookupSingleCharacterStringFromCode.
5638 STATIC_ASSERT(kSmiTag == 0); 5587 STATIC_ASSERT(kSmiTag == 0);
5639 STATIC_ASSERT(kSmiShiftSize == 0); 5588 STATIC_ASSERT(kSmiShiftSize == 0);
5640 ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1)); 5589 ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1));
5641 __ tst(code_, 5590 __ tst(code_,
5642 Operand(kSmiTagMask | 5591 Operand(kSmiTagMask |
5643 ((~String::kMaxAsciiCharCode) << kSmiTagSize))); 5592 ((~String::kMaxAsciiCharCode) << kSmiTagSize)));
5644 __ b(ne, &slow_case_); 5593 __ b(ne, &slow_case_);
5645 5594
5646 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex); 5595 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
5647 // At this point code register contains smi tagged ascii char code. 5596 // At this point code register contains smi tagged ASCII char code.
5648 STATIC_ASSERT(kSmiTag == 0); 5597 STATIC_ASSERT(kSmiTag == 0);
5649 __ add(result_, result_, Operand(code_, LSL, kPointerSizeLog2 - kSmiTagSize)); 5598 __ add(result_, result_, Operand(code_, LSL, kPointerSizeLog2 - kSmiTagSize));
5650 __ ldr(result_, FieldMemOperand(result_, FixedArray::kHeaderSize)); 5599 __ ldr(result_, FieldMemOperand(result_, FixedArray::kHeaderSize));
5651 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 5600 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
5652 __ cmp(result_, Operand(ip)); 5601 __ cmp(result_, Operand(ip));
5653 __ b(eq, &slow_case_); 5602 __ b(eq, &slow_case_);
5654 __ bind(&exit_); 5603 __ bind(&exit_);
5655 } 5604 }
5656 5605
5657 5606
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
5969 __ orr(chars, chars, Operand(c2, LSL, kBitsPerByte)); 5918 __ orr(chars, chars, Operand(c2, LSL, kBitsPerByte));
5970 5919
5971 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 5920 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
5972 // hash: hash of two character string. 5921 // hash: hash of two character string.
5973 5922
5974 // Load symbol table 5923 // Load symbol table
5975 // Load address of first element of the symbol table. 5924 // Load address of first element of the symbol table.
5976 Register symbol_table = c2; 5925 Register symbol_table = c2;
5977 __ LoadRoot(symbol_table, Heap::kSymbolTableRootIndex); 5926 __ LoadRoot(symbol_table, Heap::kSymbolTableRootIndex);
5978 5927
5979 // Load undefined value
5980 Register undefined = scratch4; 5928 Register undefined = scratch4;
5981 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex); 5929 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex);
5982 5930
5983 // Calculate capacity mask from the symbol table capacity. 5931 // Calculate capacity mask from the symbol table capacity.
5984 Register mask = scratch2; 5932 Register mask = scratch2;
5985 __ ldr(mask, FieldMemOperand(symbol_table, SymbolTable::kCapacityOffset)); 5933 __ ldr(mask, FieldMemOperand(symbol_table, SymbolTable::kCapacityOffset));
5986 __ mov(mask, Operand(mask, ASR, 1)); 5934 __ mov(mask, Operand(mask, ASR, 1));
5987 __ sub(mask, mask, Operand(1)); 5935 __ sub(mask, mask, Operand(1));
5988 5936
5989 // Calculate untagged address of the first element of the symbol table. 5937 // Calculate untagged address of the first element of the symbol table.
5990 Register first_symbol_table_element = symbol_table; 5938 Register first_symbol_table_element = symbol_table;
5991 __ add(first_symbol_table_element, symbol_table, 5939 __ add(first_symbol_table_element, symbol_table,
5992 Operand(SymbolTable::kElementsStartOffset - kHeapObjectTag)); 5940 Operand(SymbolTable::kElementsStartOffset - kHeapObjectTag));
5993 5941
5994 // Registers 5942 // Registers
5995 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 5943 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
5996 // hash: hash of two character string 5944 // hash: hash of two character string
5997 // mask: capacity mask 5945 // mask: capacity mask
5998 // first_symbol_table_element: address of the first element of 5946 // first_symbol_table_element: address of the first element of
5999 // the symbol table 5947 // the symbol table
5948 // undefined: the undefined object
6000 // scratch: - 5949 // scratch: -
6001 5950
6002 // Perform a number of probes in the symbol table. 5951 // Perform a number of probes in the symbol table.
6003 static const int kProbes = 4; 5952 static const int kProbes = 4;
6004 Label found_in_symbol_table; 5953 Label found_in_symbol_table;
6005 Label next_probe[kProbes]; 5954 Label next_probe[kProbes];
6006 for (int i = 0; i < kProbes; i++) { 5955 for (int i = 0; i < kProbes; i++) {
6007 Register candidate = scratch5; // Scratch register contains candidate. 5956 Register candidate = scratch5; // Scratch register contains candidate.
6008 5957
6009 // Calculate entry in symbol table. 5958 // Calculate entry in symbol table.
6010 if (i > 0) { 5959 if (i > 0) {
6011 __ add(candidate, hash, Operand(SymbolTable::GetProbeOffset(i))); 5960 __ add(candidate, hash, Operand(SymbolTable::GetProbeOffset(i)));
6012 } else { 5961 } else {
6013 __ mov(candidate, hash); 5962 __ mov(candidate, hash);
6014 } 5963 }
6015 5964
6016 __ and_(candidate, candidate, Operand(mask)); 5965 __ and_(candidate, candidate, Operand(mask));
6017 5966
6018 // Load the entry from the symble table. 5967 // Load the entry from the symble table.
6019 STATIC_ASSERT(SymbolTable::kEntrySize == 1); 5968 STATIC_ASSERT(SymbolTable::kEntrySize == 1);
6020 __ ldr(candidate, 5969 __ ldr(candidate,
6021 MemOperand(first_symbol_table_element, 5970 MemOperand(first_symbol_table_element,
6022 candidate, 5971 candidate,
6023 LSL, 5972 LSL,
6024 kPointerSizeLog2)); 5973 kPointerSizeLog2));
6025 5974
6026 // If entry is undefined no string with this hash can be found. 5975 // If entry is undefined no string with this hash can be found.
6027 __ cmp(candidate, undefined); 5976 Label is_string;
5977 __ CompareObjectType(candidate, scratch, scratch, ODDBALL_TYPE);
5978 __ b(ne, &is_string);
5979
5980 __ cmp(undefined, candidate);
6028 __ b(eq, not_found); 5981 __ b(eq, not_found);
5982 // Must be null (deleted entry).
5983 if (FLAG_debug_code) {
5984 __ LoadRoot(ip, Heap::kNullValueRootIndex);
5985 __ cmp(ip, candidate);
5986 __ Assert(eq, "oddball in symbol table is not undefined or null");
5987 }
5988 __ jmp(&next_probe[i]);
5989
5990 __ bind(&is_string);
5991
5992 // Check that the candidate is a non-external ASCII string. The instance
5993 // type is still in the scratch register from the CompareObjectType
5994 // operation.
5995 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, &next_probe[i]);
6029 5996
6030 // If length is not 2 the string is not a candidate. 5997 // If length is not 2 the string is not a candidate.
6031 __ ldr(scratch, FieldMemOperand(candidate, String::kLengthOffset)); 5998 __ ldr(scratch, FieldMemOperand(candidate, String::kLengthOffset));
6032 __ cmp(scratch, Operand(Smi::FromInt(2))); 5999 __ cmp(scratch, Operand(Smi::FromInt(2)));
6033 __ b(ne, &next_probe[i]); 6000 __ b(ne, &next_probe[i]);
6034 6001
6035 // Check that the candidate is a non-external ascii string.
6036 __ ldr(scratch, FieldMemOperand(candidate, HeapObject::kMapOffset));
6037 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
6038 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch,
6039 &next_probe[i]);
6040
6041 // Check if the two characters match. 6002 // Check if the two characters match.
6042 // Assumes that word load is little endian. 6003 // Assumes that word load is little endian.
6043 __ ldrh(scratch, FieldMemOperand(candidate, SeqAsciiString::kHeaderSize)); 6004 __ ldrh(scratch, FieldMemOperand(candidate, SeqAsciiString::kHeaderSize));
6044 __ cmp(chars, scratch); 6005 __ cmp(chars, scratch);
6045 __ b(eq, &found_in_symbol_table); 6006 __ b(eq, &found_in_symbol_table);
6046 __ bind(&next_probe[i]); 6007 __ bind(&next_probe[i]);
6047 } 6008 }
6048 6009
6049 // No matching 2 character string found by probing. 6010 // No matching 2 character string found by probing.
6050 __ jmp(not_found); 6011 __ jmp(not_found);
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
6186 __ ldr(r4, FieldMemOperand(r5, String::kLengthOffset)); 6147 __ ldr(r4, FieldMemOperand(r5, String::kLengthOffset));
6187 __ cmp(r4, Operand(to)); 6148 __ cmp(r4, Operand(to));
6188 __ b(lt, &runtime); // Fail if to > length. 6149 __ b(lt, &runtime); // Fail if to > length.
6189 to = no_reg; 6150 to = no_reg;
6190 6151
6191 // r1: instance type. 6152 // r1: instance type.
6192 // r2: result string length. 6153 // r2: result string length.
6193 // r3: from index (untaged smi) 6154 // r3: from index (untaged smi)
6194 // r5: string. 6155 // r5: string.
6195 // r7 (a.k.a. from): from offset (smi) 6156 // r7 (a.k.a. from): from offset (smi)
6196 // Check for flat ascii string. 6157 // Check for flat ASCII string.
6197 Label non_ascii_flat; 6158 Label non_ascii_flat;
6198 __ tst(r1, Operand(kStringEncodingMask)); 6159 __ tst(r1, Operand(kStringEncodingMask));
6199 STATIC_ASSERT(kTwoByteStringTag == 0); 6160 STATIC_ASSERT(kTwoByteStringTag == 0);
6200 __ b(eq, &non_ascii_flat); 6161 __ b(eq, &non_ascii_flat);
6201 6162
6202 Label result_longer_than_two; 6163 Label result_longer_than_two;
6203 __ cmp(r2, Operand(2)); 6164 __ cmp(r2, Operand(2));
6204 __ b(gt, &result_longer_than_two); 6165 __ b(gt, &result_longer_than_two);
6205 6166
6206 // Sub string of length 2 requested. 6167 // Sub string of length 2 requested.
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
6362 __ b(ne, &not_same); 6323 __ b(ne, &not_same);
6363 STATIC_ASSERT(EQUAL == 0); 6324 STATIC_ASSERT(EQUAL == 0);
6364 STATIC_ASSERT(kSmiTag == 0); 6325 STATIC_ASSERT(kSmiTag == 0);
6365 __ mov(r0, Operand(Smi::FromInt(EQUAL))); 6326 __ mov(r0, Operand(Smi::FromInt(EQUAL)));
6366 __ IncrementCounter(COUNTERS->string_compare_native(), 1, r1, r2); 6327 __ IncrementCounter(COUNTERS->string_compare_native(), 1, r1, r2);
6367 __ add(sp, sp, Operand(2 * kPointerSize)); 6328 __ add(sp, sp, Operand(2 * kPointerSize));
6368 __ Ret(); 6329 __ Ret();
6369 6330
6370 __ bind(&not_same); 6331 __ bind(&not_same);
6371 6332
6372 // Check that both objects are sequential ascii strings. 6333 // Check that both objects are sequential ASCII strings.
6373 __ JumpIfNotBothSequentialAsciiStrings(r1, r0, r2, r3, &runtime); 6334 __ JumpIfNotBothSequentialAsciiStrings(r1, r0, r2, r3, &runtime);
6374 6335
6375 // Compare flat ascii strings natively. Remove arguments from stack first. 6336 // Compare flat ASCII strings natively. Remove arguments from stack first.
6376 __ IncrementCounter(COUNTERS->string_compare_native(), 1, r2, r3); 6337 __ IncrementCounter(COUNTERS->string_compare_native(), 1, r2, r3);
6377 __ add(sp, sp, Operand(2 * kPointerSize)); 6338 __ add(sp, sp, Operand(2 * kPointerSize));
6378 GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5); 6339 GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5);
6379 6340
6380 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 6341 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
6381 // tagged as a small integer. 6342 // tagged as a small integer.
6382 __ bind(&runtime); 6343 __ bind(&runtime);
6383 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 6344 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
6384 } 6345 }
6385 6346
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
6457 // r1: second string 6418 // r1: second string
6458 // r2: length of first string 6419 // r2: length of first string
6459 // r3: length of second string 6420 // r3: length of second string
6460 // r4: first string instance type (if flags_ == NO_STRING_ADD_FLAGS) 6421 // r4: first string instance type (if flags_ == NO_STRING_ADD_FLAGS)
6461 // r5: second string instance type (if flags_ == NO_STRING_ADD_FLAGS) 6422 // r5: second string instance type (if flags_ == NO_STRING_ADD_FLAGS)
6462 // Look at the length of the result of adding the two strings. 6423 // Look at the length of the result of adding the two strings.
6463 Label string_add_flat_result, longer_than_two; 6424 Label string_add_flat_result, longer_than_two;
6464 // Adding two lengths can't overflow. 6425 // Adding two lengths can't overflow.
6465 STATIC_ASSERT(String::kMaxLength < String::kMaxLength * 2); 6426 STATIC_ASSERT(String::kMaxLength < String::kMaxLength * 2);
6466 __ add(r6, r2, Operand(r3)); 6427 __ add(r6, r2, Operand(r3));
6467 // Use the runtime system when adding two one character strings, as it 6428 // Use the symbol table when adding two one character strings, as it
6468 // contains optimizations for this specific case using the symbol table. 6429 // helps later optimizations to return a symbol here.
6469 __ cmp(r6, Operand(2)); 6430 __ cmp(r6, Operand(2));
6470 __ b(ne, &longer_than_two); 6431 __ b(ne, &longer_than_two);
6471 6432
6472 // Check that both strings are non-external ascii strings. 6433 // Check that both strings are non-external ASCII strings.
6473 if (flags_ != NO_STRING_ADD_FLAGS) { 6434 if (flags_ != NO_STRING_ADD_FLAGS) {
6474 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset)); 6435 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset));
6475 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset)); 6436 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset));
6476 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); 6437 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
6477 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset)); 6438 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset));
6478 } 6439 }
6479 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r4, r5, r6, r7, 6440 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r4, r5, r6, r7,
6480 &string_add_runtime); 6441 &string_add_runtime);
6481 6442
6482 // Get the two characters forming the sub string. 6443 // Get the two characters forming the sub string.
(...skipping 27 matching lines...) Expand all
6510 __ cmp(r6, Operand(String::kMinNonFlatLength)); 6471 __ cmp(r6, Operand(String::kMinNonFlatLength));
6511 __ b(lt, &string_add_flat_result); 6472 __ b(lt, &string_add_flat_result);
6512 // Handle exceptionally long strings in the runtime system. 6473 // Handle exceptionally long strings in the runtime system.
6513 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0); 6474 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0);
6514 ASSERT(IsPowerOf2(String::kMaxLength + 1)); 6475 ASSERT(IsPowerOf2(String::kMaxLength + 1));
6515 // kMaxLength + 1 is representable as shifted literal, kMaxLength is not. 6476 // kMaxLength + 1 is representable as shifted literal, kMaxLength is not.
6516 __ cmp(r6, Operand(String::kMaxLength + 1)); 6477 __ cmp(r6, Operand(String::kMaxLength + 1));
6517 __ b(hs, &string_add_runtime); 6478 __ b(hs, &string_add_runtime);
6518 6479
6519 // If result is not supposed to be flat, allocate a cons string object. 6480 // If result is not supposed to be flat, allocate a cons string object.
6520 // If both strings are ascii the result is an ascii cons string. 6481 // If both strings are ASCII the result is an ASCII cons string.
6521 if (flags_ != NO_STRING_ADD_FLAGS) { 6482 if (flags_ != NO_STRING_ADD_FLAGS) {
6522 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset)); 6483 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset));
6523 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset)); 6484 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset));
6524 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); 6485 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
6525 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset)); 6486 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset));
6526 } 6487 }
6527 Label non_ascii, allocated, ascii_data; 6488 Label non_ascii, allocated, ascii_data;
6528 STATIC_ASSERT(kTwoByteStringTag == 0); 6489 STATIC_ASSERT(kTwoByteStringTag == 0);
6529 __ tst(r4, Operand(kStringEncodingMask)); 6490 __ tst(r4, Operand(kStringEncodingMask));
6530 __ tst(r5, Operand(kStringEncodingMask), ne); 6491 __ tst(r5, Operand(kStringEncodingMask), ne);
6531 __ b(eq, &non_ascii); 6492 __ b(eq, &non_ascii);
6532 6493
6533 // Allocate an ASCII cons string. 6494 // Allocate an ASCII cons string.
6534 __ bind(&ascii_data); 6495 __ bind(&ascii_data);
6535 __ AllocateAsciiConsString(r7, r6, r4, r5, &string_add_runtime); 6496 __ AllocateAsciiConsString(r7, r6, r4, r5, &string_add_runtime);
6536 __ bind(&allocated); 6497 __ bind(&allocated);
6537 // Fill the fields of the cons string. 6498 // Fill the fields of the cons string.
6538 __ str(r0, FieldMemOperand(r7, ConsString::kFirstOffset)); 6499 __ str(r0, FieldMemOperand(r7, ConsString::kFirstOffset));
6539 __ str(r1, FieldMemOperand(r7, ConsString::kSecondOffset)); 6500 __ str(r1, FieldMemOperand(r7, ConsString::kSecondOffset));
6540 __ mov(r0, Operand(r7)); 6501 __ mov(r0, Operand(r7));
6541 __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3); 6502 __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3);
6542 __ add(sp, sp, Operand(2 * kPointerSize)); 6503 __ add(sp, sp, Operand(2 * kPointerSize));
6543 __ Ret(); 6504 __ Ret();
6544 6505
6545 __ bind(&non_ascii); 6506 __ bind(&non_ascii);
6546 // At least one of the strings is two-byte. Check whether it happens 6507 // At least one of the strings is two-byte. Check whether it happens
6547 // to contain only ascii characters. 6508 // to contain only ASCII characters.
6548 // r4: first instance type. 6509 // r4: first instance type.
6549 // r5: second instance type. 6510 // r5: second instance type.
6550 __ tst(r4, Operand(kAsciiDataHintMask)); 6511 __ tst(r4, Operand(kAsciiDataHintMask));
6551 __ tst(r5, Operand(kAsciiDataHintMask), ne); 6512 __ tst(r5, Operand(kAsciiDataHintMask), ne);
6552 __ b(ne, &ascii_data); 6513 __ b(ne, &ascii_data);
6553 __ eor(r4, r4, Operand(r5)); 6514 __ eor(r4, r4, Operand(r5));
6554 STATIC_ASSERT(kAsciiStringTag != 0 && kAsciiDataHintTag != 0); 6515 STATIC_ASSERT(kAsciiStringTag != 0 && kAsciiDataHintTag != 0);
6555 __ and_(r4, r4, Operand(kAsciiStringTag | kAsciiDataHintTag)); 6516 __ and_(r4, r4, Operand(kAsciiStringTag | kAsciiDataHintTag));
6556 __ cmp(r4, Operand(kAsciiStringTag | kAsciiDataHintTag)); 6517 __ cmp(r4, Operand(kAsciiStringTag | kAsciiDataHintTag));
6557 __ b(eq, &ascii_data); 6518 __ b(eq, &ascii_data);
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
6718 __ cmp(scratch2, 6679 __ cmp(scratch2,
6719 Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); 6680 Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
6720 __ b(ne, slow); 6681 __ b(ne, slow);
6721 __ ldr(arg, FieldMemOperand(arg, JSValue::kValueOffset)); 6682 __ ldr(arg, FieldMemOperand(arg, JSValue::kValueOffset));
6722 __ str(arg, MemOperand(sp, stack_offset)); 6683 __ str(arg, MemOperand(sp, stack_offset));
6723 6684
6724 __ bind(&done); 6685 __ bind(&done);
6725 } 6686 }
6726 6687
6727 6688
6728 void StringCharAtStub::Generate(MacroAssembler* masm) {
6729 // Expects two arguments (object, index) on the stack:
6730 // lr: return address
6731 // sp[0]: index
6732 // sp[4]: object
6733 Register object = r1;
6734 Register index = r0;
6735 Register scratch1 = r2;
6736 Register scratch2 = r3;
6737 Register result = r0;
6738
6739 // Get object and index from the stack.
6740 __ pop(index);
6741 __ pop(object);
6742
6743 Label need_conversion;
6744 Label index_out_of_range;
6745 Label done;
6746 StringCharAtGenerator generator(object,
6747 index,
6748 scratch1,
6749 scratch2,
6750 result,
6751 &need_conversion,
6752 &need_conversion,
6753 &index_out_of_range,
6754 STRING_INDEX_IS_NUMBER);
6755 generator.GenerateFast(masm);
6756 __ b(&done);
6757
6758 __ bind(&index_out_of_range);
6759 // When the index is out of range, the spec requires us to return
6760 // the empty string.
6761 __ LoadRoot(result, Heap::kEmptyStringRootIndex);
6762 __ jmp(&done);
6763
6764 __ bind(&need_conversion);
6765 // Move smi zero into the result register, which will trigger
6766 // conversion.
6767 __ mov(result, Operand(Smi::FromInt(0)));
6768 __ b(&done);
6769
6770 StubRuntimeCallHelper call_helper;
6771 generator.GenerateSlow(masm, call_helper);
6772
6773 __ bind(&done);
6774 __ Ret();
6775 }
6776
6777
6778 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { 6689 void ICCompareStub::GenerateSmis(MacroAssembler* masm) {
6779 ASSERT(state_ == CompareIC::SMIS); 6690 ASSERT(state_ == CompareIC::SMIS);
6780 Label miss; 6691 Label miss;
6781 __ orr(r2, r1, r0); 6692 __ orr(r2, r1, r0);
6782 __ tst(r2, Operand(kSmiTagMask)); 6693 __ tst(r2, Operand(kSmiTagMask));
6783 __ b(ne, &miss); 6694 __ b(ne, &miss);
6784 6695
6785 if (GetCondition() == eq) { 6696 if (GetCondition() == eq) {
6786 // For equality we do not care about the sign of the result. 6697 // For equality we do not care about the sign of the result.
6787 __ sub(r0, r0, r1, SetCC); 6698 __ sub(r0, r0, r1, SetCC);
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
6914 __ str(pc, MemOperand(sp, 0)); 6825 __ str(pc, MemOperand(sp, 0));
6915 __ Jump(target); // Call the C++ function. 6826 __ Jump(target); // Call the C++ function.
6916 } 6827 }
6917 6828
6918 6829
6919 #undef __ 6830 #undef __
6920 6831
6921 } } // namespace v8::internal 6832 } } // namespace v8::internal
6922 6833
6923 #endif // V8_TARGET_ARCH_ARM 6834 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.cc ('k') | src/arm/codegen-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698