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

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

Issue 8913010: Porting r10252 to ARM (handle external strings in generated code when concatenating short strings). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years 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 | no next file » | 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 6122 matching lines...) Expand 10 before | Expand all | Expand 10 after
6133 GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5); 6133 GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5);
6134 6134
6135 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 6135 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
6136 // tagged as a small integer. 6136 // tagged as a small integer.
6137 __ bind(&runtime); 6137 __ bind(&runtime);
6138 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 6138 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
6139 } 6139 }
6140 6140
6141 6141
6142 void StringAddStub::Generate(MacroAssembler* masm) { 6142 void StringAddStub::Generate(MacroAssembler* masm) {
6143 Label string_add_runtime, call_builtin; 6143 Label call_runtime, call_builtin;
6144 Builtins::JavaScript builtin_id = Builtins::ADD; 6144 Builtins::JavaScript builtin_id = Builtins::ADD;
6145 6145
6146 Counters* counters = masm->isolate()->counters(); 6146 Counters* counters = masm->isolate()->counters();
6147 6147
6148 // Stack on entry: 6148 // Stack on entry:
6149 // sp[0]: second argument (right). 6149 // sp[0]: second argument (right).
6150 // sp[4]: first argument (left). 6150 // sp[4]: first argument (left).
6151 6151
6152 // Load the two arguments. 6152 // Load the two arguments.
6153 __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); // First argument. 6153 __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); // First argument.
6154 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); // Second argument. 6154 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); // Second argument.
6155 6155
6156 // Make sure that both arguments are strings if not known in advance. 6156 // Make sure that both arguments are strings if not known in advance.
6157 if (flags_ == NO_STRING_ADD_FLAGS) { 6157 if (flags_ == NO_STRING_ADD_FLAGS) {
6158 __ JumpIfEitherSmi(r0, r1, &string_add_runtime); 6158 __ JumpIfEitherSmi(r0, r1, &call_runtime);
6159 // Load instance types. 6159 // Load instance types.
6160 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset)); 6160 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset));
6161 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset)); 6161 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset));
6162 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); 6162 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
6163 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset)); 6163 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset));
6164 STATIC_ASSERT(kStringTag == 0); 6164 STATIC_ASSERT(kStringTag == 0);
6165 // If either is not a string, go to runtime. 6165 // If either is not a string, go to runtime.
6166 __ tst(r4, Operand(kIsNotStringMask)); 6166 __ tst(r4, Operand(kIsNotStringMask));
6167 __ tst(r5, Operand(kIsNotStringMask), eq); 6167 __ tst(r5, Operand(kIsNotStringMask), eq);
6168 __ b(ne, &string_add_runtime); 6168 __ b(ne, &call_runtime);
6169 } else { 6169 } else {
6170 // Here at least one of the arguments is definitely a string. 6170 // Here at least one of the arguments is definitely a string.
6171 // We convert the one that is not known to be a string. 6171 // We convert the one that is not known to be a string.
6172 if ((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) == 0) { 6172 if ((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) == 0) {
6173 ASSERT((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) != 0); 6173 ASSERT((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) != 0);
6174 GenerateConvertArgument( 6174 GenerateConvertArgument(
6175 masm, 1 * kPointerSize, r0, r2, r3, r4, r5, &call_builtin); 6175 masm, 1 * kPointerSize, r0, r2, r3, r4, r5, &call_builtin);
6176 builtin_id = Builtins::STRING_ADD_RIGHT; 6176 builtin_id = Builtins::STRING_ADD_RIGHT;
6177 } else if ((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) == 0) { 6177 } else if ((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) == 0) {
6178 ASSERT((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) != 0); 6178 ASSERT((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) != 0);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
6227 __ b(ne, &longer_than_two); 6227 __ b(ne, &longer_than_two);
6228 6228
6229 // Check that both strings are non-external ASCII strings. 6229 // Check that both strings are non-external ASCII strings.
6230 if (flags_ != NO_STRING_ADD_FLAGS) { 6230 if (flags_ != NO_STRING_ADD_FLAGS) {
6231 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset)); 6231 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset));
6232 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset)); 6232 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset));
6233 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); 6233 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
6234 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset)); 6234 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset));
6235 } 6235 }
6236 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r4, r5, r6, r7, 6236 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r4, r5, r6, r7,
6237 &string_add_runtime); 6237 &call_runtime);
6238 6238
6239 // Get the two characters forming the sub string. 6239 // Get the two characters forming the sub string.
6240 __ ldrb(r2, FieldMemOperand(r0, SeqAsciiString::kHeaderSize)); 6240 __ ldrb(r2, FieldMemOperand(r0, SeqAsciiString::kHeaderSize));
6241 __ ldrb(r3, FieldMemOperand(r1, SeqAsciiString::kHeaderSize)); 6241 __ ldrb(r3, FieldMemOperand(r1, SeqAsciiString::kHeaderSize));
6242 6242
6243 // Try to lookup two character string in symbol table. If it is not found 6243 // Try to lookup two character string in symbol table. If it is not found
6244 // just allocate a new one. 6244 // just allocate a new one.
6245 Label make_two_character_string; 6245 Label make_two_character_string;
6246 StringHelper::GenerateTwoCharacterSymbolTableProbe( 6246 StringHelper::GenerateTwoCharacterSymbolTableProbe(
6247 masm, r2, r3, r6, r7, r4, r5, r9, &make_two_character_string); 6247 masm, r2, r3, r6, r7, r4, r5, r9, &make_two_character_string);
6248 __ IncrementCounter(counters->string_add_native(), 1, r2, r3); 6248 __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
6249 __ add(sp, sp, Operand(2 * kPointerSize)); 6249 __ add(sp, sp, Operand(2 * kPointerSize));
6250 __ Ret(); 6250 __ Ret();
6251 6251
6252 __ bind(&make_two_character_string); 6252 __ bind(&make_two_character_string);
6253 // Resulting string has length 2 and first chars of two strings 6253 // Resulting string has length 2 and first chars of two strings
6254 // are combined into single halfword in r2 register. 6254 // are combined into single halfword in r2 register.
6255 // So we can fill resulting string without two loops by a single 6255 // So we can fill resulting string without two loops by a single
6256 // halfword store instruction (which assumes that processor is 6256 // halfword store instruction (which assumes that processor is
6257 // in a little endian mode) 6257 // in a little endian mode)
6258 __ mov(r6, Operand(2)); 6258 __ mov(r6, Operand(2));
6259 __ AllocateAsciiString(r0, r6, r4, r5, r9, &string_add_runtime); 6259 __ AllocateAsciiString(r0, r6, r4, r5, r9, &call_runtime);
6260 __ strh(r2, FieldMemOperand(r0, SeqAsciiString::kHeaderSize)); 6260 __ strh(r2, FieldMemOperand(r0, SeqAsciiString::kHeaderSize));
6261 __ IncrementCounter(counters->string_add_native(), 1, r2, r3); 6261 __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
6262 __ add(sp, sp, Operand(2 * kPointerSize)); 6262 __ add(sp, sp, Operand(2 * kPointerSize));
6263 __ Ret(); 6263 __ Ret();
6264 6264
6265 __ bind(&longer_than_two); 6265 __ bind(&longer_than_two);
6266 // Check if resulting string will be flat. 6266 // Check if resulting string will be flat.
6267 __ cmp(r6, Operand(String::kMinNonFlatLength)); 6267 __ cmp(r6, Operand(String::kMinNonFlatLength));
6268 __ b(lt, &string_add_flat_result); 6268 __ b(lt, &string_add_flat_result);
6269 // Handle exceptionally long strings in the runtime system. 6269 // Handle exceptionally long strings in the runtime system.
6270 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0); 6270 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0);
6271 ASSERT(IsPowerOf2(String::kMaxLength + 1)); 6271 ASSERT(IsPowerOf2(String::kMaxLength + 1));
6272 // kMaxLength + 1 is representable as shifted literal, kMaxLength is not. 6272 // kMaxLength + 1 is representable as shifted literal, kMaxLength is not.
6273 __ cmp(r6, Operand(String::kMaxLength + 1)); 6273 __ cmp(r6, Operand(String::kMaxLength + 1));
6274 __ b(hs, &string_add_runtime); 6274 __ b(hs, &call_runtime);
6275 6275
6276 // If result is not supposed to be flat, allocate a cons string object. 6276 // If result is not supposed to be flat, allocate a cons string object.
6277 // If both strings are ASCII the result is an ASCII cons string. 6277 // If both strings are ASCII the result is an ASCII cons string.
6278 if (flags_ != NO_STRING_ADD_FLAGS) { 6278 if (flags_ != NO_STRING_ADD_FLAGS) {
6279 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset)); 6279 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset));
6280 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset)); 6280 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset));
6281 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); 6281 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
6282 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset)); 6282 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset));
6283 } 6283 }
6284 Label non_ascii, allocated, ascii_data; 6284 Label non_ascii, allocated, ascii_data;
6285 STATIC_ASSERT(kTwoByteStringTag == 0); 6285 STATIC_ASSERT(kTwoByteStringTag == 0);
6286 __ tst(r4, Operand(kStringEncodingMask)); 6286 __ tst(r4, Operand(kStringEncodingMask));
6287 __ tst(r5, Operand(kStringEncodingMask), ne); 6287 __ tst(r5, Operand(kStringEncodingMask), ne);
6288 __ b(eq, &non_ascii); 6288 __ b(eq, &non_ascii);
6289 6289
6290 // Allocate an ASCII cons string. 6290 // Allocate an ASCII cons string.
6291 __ bind(&ascii_data); 6291 __ bind(&ascii_data);
6292 __ AllocateAsciiConsString(r7, r6, r4, r5, &string_add_runtime); 6292 __ AllocateAsciiConsString(r7, r6, r4, r5, &call_runtime);
6293 __ bind(&allocated); 6293 __ bind(&allocated);
6294 // Fill the fields of the cons string. 6294 // Fill the fields of the cons string.
6295 __ str(r0, FieldMemOperand(r7, ConsString::kFirstOffset)); 6295 __ str(r0, FieldMemOperand(r7, ConsString::kFirstOffset));
6296 __ str(r1, FieldMemOperand(r7, ConsString::kSecondOffset)); 6296 __ str(r1, FieldMemOperand(r7, ConsString::kSecondOffset));
6297 __ mov(r0, Operand(r7)); 6297 __ mov(r0, Operand(r7));
6298 __ IncrementCounter(counters->string_add_native(), 1, r2, r3); 6298 __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
6299 __ add(sp, sp, Operand(2 * kPointerSize)); 6299 __ add(sp, sp, Operand(2 * kPointerSize));
6300 __ Ret(); 6300 __ Ret();
6301 6301
6302 __ bind(&non_ascii); 6302 __ bind(&non_ascii);
6303 // At least one of the strings is two-byte. Check whether it happens 6303 // At least one of the strings is two-byte. Check whether it happens
6304 // to contain only ASCII characters. 6304 // to contain only ASCII characters.
6305 // r4: first instance type. 6305 // r4: first instance type.
6306 // r5: second instance type. 6306 // r5: second instance type.
6307 __ tst(r4, Operand(kAsciiDataHintMask)); 6307 __ tst(r4, Operand(kAsciiDataHintMask));
6308 __ tst(r5, Operand(kAsciiDataHintMask), ne); 6308 __ tst(r5, Operand(kAsciiDataHintMask), ne);
6309 __ b(ne, &ascii_data); 6309 __ b(ne, &ascii_data);
6310 __ eor(r4, r4, Operand(r5)); 6310 __ eor(r4, r4, Operand(r5));
6311 STATIC_ASSERT(kAsciiStringTag != 0 && kAsciiDataHintTag != 0); 6311 STATIC_ASSERT(kAsciiStringTag != 0 && kAsciiDataHintTag != 0);
6312 __ and_(r4, r4, Operand(kAsciiStringTag | kAsciiDataHintTag)); 6312 __ and_(r4, r4, Operand(kAsciiStringTag | kAsciiDataHintTag));
6313 __ cmp(r4, Operand(kAsciiStringTag | kAsciiDataHintTag)); 6313 __ cmp(r4, Operand(kAsciiStringTag | kAsciiDataHintTag));
6314 __ b(eq, &ascii_data); 6314 __ b(eq, &ascii_data);
6315 6315
6316 // Allocate a two byte cons string. 6316 // Allocate a two byte cons string.
6317 __ AllocateTwoByteConsString(r7, r6, r4, r5, &string_add_runtime); 6317 __ AllocateTwoByteConsString(r7, r6, r4, r5, &call_runtime);
6318 __ jmp(&allocated); 6318 __ jmp(&allocated);
6319 6319
6320 // Handle creating a flat result. First check that both strings are 6320 // We cannot encounter sliced strings or cons strings here since:
6321 // sequential and that they have the same encoding. 6321 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength);
6322 // Handle creating a flat result from either external or sequential strings.
6323 // Locate the first characters' locations.
6322 // r0: first string 6324 // r0: first string
6323 // r1: second string 6325 // r1: second string
6324 // r2: length of first string 6326 // r2: length of first string
6325 // r3: length of second string 6327 // r3: length of second string
6326 // r4: first string instance type (if flags_ == NO_STRING_ADD_FLAGS) 6328 // r4: first string instance type (if flags_ == NO_STRING_ADD_FLAGS)
6327 // r5: second string instance type (if flags_ == NO_STRING_ADD_FLAGS) 6329 // r5: second string instance type (if flags_ == NO_STRING_ADD_FLAGS)
6328 // r6: sum of lengths. 6330 // r6: sum of lengths.
6331 Label first_prepared, second_prepared;
6329 __ bind(&string_add_flat_result); 6332 __ bind(&string_add_flat_result);
6330 if (flags_ != NO_STRING_ADD_FLAGS) { 6333 if (flags_ != NO_STRING_ADD_FLAGS) {
6331 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset)); 6334 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset));
6332 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset)); 6335 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset));
6333 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); 6336 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
6334 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset)); 6337 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset));
6335 } 6338 }
6336 // Check that both strings are sequential. 6339
6340 // Check whether both strings have same encoding
6341 __ eor(r7, r4, Operand(r5));
6342 __ tst(r7, Operand(kStringEncodingMask));
6343 __ b(ne, &call_runtime);
6344
6337 STATIC_ASSERT(kSeqStringTag == 0); 6345 STATIC_ASSERT(kSeqStringTag == 0);
6338 __ tst(r4, Operand(kStringRepresentationMask)); 6346 __ tst(r4, Operand(kStringRepresentationMask));
6339 __ tst(r5, Operand(kStringRepresentationMask), eq); 6347 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize);
6340 __ b(ne, &string_add_runtime); 6348 __ add(r7,
6341 // Now check if both strings have the same encoding (ASCII/Two-byte). 6349 r0,
6342 // r0: first string. 6350 Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag),
6343 // r1: second string. 6351 LeaveCC,
6352 eq);
6353 __ b(eq, &first_prepared);
6354 // External string: rule out short external string and load string resource.
6355 STATIC_ASSERT(kShortExternalStringTag != 0);
6356 __ tst(r4, Operand(kShortExternalStringMask));
6357 __ b(ne, &call_runtime);
6358 __ ldr(r7, FieldMemOperand(r0, ExternalString::kResourceDataOffset));
6359 __ bind(&first_prepared);
6360
6361 STATIC_ASSERT(kSeqStringTag == 0);
6362 __ tst(r5, Operand(kStringRepresentationMask));
6363 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize);
6364 __ add(r1,
6365 r1,
6366 Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag),
6367 LeaveCC,
6368 eq);
6369 __ b(eq, &second_prepared);
6370 // External string: rule out short external string and load string resource.
6371 STATIC_ASSERT(kShortExternalStringTag != 0);
6372 __ tst(r5, Operand(kShortExternalStringMask));
6373 __ b(ne, &call_runtime);
6374 __ ldr(r1, FieldMemOperand(r1, ExternalString::kResourceDataOffset));
6375 __ bind(&second_prepared);
6376
6377 Label non_ascii_string_add_flat_result;
6378 // r7: first character of first string
6379 // r1: first character of second string
6344 // r2: length of first string. 6380 // r2: length of first string.
6345 // r3: length of second string. 6381 // r3: length of second string.
6346 // r6: sum of lengths.. 6382 // r6: sum of lengths.
6347 Label non_ascii_string_add_flat_result; 6383 // Both strings have the same encoding.
6348 ASSERT(IsPowerOf2(kStringEncodingMask)); // Just one bit to test. 6384 STATIC_ASSERT(kTwoByteStringTag == 0);
6349 __ eor(r7, r4, Operand(r5)); 6385 __ tst(r5, Operand(kStringEncodingMask));
6350 __ tst(r7, Operand(kStringEncodingMask));
6351 __ b(ne, &string_add_runtime);
6352 // And see if it's ASCII or two-byte.
6353 __ tst(r4, Operand(kStringEncodingMask));
6354 __ b(eq, &non_ascii_string_add_flat_result); 6386 __ b(eq, &non_ascii_string_add_flat_result);
6355 6387
6356 // Both strings are sequential ASCII strings. We also know that they are 6388 __ AllocateAsciiString(r0, r6, r4, r5, r9, &call_runtime);
6357 // short (since the sum of the lengths is less than kMinNonFlatLength). 6389 __ add(r6, r0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
6358 // r6: length of resulting flat string 6390 // r0: result string.
6359 __ AllocateAsciiString(r7, r6, r4, r5, r9, &string_add_runtime); 6391 // r7: first character of first string.
6360 // Locate first character of result. 6392 // r1: first character of second string.
6361 __ add(r6, r7, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
6362 // Locate first character of first argument.
6363 __ add(r0, r0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
6364 // r0: first character of first string.
6365 // r1: second string.
6366 // r2: length of first string. 6393 // r2: length of first string.
6367 // r3: length of second string. 6394 // r3: length of second string.
6368 // r6: first character of result. 6395 // r6: first character of result.
6369 // r7: result string. 6396 StringHelper::GenerateCopyCharacters(masm, r6, r7, r2, r4, true);
6370 StringHelper::GenerateCopyCharacters(masm, r6, r0, r2, r4, true);
6371
6372 // Load second argument and locate first character.
6373 __ add(r1, r1, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
6374 // r1: first character of second string.
6375 // r3: length of second string.
6376 // r6: next character of result. 6397 // r6: next character of result.
6377 // r7: result string.
6378 StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, true); 6398 StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, true);
6379 __ mov(r0, Operand(r7));
6380 __ IncrementCounter(counters->string_add_native(), 1, r2, r3); 6399 __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
6381 __ add(sp, sp, Operand(2 * kPointerSize)); 6400 __ add(sp, sp, Operand(2 * kPointerSize));
6382 __ Ret(); 6401 __ Ret();
6383 6402
6384 __ bind(&non_ascii_string_add_flat_result); 6403 __ bind(&non_ascii_string_add_flat_result);
6385 // Both strings are sequential two byte strings. 6404 __ AllocateTwoByteString(r0, r6, r4, r5, r9, &call_runtime);
6386 // r0: first string. 6405 __ add(r6, r0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
6387 // r1: second string. 6406 // r0: result string.
6388 // r2: length of first string. 6407 // r7: first character of first string.
6389 // r3: length of second string. 6408 // r1: first character of second string.
6390 // r6: sum of length of strings.
6391 __ AllocateTwoByteString(r7, r6, r4, r5, r9, &string_add_runtime);
6392 // r0: first string.
6393 // r1: second string.
6394 // r2: length of first string.
6395 // r3: length of second string.
6396 // r7: result string.
6397
6398 // Locate first character of result.
6399 __ add(r6, r7, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
6400 // Locate first character of first argument.
6401 __ add(r0, r0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
6402
6403 // r0: first character of first string.
6404 // r1: second string.
6405 // r2: length of first string. 6409 // r2: length of first string.
6406 // r3: length of second string. 6410 // r3: length of second string.
6407 // r6: first character of result. 6411 // r6: first character of result.
6408 // r7: result string. 6412 StringHelper::GenerateCopyCharacters(masm, r6, r7, r2, r4, false);
6409 StringHelper::GenerateCopyCharacters(masm, r6, r0, r2, r4, false); 6413 // r6: next character of result.
6410
6411 // Locate first character of second argument.
6412 __ add(r1, r1, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
6413
6414 // r1: first character of second string.
6415 // r3: length of second string.
6416 // r6: next character of result (after copy of first string).
6417 // r7: result string.
6418 StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, false); 6414 StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, false);
6419
6420 __ mov(r0, Operand(r7));
6421 __ IncrementCounter(counters->string_add_native(), 1, r2, r3); 6415 __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
6422 __ add(sp, sp, Operand(2 * kPointerSize)); 6416 __ add(sp, sp, Operand(2 * kPointerSize));
6423 __ Ret(); 6417 __ Ret();
6424 6418
6425 // Just jump to runtime to add the two strings. 6419 // Just jump to runtime to add the two strings.
6426 __ bind(&string_add_runtime); 6420 __ bind(&call_runtime);
6427 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 6421 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
6428 6422
6429 if (call_builtin.is_linked()) { 6423 if (call_builtin.is_linked()) {
6430 __ bind(&call_builtin); 6424 __ bind(&call_builtin);
6431 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION); 6425 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION);
6432 } 6426 }
6433 } 6427 }
6434 6428
6435 6429
6436 void StringAddStub::GenerateConvertArgument(MacroAssembler* masm, 6430 void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
(...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after
7316 __ StoreNumberToDoubleElements(r0, r3, r1, r5, r6, r7, r9, r10, 7310 __ StoreNumberToDoubleElements(r0, r3, r1, r5, r6, r7, r9, r10,
7317 &slow_elements); 7311 &slow_elements);
7318 __ Ret(); 7312 __ Ret();
7319 } 7313 }
7320 7314
7321 #undef __ 7315 #undef __
7322 7316
7323 } } // namespace v8::internal 7317 } } // namespace v8::internal
7324 7318
7325 #endif // V8_TARGET_ARCH_ARM 7319 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698