OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1291 // and go to (1). Otherwise bail out to runtime. | 1291 // and go to (1). Otherwise bail out to runtime. |
1292 // (4) Sequential string. Load regexp code according to encoding. | 1292 // (4) Sequential string. Load regexp code according to encoding. |
1293 // (E) Carry on. | 1293 // (E) Carry on. |
1294 /// [...] | 1294 /// [...] |
1295 | 1295 |
1296 // Deferred code at the end of the stub: | 1296 // Deferred code at the end of the stub: |
1297 // (5) Long external string? If not, go to (7). | 1297 // (5) Long external string? If not, go to (7). |
1298 // (6) External string. Make it, offset-wise, look like a sequential string. | 1298 // (6) External string. Make it, offset-wise, look like a sequential string. |
1299 // Go to (4). | 1299 // Go to (4). |
1300 // (7) Short external string or not a string? If yes, bail out to runtime. | 1300 // (7) Short external string or not a string? If yes, bail out to runtime. |
1301 // (8) Sliced or thin string. Replace subject with parent. Go to (1). | 1301 // (8) Sliced string. Replace subject with parent. Go to (1). |
1302 | 1302 |
1303 Label seq_string /* 4 */, external_string /* 6 */, check_underlying /* 1 */, | 1303 Label seq_string /* 4 */, external_string /* 6 */, check_underlying /* 1 */, |
1304 not_seq_nor_cons /* 5 */, not_long_external /* 7 */; | 1304 not_seq_nor_cons /* 5 */, not_long_external /* 7 */; |
1305 | 1305 |
1306 __ bind(&check_underlying); | 1306 __ bind(&check_underlying); |
1307 __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset)); | 1307 __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset)); |
1308 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset)); | 1308 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset)); |
1309 | 1309 |
1310 // (1) Sequential string? If yes, go to (4). | 1310 // (1) Sequential string? If yes, go to (4). |
1311 __ and_(r1, | 1311 __ and_(r1, |
1312 r0, | 1312 r0, |
1313 Operand(kIsNotStringMask | | 1313 Operand(kIsNotStringMask | |
1314 kStringRepresentationMask | | 1314 kStringRepresentationMask | |
1315 kShortExternalStringMask), | 1315 kShortExternalStringMask), |
1316 SetCC); | 1316 SetCC); |
1317 STATIC_ASSERT((kStringTag | kSeqStringTag) == 0); | 1317 STATIC_ASSERT((kStringTag | kSeqStringTag) == 0); |
1318 __ b(eq, &seq_string); // Go to (4). | 1318 __ b(eq, &seq_string); // Go to (4). |
1319 | 1319 |
1320 // (2) Sequential or cons? If not, go to (5). | 1320 // (2) Sequential or cons? If not, go to (5). |
1321 STATIC_ASSERT(kConsStringTag < kExternalStringTag); | 1321 STATIC_ASSERT(kConsStringTag < kExternalStringTag); |
1322 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); | 1322 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); |
1323 STATIC_ASSERT(kThinStringTag > kExternalStringTag); | |
1324 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); | 1323 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); |
1325 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); | 1324 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); |
1326 __ cmp(r1, Operand(kExternalStringTag)); | 1325 __ cmp(r1, Operand(kExternalStringTag)); |
1327 __ b(ge, ¬_seq_nor_cons); // Go to (5). | 1326 __ b(ge, ¬_seq_nor_cons); // Go to (5). |
1328 | 1327 |
1329 // (3) Cons string. Check that it's flat. | 1328 // (3) Cons string. Check that it's flat. |
1330 // Replace subject with first string and reload instance type. | 1329 // Replace subject with first string and reload instance type. |
1331 __ ldr(r0, FieldMemOperand(subject, ConsString::kSecondOffset)); | 1330 __ ldr(r0, FieldMemOperand(subject, ConsString::kSecondOffset)); |
1332 __ CompareRoot(r0, Heap::kempty_stringRootIndex); | 1331 __ CompareRoot(r0, Heap::kempty_stringRootIndex); |
1333 __ b(ne, &runtime); | 1332 __ b(ne, &runtime); |
1334 __ ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset)); | 1333 __ ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset)); |
1335 __ jmp(&check_underlying); | 1334 __ jmp(&check_underlying); |
1336 | 1335 |
1337 // (4) Sequential string. Load regexp code according to encoding. | 1336 // (4) Sequential string. Load regexp code according to encoding. |
1338 __ bind(&seq_string); | 1337 __ bind(&seq_string); |
1339 // subject: sequential subject string (or look-alike, external string) | 1338 // subject: sequential subject string (or look-alike, external string) |
1340 // r3: original subject string | 1339 // r3: original subject string |
1341 // Load previous index and check range before r3 is overwritten. We have to | 1340 // Load previous index and check range before r3 is overwritten. We have to |
1342 // use r3 instead of subject here because subject might have been only made | 1341 // use r3 instead of subject here because subject might have been only made |
1343 // to look like a sequential string when it actually is an external string. | 1342 // to look like a sequential string when it actually is an external string. |
1344 __ ldr(r1, MemOperand(sp, kPreviousIndexOffset)); | 1343 __ ldr(r1, MemOperand(sp, kPreviousIndexOffset)); |
1345 __ JumpIfNotSmi(r1, &runtime); | 1344 __ JumpIfNotSmi(r1, &runtime); |
1346 __ ldr(r3, FieldMemOperand(r3, String::kLengthOffset)); | 1345 __ ldr(r3, FieldMemOperand(r3, String::kLengthOffset)); |
1347 __ cmp(r3, Operand(r1)); | 1346 __ cmp(r3, Operand(r1)); |
1348 __ b(ls, &runtime); | 1347 __ b(ls, &runtime); |
1349 __ SmiUntag(r1); | 1348 __ SmiUntag(r1); |
1350 | 1349 |
1351 STATIC_ASSERT(8 == kOneByteStringTag); | 1350 STATIC_ASSERT(4 == kOneByteStringTag); |
1352 STATIC_ASSERT(kTwoByteStringTag == 0); | 1351 STATIC_ASSERT(kTwoByteStringTag == 0); |
1353 __ and_(r0, r0, Operand(kStringEncodingMask)); | 1352 __ and_(r0, r0, Operand(kStringEncodingMask)); |
1354 __ mov(r3, Operand(r0, ASR, 3), SetCC); | 1353 __ mov(r3, Operand(r0, ASR, 2), SetCC); |
1355 __ ldr(r6, FieldMemOperand(regexp_data, JSRegExp::kDataOneByteCodeOffset), | 1354 __ ldr(r6, FieldMemOperand(regexp_data, JSRegExp::kDataOneByteCodeOffset), |
1356 ne); | 1355 ne); |
1357 __ ldr(r6, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset), eq); | 1356 __ ldr(r6, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset), eq); |
1358 | 1357 |
1359 // (E) Carry on. String handling is done. | 1358 // (E) Carry on. String handling is done. |
1360 // r6: irregexp code | 1359 // r6: irregexp code |
1361 // Check that the irregexp code has been generated for the actual string | 1360 // Check that the irregexp code has been generated for the actual string |
1362 // encoding. If it has, the field contains a code object otherwise it contains | 1361 // encoding. If it has, the field contains a code object otherwise it contains |
1363 // a smi (code flushing support). | 1362 // a smi (code flushing support). |
1364 __ JumpIfSmi(r6, &runtime); | 1363 __ JumpIfSmi(r6, &runtime); |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1578 subject, | 1577 subject, |
1579 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | 1578 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
1580 __ jmp(&seq_string); // Go to (4). | 1579 __ jmp(&seq_string); // Go to (4). |
1581 | 1580 |
1582 // (7) Short external string or not a string? If yes, bail out to runtime. | 1581 // (7) Short external string or not a string? If yes, bail out to runtime. |
1583 __ bind(¬_long_external); | 1582 __ bind(¬_long_external); |
1584 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); | 1583 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); |
1585 __ tst(r1, Operand(kIsNotStringMask | kShortExternalStringMask)); | 1584 __ tst(r1, Operand(kIsNotStringMask | kShortExternalStringMask)); |
1586 __ b(ne, &runtime); | 1585 __ b(ne, &runtime); |
1587 | 1586 |
1588 // (8) Sliced or thin string. Replace subject with parent. Go to (4). | 1587 // (8) Sliced string. Replace subject with parent. Go to (4). |
1589 Label thin_string; | |
1590 __ cmp(r1, Operand(kThinStringTag)); | |
1591 __ b(eq, &thin_string); | |
1592 // Load offset into r9 and replace subject string with parent. | 1588 // Load offset into r9 and replace subject string with parent. |
1593 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); | 1589 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); |
1594 __ SmiUntag(r9); | 1590 __ SmiUntag(r9); |
1595 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 1591 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
1596 __ jmp(&check_underlying); // Go to (4). | 1592 __ jmp(&check_underlying); // Go to (4). |
1597 | |
1598 __ bind(&thin_string); | |
1599 __ ldr(subject, FieldMemOperand(subject, ThinString::kActualOffset)); | |
1600 __ jmp(&check_underlying); // Go to (4). | |
1601 #endif // V8_INTERPRETED_REGEXP | 1593 #endif // V8_INTERPRETED_REGEXP |
1602 } | 1594 } |
1603 | 1595 |
1604 | 1596 |
1605 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { | 1597 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { |
1606 // r0 : number of arguments to the construct function | 1598 // r0 : number of arguments to the construct function |
1607 // r1 : the function to call | 1599 // r1 : the function to call |
1608 // r2 : feedback vector | 1600 // r2 : feedback vector |
1609 // r3 : slot in feedback vector (Smi) | 1601 // r3 : slot in feedback vector (Smi) |
1610 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 1602 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
(...skipping 2483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4094 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, | 4086 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, |
4095 kStackUnwindSpace, NULL, return_value_operand, NULL); | 4087 kStackUnwindSpace, NULL, return_value_operand, NULL); |
4096 } | 4088 } |
4097 | 4089 |
4098 #undef __ | 4090 #undef __ |
4099 | 4091 |
4100 } // namespace internal | 4092 } // namespace internal |
4101 } // namespace v8 | 4093 } // namespace v8 |
4102 | 4094 |
4103 #endif // V8_TARGET_ARCH_ARM | 4095 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |