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

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

Issue 6723014: Avoid TLS access for counters. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
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/builtins-arm.cc ('k') | src/arm/codegen-arm.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 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 1440 matching lines...) Expand 10 before | Expand all | Expand 10 after
1451 // contains two elements (number and string) for each cache entry. 1451 // contains two elements (number and string) for each cache entry.
1452 __ ldr(mask, FieldMemOperand(number_string_cache, FixedArray::kLengthOffset)); 1452 __ ldr(mask, FieldMemOperand(number_string_cache, FixedArray::kLengthOffset));
1453 // Divide length by two (length is a smi). 1453 // Divide length by two (length is a smi).
1454 __ mov(mask, Operand(mask, ASR, kSmiTagSize + 1)); 1454 __ mov(mask, Operand(mask, ASR, kSmiTagSize + 1));
1455 __ sub(mask, mask, Operand(1)); // Make mask. 1455 __ sub(mask, mask, Operand(1)); // Make mask.
1456 1456
1457 // Calculate the entry in the number string cache. The hash value in the 1457 // Calculate the entry in the number string cache. The hash value in the
1458 // number string cache for smis is just the smi value, and the hash for 1458 // number string cache for smis is just the smi value, and the hash for
1459 // doubles is the xor of the upper and lower words. See 1459 // doubles is the xor of the upper and lower words. See
1460 // Heap::GetNumberStringCache. 1460 // Heap::GetNumberStringCache.
1461 Isolate* isolate = masm->isolate();
1461 Label is_smi; 1462 Label is_smi;
1462 Label load_result_from_cache; 1463 Label load_result_from_cache;
1463 if (!object_is_smi) { 1464 if (!object_is_smi) {
1464 __ JumpIfSmi(object, &is_smi); 1465 __ JumpIfSmi(object, &is_smi);
1465 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) { 1466 if (isolate->cpu_features()->IsSupported(VFP3)) {
1466 CpuFeatures::Scope scope(VFP3); 1467 CpuFeatures::Scope scope(VFP3);
1467 __ CheckMap(object, 1468 __ CheckMap(object,
1468 scratch1, 1469 scratch1,
1469 Heap::kHeapNumberMapRootIndex, 1470 Heap::kHeapNumberMapRootIndex,
1470 not_found, 1471 not_found,
1471 true); 1472 true);
1472 1473
1473 STATIC_ASSERT(8 == kDoubleSize); 1474 STATIC_ASSERT(8 == kDoubleSize);
1474 __ add(scratch1, 1475 __ add(scratch1,
1475 object, 1476 object,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1512 // Check if the entry is the smi we are looking for. 1513 // Check if the entry is the smi we are looking for.
1513 Register probe = mask; 1514 Register probe = mask;
1514 __ ldr(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 1515 __ ldr(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize));
1515 __ cmp(object, probe); 1516 __ cmp(object, probe);
1516 __ b(ne, not_found); 1517 __ b(ne, not_found);
1517 1518
1518 // Get the result from the cache. 1519 // Get the result from the cache.
1519 __ bind(&load_result_from_cache); 1520 __ bind(&load_result_from_cache);
1520 __ ldr(result, 1521 __ ldr(result,
1521 FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize)); 1522 FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize));
1522 __ IncrementCounter(COUNTERS->number_to_string_native(), 1523 __ IncrementCounter(isolate->counters()->number_to_string_native(),
1523 1, 1524 1,
1524 scratch1, 1525 scratch1,
1525 scratch2); 1526 scratch2);
1526 } 1527 }
1527 1528
1528 1529
1529 void NumberToStringStub::Generate(MacroAssembler* masm) { 1530 void NumberToStringStub::Generate(MacroAssembler* masm) {
1530 Label runtime; 1531 Label runtime;
1531 1532
1532 __ ldr(r1, MemOperand(sp, 0)); 1533 __ ldr(r1, MemOperand(sp, 0));
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 // 4) Jump to lhs_not_nan. 1589 // 4) Jump to lhs_not_nan.
1589 // In cases 3 and 4 we have found out we were dealing with a number-number 1590 // In cases 3 and 4 we have found out we were dealing with a number-number
1590 // comparison. If VFP3 is supported the double values of the numbers have 1591 // comparison. If VFP3 is supported the double values of the numbers have
1591 // been loaded into d7 and d6. Otherwise, the double values have been loaded 1592 // been loaded into d7 and d6. Otherwise, the double values have been loaded
1592 // into r0, r1, r2, and r3. 1593 // into r0, r1, r2, and r3.
1593 EmitSmiNonsmiComparison(masm, lhs_, rhs_, &lhs_not_nan, &slow, strict_); 1594 EmitSmiNonsmiComparison(masm, lhs_, rhs_, &lhs_not_nan, &slow, strict_);
1594 1595
1595 __ bind(&both_loaded_as_doubles); 1596 __ bind(&both_loaded_as_doubles);
1596 // The arguments have been converted to doubles and stored in d6 and d7, if 1597 // The arguments have been converted to doubles and stored in d6 and d7, if
1597 // VFP3 is supported, or in r0, r1, r2, and r3. 1598 // VFP3 is supported, or in r0, r1, r2, and r3.
1598 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) { 1599 Isolate* isolate = masm->isolate();
1600 if (isolate->cpu_features()->IsSupported(VFP3)) {
1599 __ bind(&lhs_not_nan); 1601 __ bind(&lhs_not_nan);
1600 CpuFeatures::Scope scope(VFP3); 1602 CpuFeatures::Scope scope(VFP3);
1601 Label no_nan; 1603 Label no_nan;
1602 // ARMv7 VFP3 instructions to implement double precision comparison. 1604 // ARMv7 VFP3 instructions to implement double precision comparison.
1603 __ VFPCompareAndSetFlags(d7, d6); 1605 __ VFPCompareAndSetFlags(d7, d6);
1604 Label nan; 1606 Label nan;
1605 __ b(vs, &nan); 1607 __ b(vs, &nan);
1606 __ mov(r0, Operand(EQUAL), LeaveCC, eq); 1608 __ mov(r0, Operand(EQUAL), LeaveCC, eq);
1607 __ mov(r0, Operand(LESS), LeaveCC, lt); 1609 __ mov(r0, Operand(LESS), LeaveCC, lt);
1608 __ mov(r0, Operand(GREATER), LeaveCC, gt); 1610 __ mov(r0, Operand(GREATER), LeaveCC, gt);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1658 // Assumes that r2 is the type of rhs_ on entry. 1660 // Assumes that r2 is the type of rhs_ on entry.
1659 EmitCheckForSymbolsOrObjects(masm, lhs_, rhs_, &flat_string_check, &slow); 1661 EmitCheckForSymbolsOrObjects(masm, lhs_, rhs_, &flat_string_check, &slow);
1660 } 1662 }
1661 1663
1662 // Check for both being sequential ASCII strings, and inline if that is the 1664 // Check for both being sequential ASCII strings, and inline if that is the
1663 // case. 1665 // case.
1664 __ bind(&flat_string_check); 1666 __ bind(&flat_string_check);
1665 1667
1666 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs_, rhs_, r2, r3, &slow); 1668 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs_, rhs_, r2, r3, &slow);
1667 1669
1668 __ IncrementCounter(COUNTERS->string_compare_native(), 1, r2, r3); 1670 __ IncrementCounter(isolate->counters()->string_compare_native(), 1, r2, r3);
1669 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, 1671 StringCompareStub::GenerateCompareFlatAsciiStrings(masm,
1670 lhs_, 1672 lhs_,
1671 rhs_, 1673 rhs_,
1672 r2, 1674 r2,
1673 r3, 1675 r3,
1674 r4, 1676 r4,
1675 r5); 1677 r5);
1676 // Never falls through to here. 1678 // Never falls through to here.
1677 1679
1678 __ bind(&slow); 1680 __ bind(&slow);
(...skipping 3403 matching lines...) Expand 10 before | Expand all | Expand 10 after
5082 // RegExp code to avoid handling changing stack height. 5084 // RegExp code to avoid handling changing stack height.
5083 __ ldr(r1, MemOperand(sp, kPreviousIndexOffset)); 5085 __ ldr(r1, MemOperand(sp, kPreviousIndexOffset));
5084 __ mov(r1, Operand(r1, ASR, kSmiTagSize)); 5086 __ mov(r1, Operand(r1, ASR, kSmiTagSize));
5085 5087
5086 // r1: previous index 5088 // r1: previous index
5087 // r3: encoding of subject string (1 if ASCII, 0 if two_byte); 5089 // r3: encoding of subject string (1 if ASCII, 0 if two_byte);
5088 // r7: code 5090 // r7: code
5089 // subject: Subject string 5091 // subject: Subject string
5090 // regexp_data: RegExp data (FixedArray) 5092 // regexp_data: RegExp data (FixedArray)
5091 // All checks done. Now push arguments for native regexp code. 5093 // All checks done. Now push arguments for native regexp code.
5092 __ IncrementCounter(COUNTERS->regexp_entry_native(), 1, r0, r2); 5094 __ IncrementCounter(isolate->counters()->regexp_entry_native(), 1, r0, r2);
5093 5095
5094 // Isolates: note we add an additional parameter here (isolate pointer). 5096 // Isolates: note we add an additional parameter here (isolate pointer).
5095 static const int kRegExpExecuteArguments = 8; 5097 static const int kRegExpExecuteArguments = 8;
5096 static const int kParameterRegisters = 4; 5098 static const int kParameterRegisters = 4;
5097 __ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters); 5099 __ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
5098 5100
5099 // Stack pointer now points to cell where return address is to be written. 5101 // Stack pointer now points to cell where return address is to be written.
5100 // Arguments are before that on the stack or in registers. 5102 // Arguments are before that on the stack or in registers.
5101 5103
5102 // Argument 8 (sp[16]): Pass current isolate address. 5104 // Argument 8 (sp[16]): Pass current isolate address.
(...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after
6098 // nothing can be assumed about the arguments. It is tested that: 6100 // nothing can be assumed about the arguments. It is tested that:
6099 // "string" is a sequential string, 6101 // "string" is a sequential string,
6100 // both "from" and "to" are smis, and 6102 // both "from" and "to" are smis, and
6101 // 0 <= from <= to <= string.length. 6103 // 0 <= from <= to <= string.length.
6102 // If any of these assumptions fail, we call the runtime system. 6104 // If any of these assumptions fail, we call the runtime system.
6103 6105
6104 static const int kToOffset = 0 * kPointerSize; 6106 static const int kToOffset = 0 * kPointerSize;
6105 static const int kFromOffset = 1 * kPointerSize; 6107 static const int kFromOffset = 1 * kPointerSize;
6106 static const int kStringOffset = 2 * kPointerSize; 6108 static const int kStringOffset = 2 * kPointerSize;
6107 6109
6108
6109 // Check bounds and smi-ness. 6110 // Check bounds and smi-ness.
6110 Register to = r6; 6111 Register to = r6;
6111 Register from = r7; 6112 Register from = r7;
6112 __ Ldrd(to, from, MemOperand(sp, kToOffset)); 6113 __ Ldrd(to, from, MemOperand(sp, kToOffset));
6113 STATIC_ASSERT(kFromOffset == kToOffset + 4); 6114 STATIC_ASSERT(kFromOffset == kToOffset + 4);
6114 STATIC_ASSERT(kSmiTag == 0); 6115 STATIC_ASSERT(kSmiTag == 0);
6115 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); 6116 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
6116 // I.e., arithmetic shift right by one un-smi-tags. 6117 // I.e., arithmetic shift right by one un-smi-tags.
6117 __ mov(r2, Operand(to, ASR, 1), SetCC); 6118 __ mov(r2, Operand(to, ASR, 1), SetCC);
6118 __ mov(r3, Operand(from, ASR, 1), SetCC, cc); 6119 __ mov(r3, Operand(from, ASR, 1), SetCC, cc);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
6199 // Sub string of length 2 requested. 6200 // Sub string of length 2 requested.
6200 // Get the two characters forming the sub string. 6201 // Get the two characters forming the sub string.
6201 __ add(r5, r5, Operand(r3)); 6202 __ add(r5, r5, Operand(r3));
6202 __ ldrb(r3, FieldMemOperand(r5, SeqAsciiString::kHeaderSize)); 6203 __ ldrb(r3, FieldMemOperand(r5, SeqAsciiString::kHeaderSize));
6203 __ ldrb(r4, FieldMemOperand(r5, SeqAsciiString::kHeaderSize + 1)); 6204 __ ldrb(r4, FieldMemOperand(r5, SeqAsciiString::kHeaderSize + 1));
6204 6205
6205 // Try to lookup two character string in symbol table. 6206 // Try to lookup two character string in symbol table.
6206 Label make_two_character_string; 6207 Label make_two_character_string;
6207 StringHelper::GenerateTwoCharacterSymbolTableProbe( 6208 StringHelper::GenerateTwoCharacterSymbolTableProbe(
6208 masm, r3, r4, r1, r5, r6, r7, r9, &make_two_character_string); 6209 masm, r3, r4, r1, r5, r6, r7, r9, &make_two_character_string);
6209 __ IncrementCounter(COUNTERS->sub_string_native(), 1, r3, r4); 6210 Counters* counters = masm->isolate()->counters();
6211 __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
6210 __ add(sp, sp, Operand(3 * kPointerSize)); 6212 __ add(sp, sp, Operand(3 * kPointerSize));
6211 __ Ret(); 6213 __ Ret();
6212 6214
6213 // r2: result string length. 6215 // r2: result string length.
6214 // r3: two characters combined into halfword in little endian byte order. 6216 // r3: two characters combined into halfword in little endian byte order.
6215 __ bind(&make_two_character_string); 6217 __ bind(&make_two_character_string);
6216 __ AllocateAsciiString(r0, r2, r4, r5, r9, &runtime); 6218 __ AllocateAsciiString(r0, r2, r4, r5, r9, &runtime);
6217 __ strh(r3, FieldMemOperand(r0, SeqAsciiString::kHeaderSize)); 6219 __ strh(r3, FieldMemOperand(r0, SeqAsciiString::kHeaderSize));
6218 __ IncrementCounter(COUNTERS->sub_string_native(), 1, r3, r4); 6220 __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
6219 __ add(sp, sp, Operand(3 * kPointerSize)); 6221 __ add(sp, sp, Operand(3 * kPointerSize));
6220 __ Ret(); 6222 __ Ret();
6221 6223
6222 __ bind(&result_longer_than_two); 6224 __ bind(&result_longer_than_two);
6223 6225
6224 // Allocate the result. 6226 // Allocate the result.
6225 __ AllocateAsciiString(r0, r2, r3, r4, r1, &runtime); 6227 __ AllocateAsciiString(r0, r2, r3, r4, r1, &runtime);
6226 6228
6227 // r0: result string. 6229 // r0: result string.
6228 // r2: result string length. 6230 // r2: result string length.
6229 // r5: string. 6231 // r5: string.
6230 // r7 (a.k.a. from): from offset (smi) 6232 // r7 (a.k.a. from): from offset (smi)
6231 // Locate first character of result. 6233 // Locate first character of result.
6232 __ add(r1, r0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 6234 __ add(r1, r0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
6233 // Locate 'from' character of string. 6235 // Locate 'from' character of string.
6234 __ add(r5, r5, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 6236 __ add(r5, r5, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
6235 __ add(r5, r5, Operand(from, ASR, 1)); 6237 __ add(r5, r5, Operand(from, ASR, 1));
6236 6238
6237 // r0: result string. 6239 // r0: result string.
6238 // r1: first character of result string. 6240 // r1: first character of result string.
6239 // r2: result string length. 6241 // r2: result string length.
6240 // r5: first character of sub string to copy. 6242 // r5: first character of sub string to copy.
6241 STATIC_ASSERT((SeqAsciiString::kHeaderSize & kObjectAlignmentMask) == 0); 6243 STATIC_ASSERT((SeqAsciiString::kHeaderSize & kObjectAlignmentMask) == 0);
6242 StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9, 6244 StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9,
6243 COPY_ASCII | DEST_ALWAYS_ALIGNED); 6245 COPY_ASCII | DEST_ALWAYS_ALIGNED);
6244 __ IncrementCounter(COUNTERS->sub_string_native(), 1, r3, r4); 6246 __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
6245 __ add(sp, sp, Operand(3 * kPointerSize)); 6247 __ add(sp, sp, Operand(3 * kPointerSize));
6246 __ Ret(); 6248 __ Ret();
6247 6249
6248 __ bind(&non_ascii_flat); 6250 __ bind(&non_ascii_flat);
6249 // r2: result string length. 6251 // r2: result string length.
6250 // r5: string. 6252 // r5: string.
6251 // r7 (a.k.a. from): from offset (smi) 6253 // r7 (a.k.a. from): from offset (smi)
6252 // Check for flat two byte string. 6254 // Check for flat two byte string.
6253 6255
6254 // Allocate the result. 6256 // Allocate the result.
(...skipping 11 matching lines...) Expand all
6266 __ add(r5, r5, Operand(from)); 6268 __ add(r5, r5, Operand(from));
6267 from = no_reg; 6269 from = no_reg;
6268 6270
6269 // r0: result string. 6271 // r0: result string.
6270 // r1: first character of result. 6272 // r1: first character of result.
6271 // r2: result length. 6273 // r2: result length.
6272 // r5: first character of string to copy. 6274 // r5: first character of string to copy.
6273 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); 6275 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
6274 StringHelper::GenerateCopyCharactersLong( 6276 StringHelper::GenerateCopyCharactersLong(
6275 masm, r1, r5, r2, r3, r4, r6, r7, r9, DEST_ALWAYS_ALIGNED); 6277 masm, r1, r5, r2, r3, r4, r6, r7, r9, DEST_ALWAYS_ALIGNED);
6276 __ IncrementCounter(COUNTERS->sub_string_native(), 1, r3, r4); 6278 __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
6277 __ add(sp, sp, Operand(3 * kPointerSize)); 6279 __ add(sp, sp, Operand(3 * kPointerSize));
6278 __ Ret(); 6280 __ Ret();
6279 6281
6280 // Just jump to runtime to create the sub string. 6282 // Just jump to runtime to create the sub string.
6281 __ bind(&runtime); 6283 __ bind(&runtime);
6282 __ TailCallRuntime(Runtime::kSubString, 3, 1); 6284 __ TailCallRuntime(Runtime::kSubString, 3, 1);
6283 } 6285 }
6284 6286
6285 6287
6286 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, 6288 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
6338 // Fall through to here if characters compare not-equal. 6340 // Fall through to here if characters compare not-equal.
6339 __ mov(r0, Operand(Smi::FromInt(GREATER)), LeaveCC, gt); 6341 __ mov(r0, Operand(Smi::FromInt(GREATER)), LeaveCC, gt);
6340 __ mov(r0, Operand(Smi::FromInt(LESS)), LeaveCC, lt); 6342 __ mov(r0, Operand(Smi::FromInt(LESS)), LeaveCC, lt);
6341 __ Ret(); 6343 __ Ret();
6342 } 6344 }
6343 6345
6344 6346
6345 void StringCompareStub::Generate(MacroAssembler* masm) { 6347 void StringCompareStub::Generate(MacroAssembler* masm) {
6346 Label runtime; 6348 Label runtime;
6347 6349
6350 Counters* counters = masm->isolate()->counters();
6351
6348 // Stack frame on entry. 6352 // Stack frame on entry.
6349 // sp[0]: right string 6353 // sp[0]: right string
6350 // sp[4]: left string 6354 // sp[4]: left string
6351 __ Ldrd(r0 , r1, MemOperand(sp)); // Load right in r0, left in r1. 6355 __ Ldrd(r0 , r1, MemOperand(sp)); // Load right in r0, left in r1.
6352 6356
6353 Label not_same; 6357 Label not_same;
6354 __ cmp(r0, r1); 6358 __ cmp(r0, r1);
6355 __ b(ne, &not_same); 6359 __ b(ne, &not_same);
6356 STATIC_ASSERT(EQUAL == 0); 6360 STATIC_ASSERT(EQUAL == 0);
6357 STATIC_ASSERT(kSmiTag == 0); 6361 STATIC_ASSERT(kSmiTag == 0);
6358 __ mov(r0, Operand(Smi::FromInt(EQUAL))); 6362 __ mov(r0, Operand(Smi::FromInt(EQUAL)));
6359 __ IncrementCounter(COUNTERS->string_compare_native(), 1, r1, r2); 6363 __ IncrementCounter(counters->string_compare_native(), 1, r1, r2);
6360 __ add(sp, sp, Operand(2 * kPointerSize)); 6364 __ add(sp, sp, Operand(2 * kPointerSize));
6361 __ Ret(); 6365 __ Ret();
6362 6366
6363 __ bind(&not_same); 6367 __ bind(&not_same);
6364 6368
6365 // Check that both objects are sequential ASCII strings. 6369 // Check that both objects are sequential ASCII strings.
6366 __ JumpIfNotBothSequentialAsciiStrings(r1, r0, r2, r3, &runtime); 6370 __ JumpIfNotBothSequentialAsciiStrings(r1, r0, r2, r3, &runtime);
6367 6371
6368 // Compare flat ASCII strings natively. Remove arguments from stack first. 6372 // Compare flat ASCII strings natively. Remove arguments from stack first.
6369 __ IncrementCounter(COUNTERS->string_compare_native(), 1, r2, r3); 6373 __ IncrementCounter(counters->string_compare_native(), 1, r2, r3);
6370 __ add(sp, sp, Operand(2 * kPointerSize)); 6374 __ add(sp, sp, Operand(2 * kPointerSize));
6371 GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5); 6375 GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5);
6372 6376
6373 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 6377 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
6374 // tagged as a small integer. 6378 // tagged as a small integer.
6375 __ bind(&runtime); 6379 __ bind(&runtime);
6376 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 6380 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
6377 } 6381 }
6378 6382
6379 6383
6380 void StringAddStub::Generate(MacroAssembler* masm) { 6384 void StringAddStub::Generate(MacroAssembler* masm) {
6381 Label string_add_runtime, call_builtin; 6385 Label string_add_runtime, call_builtin;
6382 Builtins::JavaScript builtin_id = Builtins::ADD; 6386 Builtins::JavaScript builtin_id = Builtins::ADD;
6383 6387
6388 Counters* counters = masm->isolate()->counters();
6389
6384 // Stack on entry: 6390 // Stack on entry:
6385 // sp[0]: second argument (right). 6391 // sp[0]: second argument (right).
6386 // sp[4]: first argument (left). 6392 // sp[4]: first argument (left).
6387 6393
6388 // Load the two arguments. 6394 // Load the two arguments.
6389 __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); // First argument. 6395 __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); // First argument.
6390 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); // Second argument. 6396 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); // Second argument.
6391 6397
6392 // Make sure that both arguments are strings if not known in advance. 6398 // Make sure that both arguments are strings if not known in advance.
6393 if (flags_ == NO_STRING_ADD_FLAGS) { 6399 if (flags_ == NO_STRING_ADD_FLAGS) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
6429 __ ldr(r2, FieldMemOperand(r0, String::kLengthOffset)); 6435 __ ldr(r2, FieldMemOperand(r0, String::kLengthOffset));
6430 __ ldr(r3, FieldMemOperand(r1, String::kLengthOffset)); 6436 __ ldr(r3, FieldMemOperand(r1, String::kLengthOffset));
6431 STATIC_ASSERT(kSmiTag == 0); 6437 STATIC_ASSERT(kSmiTag == 0);
6432 __ cmp(r2, Operand(Smi::FromInt(0))); // Test if first string is empty. 6438 __ cmp(r2, Operand(Smi::FromInt(0))); // Test if first string is empty.
6433 __ mov(r0, Operand(r1), LeaveCC, eq); // If first is empty, return second. 6439 __ mov(r0, Operand(r1), LeaveCC, eq); // If first is empty, return second.
6434 STATIC_ASSERT(kSmiTag == 0); 6440 STATIC_ASSERT(kSmiTag == 0);
6435 // Else test if second string is empty. 6441 // Else test if second string is empty.
6436 __ cmp(r3, Operand(Smi::FromInt(0)), ne); 6442 __ cmp(r3, Operand(Smi::FromInt(0)), ne);
6437 __ b(ne, &strings_not_empty); // If either string was empty, return r0. 6443 __ b(ne, &strings_not_empty); // If either string was empty, return r0.
6438 6444
6439 __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3); 6445 __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
6440 __ add(sp, sp, Operand(2 * kPointerSize)); 6446 __ add(sp, sp, Operand(2 * kPointerSize));
6441 __ Ret(); 6447 __ Ret();
6442 6448
6443 __ bind(&strings_not_empty); 6449 __ bind(&strings_not_empty);
6444 } 6450 }
6445 6451
6446 __ mov(r2, Operand(r2, ASR, kSmiTagSize)); 6452 __ mov(r2, Operand(r2, ASR, kSmiTagSize));
6447 __ mov(r3, Operand(r3, ASR, kSmiTagSize)); 6453 __ mov(r3, Operand(r3, ASR, kSmiTagSize));
6448 // Both strings are non-empty. 6454 // Both strings are non-empty.
6449 // r0: first string 6455 // r0: first string
(...skipping 24 matching lines...) Expand all
6474 6480
6475 // Get the two characters forming the sub string. 6481 // Get the two characters forming the sub string.
6476 __ ldrb(r2, FieldMemOperand(r0, SeqAsciiString::kHeaderSize)); 6482 __ ldrb(r2, FieldMemOperand(r0, SeqAsciiString::kHeaderSize));
6477 __ ldrb(r3, FieldMemOperand(r1, SeqAsciiString::kHeaderSize)); 6483 __ ldrb(r3, FieldMemOperand(r1, SeqAsciiString::kHeaderSize));
6478 6484
6479 // Try to lookup two character string in symbol table. If it is not found 6485 // Try to lookup two character string in symbol table. If it is not found
6480 // just allocate a new one. 6486 // just allocate a new one.
6481 Label make_two_character_string; 6487 Label make_two_character_string;
6482 StringHelper::GenerateTwoCharacterSymbolTableProbe( 6488 StringHelper::GenerateTwoCharacterSymbolTableProbe(
6483 masm, r2, r3, r6, r7, r4, r5, r9, &make_two_character_string); 6489 masm, r2, r3, r6, r7, r4, r5, r9, &make_two_character_string);
6484 __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3); 6490 __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
6485 __ add(sp, sp, Operand(2 * kPointerSize)); 6491 __ add(sp, sp, Operand(2 * kPointerSize));
6486 __ Ret(); 6492 __ Ret();
6487 6493
6488 __ bind(&make_two_character_string); 6494 __ bind(&make_two_character_string);
6489 // Resulting string has length 2 and first chars of two strings 6495 // Resulting string has length 2 and first chars of two strings
6490 // are combined into single halfword in r2 register. 6496 // are combined into single halfword in r2 register.
6491 // So we can fill resulting string without two loops by a single 6497 // So we can fill resulting string without two loops by a single
6492 // halfword store instruction (which assumes that processor is 6498 // halfword store instruction (which assumes that processor is
6493 // in a little endian mode) 6499 // in a little endian mode)
6494 __ mov(r6, Operand(2)); 6500 __ mov(r6, Operand(2));
6495 __ AllocateAsciiString(r0, r6, r4, r5, r9, &string_add_runtime); 6501 __ AllocateAsciiString(r0, r6, r4, r5, r9, &string_add_runtime);
6496 __ strh(r2, FieldMemOperand(r0, SeqAsciiString::kHeaderSize)); 6502 __ strh(r2, FieldMemOperand(r0, SeqAsciiString::kHeaderSize));
6497 __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3); 6503 __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
6498 __ add(sp, sp, Operand(2 * kPointerSize)); 6504 __ add(sp, sp, Operand(2 * kPointerSize));
6499 __ Ret(); 6505 __ Ret();
6500 6506
6501 __ bind(&longer_than_two); 6507 __ bind(&longer_than_two);
6502 // Check if resulting string will be flat. 6508 // Check if resulting string will be flat.
6503 __ cmp(r6, Operand(String::kMinNonFlatLength)); 6509 __ cmp(r6, Operand(String::kMinNonFlatLength));
6504 __ b(lt, &string_add_flat_result); 6510 __ b(lt, &string_add_flat_result);
6505 // Handle exceptionally long strings in the runtime system. 6511 // Handle exceptionally long strings in the runtime system.
6506 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0); 6512 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0);
6507 ASSERT(IsPowerOf2(String::kMaxLength + 1)); 6513 ASSERT(IsPowerOf2(String::kMaxLength + 1));
(...skipping 16 matching lines...) Expand all
6524 __ b(eq, &non_ascii); 6530 __ b(eq, &non_ascii);
6525 6531
6526 // Allocate an ASCII cons string. 6532 // Allocate an ASCII cons string.
6527 __ bind(&ascii_data); 6533 __ bind(&ascii_data);
6528 __ AllocateAsciiConsString(r7, r6, r4, r5, &string_add_runtime); 6534 __ AllocateAsciiConsString(r7, r6, r4, r5, &string_add_runtime);
6529 __ bind(&allocated); 6535 __ bind(&allocated);
6530 // Fill the fields of the cons string. 6536 // Fill the fields of the cons string.
6531 __ str(r0, FieldMemOperand(r7, ConsString::kFirstOffset)); 6537 __ str(r0, FieldMemOperand(r7, ConsString::kFirstOffset));
6532 __ str(r1, FieldMemOperand(r7, ConsString::kSecondOffset)); 6538 __ str(r1, FieldMemOperand(r7, ConsString::kSecondOffset));
6533 __ mov(r0, Operand(r7)); 6539 __ mov(r0, Operand(r7));
6534 __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3); 6540 __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
6535 __ add(sp, sp, Operand(2 * kPointerSize)); 6541 __ add(sp, sp, Operand(2 * kPointerSize));
6536 __ Ret(); 6542 __ Ret();
6537 6543
6538 __ bind(&non_ascii); 6544 __ bind(&non_ascii);
6539 // At least one of the strings is two-byte. Check whether it happens 6545 // At least one of the strings is two-byte. Check whether it happens
6540 // to contain only ASCII characters. 6546 // to contain only ASCII characters.
6541 // r4: first instance type. 6547 // r4: first instance type.
6542 // r5: second instance type. 6548 // r5: second instance type.
6543 __ tst(r4, Operand(kAsciiDataHintMask)); 6549 __ tst(r4, Operand(kAsciiDataHintMask));
6544 __ tst(r5, Operand(kAsciiDataHintMask), ne); 6550 __ tst(r5, Operand(kAsciiDataHintMask), ne);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
6606 StringHelper::GenerateCopyCharacters(masm, r6, r0, r2, r4, true); 6612 StringHelper::GenerateCopyCharacters(masm, r6, r0, r2, r4, true);
6607 6613
6608 // Load second argument and locate first character. 6614 // Load second argument and locate first character.
6609 __ add(r1, r1, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 6615 __ add(r1, r1, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
6610 // r1: first character of second string. 6616 // r1: first character of second string.
6611 // r3: length of second string. 6617 // r3: length of second string.
6612 // r6: next character of result. 6618 // r6: next character of result.
6613 // r7: result string. 6619 // r7: result string.
6614 StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, true); 6620 StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, true);
6615 __ mov(r0, Operand(r7)); 6621 __ mov(r0, Operand(r7));
6616 __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3); 6622 __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
6617 __ add(sp, sp, Operand(2 * kPointerSize)); 6623 __ add(sp, sp, Operand(2 * kPointerSize));
6618 __ Ret(); 6624 __ Ret();
6619 6625
6620 __ bind(&non_ascii_string_add_flat_result); 6626 __ bind(&non_ascii_string_add_flat_result);
6621 // Both strings are sequential two byte strings. 6627 // Both strings are sequential two byte strings.
6622 // r0: first string. 6628 // r0: first string.
6623 // r1: second string. 6629 // r1: second string.
6624 // r2: length of first string. 6630 // r2: length of first string.
6625 // r3: length of second string. 6631 // r3: length of second string.
6626 // r6: sum of length of strings. 6632 // r6: sum of length of strings.
(...skipping 20 matching lines...) Expand all
6647 // Locate first character of second argument. 6653 // Locate first character of second argument.
6648 __ add(r1, r1, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 6654 __ add(r1, r1, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
6649 6655
6650 // r1: first character of second string. 6656 // r1: first character of second string.
6651 // r3: length of second string. 6657 // r3: length of second string.
6652 // r6: next character of result (after copy of first string). 6658 // r6: next character of result (after copy of first string).
6653 // r7: result string. 6659 // r7: result string.
6654 StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, false); 6660 StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, false);
6655 6661
6656 __ mov(r0, Operand(r7)); 6662 __ mov(r0, Operand(r7));
6657 __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3); 6663 __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
6658 __ add(sp, sp, Operand(2 * kPointerSize)); 6664 __ add(sp, sp, Operand(2 * kPointerSize));
6659 __ Ret(); 6665 __ Ret();
6660 6666
6661 // Just jump to runtime to add the two strings. 6667 // Just jump to runtime to add the two strings.
6662 __ bind(&string_add_runtime); 6668 __ bind(&string_add_runtime);
6663 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 6669 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
6664 6670
6665 if (call_builtin.is_linked()) { 6671 if (call_builtin.is_linked()) {
6666 __ bind(&call_builtin); 6672 __ bind(&call_builtin);
6667 __ InvokeBuiltin(builtin_id, JUMP_JS); 6673 __ InvokeBuiltin(builtin_id, JUMP_JS);
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
6858 __ str(pc, MemOperand(sp, 0)); 6864 __ str(pc, MemOperand(sp, 0));
6859 __ Jump(target); // Call the C++ function. 6865 __ Jump(target); // Call the C++ function.
6860 } 6866 }
6861 6867
6862 6868
6863 #undef __ 6869 #undef __
6864 6870
6865 } } // namespace v8::internal 6871 } } // namespace v8::internal
6866 6872
6867 #endif // V8_TARGET_ARCH_ARM 6873 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/arm/codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698