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

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

Issue 2738413002: [regexp] Port RegExpExecStub to CSA (mostly) (Closed)
Patch Set: Rebase Created 3 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
« no previous file with comments | « src/objects.h ('k') | src/ppc/interface-descriptors-ppc.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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_PPC 5 #if V8_TARGET_ARCH_PPC
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 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 // Restore callee-saved registers. 1208 // Restore callee-saved registers.
1209 __ MultiPop(kCalleeSaved); 1209 __ MultiPop(kCalleeSaved);
1210 1210
1211 // Return 1211 // Return
1212 __ LoadP(r0, MemOperand(sp, kStackFrameLRSlot * kPointerSize)); 1212 __ LoadP(r0, MemOperand(sp, kStackFrameLRSlot * kPointerSize));
1213 __ mtlr(r0); 1213 __ mtlr(r0);
1214 __ blr(); 1214 __ blr();
1215 } 1215 }
1216 1216
1217 void RegExpExecStub::Generate(MacroAssembler* masm) { 1217 void RegExpExecStub::Generate(MacroAssembler* masm) {
1218 // Just jump directly to runtime if native RegExp is not selected at compile
1219 // time or if regexp entry in generated code is turned off runtime switch or
1220 // at compilation.
1221 #ifdef V8_INTERPRETED_REGEXP 1218 #ifdef V8_INTERPRETED_REGEXP
1222 __ TailCallRuntime(Runtime::kRegExpExec); 1219 // This case is handled prior to the RegExpExecStub call.
1220 __ Abort(kUnexpectedRegExpExecCall);
1223 #else // V8_INTERPRETED_REGEXP 1221 #else // V8_INTERPRETED_REGEXP
1224
1225 // Stack frame on entry.
1226 // sp[0]: last_match_info (expected JSArray)
1227 // sp[4]: previous index
1228 // sp[8]: subject string
1229 // sp[12]: JSRegExp object
1230
1231 const int kLastMatchInfoOffset = 0 * kPointerSize;
1232 const int kPreviousIndexOffset = 1 * kPointerSize;
1233 const int kSubjectOffset = 2 * kPointerSize;
1234 const int kJSRegExpOffset = 3 * kPointerSize;
1235
1236 Label runtime, br_over, encoding_type_UC16;
1237
1238 // Allocation of registers for this function. These are in callee save
1239 // registers and will be preserved by the call to the native RegExp code, as
1240 // this code is called using the normal C calling convention. When calling
1241 // directly from generated code the native RegExp code will not do a GC and
1242 // therefore the content of these registers are safe to use after the call.
1243 Register subject = r14;
1244 Register regexp_data = r15;
1245 Register last_match_info_elements = r16;
1246 Register code = r17;
1247
1248 // Ensure register assigments are consistent with callee save masks
1249 DCHECK(subject.bit() & kCalleeSaved);
1250 DCHECK(regexp_data.bit() & kCalleeSaved);
1251 DCHECK(last_match_info_elements.bit() & kCalleeSaved);
1252 DCHECK(code.bit() & kCalleeSaved);
1253
1254 // Ensure that a RegExp stack is allocated.
1255 ExternalReference address_of_regexp_stack_memory_address =
1256 ExternalReference::address_of_regexp_stack_memory_address(isolate());
1257 ExternalReference address_of_regexp_stack_memory_size =
1258 ExternalReference::address_of_regexp_stack_memory_size(isolate());
1259 __ mov(r3, Operand(address_of_regexp_stack_memory_size));
1260 __ LoadP(r3, MemOperand(r3, 0));
1261 __ cmpi(r3, Operand::Zero());
1262 __ beq(&runtime);
1263
1264 // Check that the first argument is a JSRegExp object.
1265 __ LoadP(r3, MemOperand(sp, kJSRegExpOffset));
1266 __ JumpIfSmi(r3, &runtime);
1267 __ CompareObjectType(r3, r4, r4, JS_REGEXP_TYPE);
1268 __ bne(&runtime);
1269
1270 // Check that the RegExp has been compiled (data contains a fixed array).
1271 __ LoadP(regexp_data, FieldMemOperand(r3, JSRegExp::kDataOffset));
1272 if (FLAG_debug_code) {
1273 __ TestIfSmi(regexp_data, r0);
1274 __ Check(ne, kUnexpectedTypeForRegExpDataFixedArrayExpected, cr0);
1275 __ CompareObjectType(regexp_data, r3, r3, FIXED_ARRAY_TYPE);
1276 __ Check(eq, kUnexpectedTypeForRegExpDataFixedArrayExpected);
1277 }
1278
1279 // regexp_data: RegExp data (FixedArray)
1280 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP.
1281 __ LoadP(r3, FieldMemOperand(regexp_data, JSRegExp::kDataTagOffset));
1282 // DCHECK(Smi::FromInt(JSRegExp::IRREGEXP) < (char *)0xffffu);
1283 __ CmpSmiLiteral(r3, Smi::FromInt(JSRegExp::IRREGEXP), r0);
1284 __ bne(&runtime);
1285
1286 // regexp_data: RegExp data (FixedArray)
1287 // Check that the number of captures fit in the static offsets vector buffer.
1288 __ LoadP(r5,
1289 FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset));
1290 // Check (number_of_captures + 1) * 2 <= offsets vector size
1291 // Or number_of_captures * 2 <= offsets vector size - 2
1292 // SmiToShortArrayOffset accomplishes the multiplication by 2 and
1293 // SmiUntag (which is a nop for 32-bit).
1294 __ SmiToShortArrayOffset(r5, r5);
1295 STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2);
1296 __ cmpli(r5, Operand(Isolate::kJSRegexpStaticOffsetsVectorSize - 2));
1297 __ bgt(&runtime);
1298
1299 // Reset offset for possibly sliced string.
1300 __ li(r11, Operand::Zero());
1301 __ LoadP(subject, MemOperand(sp, kSubjectOffset));
1302 __ JumpIfSmi(subject, &runtime);
1303 __ mr(r6, subject); // Make a copy of the original subject string.
1304 // subject: subject string
1305 // r6: subject string
1306 // regexp_data: RegExp data (FixedArray)
1307 // Handle subject string according to its encoding and representation:
1308 // (1) Sequential string? If yes, go to (4).
1309 // (2) Sequential or cons? If not, go to (5).
1310 // (3) Cons string. If the string is flat, replace subject with first string
1311 // and go to (1). Otherwise bail out to runtime.
1312 // (4) Sequential string. Load regexp code according to encoding.
1313 // (E) Carry on.
1314 /// [...]
1315
1316 // Deferred code at the end of the stub:
1317 // (5) Long external string? If not, go to (7).
1318 // (6) External string. Make it, offset-wise, look like a sequential string.
1319 // Go to (4).
1320 // (7) Short external string or not a string? If yes, bail out to runtime.
1321 // (8) Sliced or thin string. Replace subject with parent. Go to (1).
1322
1323 Label seq_string /* 4 */, external_string /* 6 */, check_underlying /* 1 */,
1324 not_seq_nor_cons /* 5 */, not_long_external /* 7 */;
1325
1326 __ bind(&check_underlying);
1327 __ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset));
1328 __ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
1329
1330 // (1) Sequential string? If yes, go to (4).
1331
1332 STATIC_ASSERT((kIsNotStringMask | kStringRepresentationMask |
1333 kShortExternalStringMask) == 0xa7);
1334 __ andi(r4, r3, Operand(kIsNotStringMask | kStringRepresentationMask |
1335 kShortExternalStringMask));
1336 STATIC_ASSERT((kStringTag | kSeqStringTag) == 0);
1337 __ beq(&seq_string, cr0); // Go to (4).
1338
1339 // (2) Sequential or cons? If not, go to (5).
1340 STATIC_ASSERT(kConsStringTag < kExternalStringTag);
1341 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
1342 STATIC_ASSERT(kThinStringTag > kExternalStringTag);
1343 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
1344 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
1345 STATIC_ASSERT(kExternalStringTag < 0xffffu);
1346 __ cmpi(r4, Operand(kExternalStringTag));
1347 __ bge(&not_seq_nor_cons); // Go to (5).
1348
1349 // (3) Cons string. Check that it's flat.
1350 // Replace subject with first string and reload instance type.
1351 __ LoadP(r3, FieldMemOperand(subject, ConsString::kSecondOffset));
1352 __ CompareRoot(r3, Heap::kempty_stringRootIndex);
1353 __ bne(&runtime);
1354 __ LoadP(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
1355 __ b(&check_underlying);
1356
1357 // (4) Sequential string. Load regexp code according to encoding.
1358 __ bind(&seq_string);
1359 // subject: sequential subject string (or look-alike, external string)
1360 // r6: original subject string
1361 // Load previous index and check range before r6 is overwritten. We have to
1362 // use r6 instead of subject here because subject might have been only made
1363 // to look like a sequential string when it actually is an external string.
1364 __ LoadP(r4, MemOperand(sp, kPreviousIndexOffset));
1365 __ JumpIfNotSmi(r4, &runtime);
1366 __ LoadP(r6, FieldMemOperand(r6, String::kLengthOffset));
1367 __ cmpl(r6, r4);
1368 __ ble(&runtime);
1369 __ SmiUntag(r4);
1370
1371 STATIC_ASSERT(8 == kOneByteStringTag);
1372 STATIC_ASSERT(kTwoByteStringTag == 0);
1373 STATIC_ASSERT(kStringEncodingMask == 8);
1374 __ ExtractBitMask(r6, r3, kStringEncodingMask, SetRC);
1375 __ beq(&encoding_type_UC16, cr0);
1376 __ LoadP(code,
1377 FieldMemOperand(regexp_data, JSRegExp::kDataOneByteCodeOffset));
1378 __ b(&br_over);
1379 __ bind(&encoding_type_UC16);
1380 __ LoadP(code, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset));
1381 __ bind(&br_over);
1382
1383 // (E) Carry on. String handling is done.
1384 // code: irregexp code
1385 // Check that the irregexp code has been generated for the actual string
1386 // encoding. If it has, the field contains a code object otherwise it contains
1387 // a smi (code flushing support).
1388 __ JumpIfSmi(code, &runtime);
1389
1390 // r4: previous index
1391 // r6: encoding of subject string (1 if one_byte, 0 if two_byte);
1392 // code: Address of generated regexp code
1393 // subject: Subject string
1394 // regexp_data: RegExp data (FixedArray)
1395 // All checks done. Now push arguments for native regexp code.
1396 __ IncrementCounter(isolate()->counters()->regexp_entry_native(), 1, r3, r5);
1397
1398 // Isolates: note we add an additional parameter here (isolate pointer). 1222 // Isolates: note we add an additional parameter here (isolate pointer).
1399 const int kRegExpExecuteArguments = 10; 1223 const int kRegExpExecuteArguments = 10;
1400 const int kParameterRegisters = 8; 1224 const int kParameterRegisters = 8;
1401 __ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters); 1225 __ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
1402 1226
1403 // Stack pointer now points to cell where return address is to be written. 1227 // Stack pointer now points to cell where return address is to be written.
1404 // Arguments are before that on the stack or in registers. 1228 // Arguments are before that on the stack or in registers.
1405 1229
1406 // Argument 10 (in stack parameter area): Pass current isolate address. 1230 // Argument 10 (in stack parameter area): Pass current isolate address.
1407 __ mov(r3, Operand(ExternalReference::isolate_address(isolate()))); 1231 __ mov(r11, Operand(ExternalReference::isolate_address(isolate())));
1408 __ StoreP(r3, MemOperand(sp, (kStackFrameExtraParamSlot + 1) * kPointerSize)); 1232 __ StoreP(r11,
1233 MemOperand(sp, (kStackFrameExtraParamSlot + 1) * kPointerSize));
1409 1234
1410 // Argument 9 is a dummy that reserves the space used for 1235 // Argument 9 is a dummy that reserves the space used for
1411 // the return address added by the ExitFrame in native calls. 1236 // the return address added by the ExitFrame in native calls.
1412 1237
1413 // Argument 8 (r10): Indicate that this is a direct call from JavaScript. 1238 // Argument 8 (r10): Indicate that this is a direct call from JavaScript.
1414 __ li(r10, Operand(1)); 1239 __ li(r10, Operand(1));
1415 1240
1416 // Argument 7 (r9): Start (high end) of backtracking stack memory area. 1241 // Argument 7 (r9): Start (high end) of backtracking stack memory area.
1417 __ mov(r3, Operand(address_of_regexp_stack_memory_address)); 1242 ExternalReference address_of_regexp_stack_memory_address =
1418 __ LoadP(r3, MemOperand(r3, 0)); 1243 ExternalReference::address_of_regexp_stack_memory_address(isolate());
1419 __ mov(r5, Operand(address_of_regexp_stack_memory_size)); 1244 ExternalReference address_of_regexp_stack_memory_size =
1420 __ LoadP(r5, MemOperand(r5, 0)); 1245 ExternalReference::address_of_regexp_stack_memory_size(isolate());
1421 __ add(r9, r3, r5); 1246 __ mov(r11, Operand(address_of_regexp_stack_memory_address));
1247 __ LoadP(r11, MemOperand(r11, 0));
1248 __ mov(r12, Operand(address_of_regexp_stack_memory_size));
1249 __ LoadP(r12, MemOperand(r12, 0));
1250 __ add(r9, r11, r12);
1422 1251
1423 // Argument 6 (r8): Set the number of capture registers to zero to force 1252 // Argument 6 (r8): Set the number of capture registers to zero to force
1424 // global egexps to behave as non-global. This does not affect non-global 1253 // global egexps to behave as non-global. This does not affect non-global
1425 // regexps. 1254 // regexps.
1426 __ li(r8, Operand::Zero()); 1255 __ li(r8, Operand::Zero());
1427 1256
1428 // Argument 5 (r7): static offsets vector buffer. 1257 // Argument 5 (r7): static offsets vector buffer.
1429 __ mov( 1258 __ mov(
1430 r7, 1259 r7,
1431 Operand(ExternalReference::address_of_static_offsets_vector(isolate()))); 1260 Operand(ExternalReference::address_of_static_offsets_vector(isolate())));
1432 1261
1433 // For arguments 4 (r6) and 3 (r5) get string length, calculate start of data
1434 // and calculate the shift of the index (0 for one-byte and 1 for two-byte).
1435 __ addi(r18, subject, Operand(SeqString::kHeaderSize - kHeapObjectTag));
1436 __ xori(r6, r6, Operand(1));
1437 // Load the length from the original subject string from the previous stack
1438 // frame. Therefore we have to use fp, which points exactly to two pointer
1439 // sizes below the previous sp. (Because creating a new stack frame pushes
1440 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.)
1441 __ LoadP(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize));
1442 // If slice offset is not 0, load the length from the original sliced string.
1443 // Argument 4, r6: End of string data 1262 // Argument 4, r6: End of string data
1444 // Argument 3, r5: Start of string data 1263 // Argument 3, r5: Start of string data
1445 // Prepare start and end index of the input. 1264 CHECK(r6.is(RegExpExecDescriptor::StringEndRegister()));
1446 __ ShiftLeft_(r11, r11, r6); 1265 CHECK(r5.is(RegExpExecDescriptor::StringStartRegister()));
1447 __ add(r11, r18, r11);
1448 __ ShiftLeft_(r5, r4, r6);
1449 __ add(r5, r11, r5);
1450
1451 __ LoadP(r18, FieldMemOperand(subject, String::kLengthOffset));
1452 __ SmiUntag(r18);
1453 __ ShiftLeft_(r6, r18, r6);
1454 __ add(r6, r11, r6);
1455 1266
1456 // Argument 2 (r4): Previous index. 1267 // Argument 2 (r4): Previous index.
1457 // Already there 1268 CHECK(r4.is(RegExpExecDescriptor::LastIndexRegister()));
1458 1269
1459 // Argument 1 (r3): Subject string. 1270 // Argument 1 (r3): Subject string.
1460 __ mr(r3, subject); 1271 CHECK(r3.is(RegExpExecDescriptor::StringRegister()));
1461 1272
1462 // Locate the code entry and call it. 1273 // Locate the code entry and call it.
1463 __ addi(code, code, Operand(Code::kHeaderSize - kHeapObjectTag)); 1274 Register code_reg = RegExpExecDescriptor::CodeRegister();
1275 __ addi(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag));
1464 1276
1465 DirectCEntryStub stub(isolate()); 1277 DirectCEntryStub stub(isolate());
1466 stub.GenerateCall(masm, code); 1278 stub.GenerateCall(masm, code_reg);
1467 1279
1468 __ LeaveExitFrame(false, no_reg, true); 1280 __ LeaveExitFrame(false, no_reg, true);
1469 1281
1470 // r3: result (int32) 1282 // Return the smi-tagged result.
1471 // subject: subject string (callee saved) 1283 __ SmiTag(r3);
1472 // regexp_data: RegExp data (callee saved)
1473 // last_match_info_elements: Last match info elements (callee saved)
1474 // Check the result.
1475 Label success;
1476 __ cmpwi(r3, Operand(1));
1477 // We expect exactly one result since we force the called regexp to behave
1478 // as non-global.
1479 __ beq(&success);
1480 Label failure;
1481 __ cmpwi(r3, Operand(NativeRegExpMacroAssembler::FAILURE));
1482 __ beq(&failure);
1483 __ cmpwi(r3, Operand(NativeRegExpMacroAssembler::EXCEPTION));
1484 // If not exception it can only be retry. Handle that in the runtime system.
1485 __ bne(&runtime);
1486 // Result must now be exception. If there is no pending exception already a
1487 // stack overflow (on the backtrack stack) was detected in RegExp code but
1488 // haven't created the exception yet. Handle that in the runtime system.
1489 // TODO(592): Rerunning the RegExp to get the stack overflow exception.
1490 __ mov(r4, Operand(isolate()->factory()->the_hole_value()));
1491 __ mov(r5, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
1492 isolate())));
1493 __ LoadP(r3, MemOperand(r5, 0));
1494 __ cmp(r3, r4);
1495 __ beq(&runtime);
1496
1497 // For exception, throw the exception again.
1498 __ TailCallRuntime(Runtime::kRegExpExecReThrow);
1499
1500 __ bind(&failure);
1501 // For failure and exception return null.
1502 __ mov(r3, Operand(isolate()->factory()->null_value()));
1503 __ addi(sp, sp, Operand(4 * kPointerSize));
1504 __ Ret(); 1284 __ Ret();
1505
1506 // Process the result from the native regexp code.
1507 __ bind(&success);
1508 __ LoadP(r4,
1509 FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset));
1510 // Calculate number of capture registers (number_of_captures + 1) * 2.
1511 // SmiToShortArrayOffset accomplishes the multiplication by 2 and
1512 // SmiUntag (which is a nop for 32-bit).
1513 __ SmiToShortArrayOffset(r4, r4);
1514 __ addi(r4, r4, Operand(2));
1515
1516 // Check that the last match info is a FixedArray.
1517 __ LoadP(last_match_info_elements, MemOperand(sp, kLastMatchInfoOffset));
1518 __ JumpIfSmi(last_match_info_elements, &runtime);
1519 // Check that the object has fast elements.
1520 __ LoadP(r3,
1521 FieldMemOperand(last_match_info_elements, HeapObject::kMapOffset));
1522 __ CompareRoot(r3, Heap::kFixedArrayMapRootIndex);
1523 __ bne(&runtime);
1524 // Check that the last match info has space for the capture registers and the
1525 // additional information.
1526 __ LoadP(
1527 r3, FieldMemOperand(last_match_info_elements, FixedArray::kLengthOffset));
1528 __ addi(r5, r4, Operand(RegExpMatchInfo::kLastMatchOverhead));
1529 __ SmiUntag(r0, r3);
1530 __ cmp(r5, r0);
1531 __ bgt(&runtime);
1532
1533 // r4: number of capture registers
1534 // subject: subject string
1535 // Store the capture count.
1536 __ SmiTag(r5, r4);
1537 __ StoreP(r5, FieldMemOperand(last_match_info_elements,
1538 RegExpMatchInfo::kNumberOfCapturesOffset),
1539 r0);
1540 // Store last subject and last input.
1541 __ StoreP(subject, FieldMemOperand(last_match_info_elements,
1542 RegExpMatchInfo::kLastSubjectOffset),
1543 r0);
1544 __ mr(r5, subject);
1545 __ RecordWriteField(last_match_info_elements,
1546 RegExpMatchInfo::kLastSubjectOffset, subject, r10,
1547 kLRHasNotBeenSaved, kDontSaveFPRegs);
1548 __ mr(subject, r5);
1549 __ StoreP(subject, FieldMemOperand(last_match_info_elements,
1550 RegExpMatchInfo::kLastInputOffset),
1551 r0);
1552 __ RecordWriteField(last_match_info_elements,
1553 RegExpMatchInfo::kLastInputOffset, subject, r10,
1554 kLRHasNotBeenSaved, kDontSaveFPRegs);
1555
1556 // Get the static offsets vector filled by the native regexp code.
1557 ExternalReference address_of_static_offsets_vector =
1558 ExternalReference::address_of_static_offsets_vector(isolate());
1559 __ mov(r5, Operand(address_of_static_offsets_vector));
1560
1561 // r4: number of capture registers
1562 // r5: offsets vector
1563 Label next_capture;
1564 // Capture register counter starts from number of capture registers and
1565 // counts down until wrapping after zero.
1566 __ addi(r3, last_match_info_elements,
1567 Operand(RegExpMatchInfo::kFirstCaptureOffset - kHeapObjectTag -
1568 kPointerSize));
1569 __ addi(r5, r5, Operand(-kIntSize)); // bias down for lwzu
1570 __ mtctr(r4);
1571 __ bind(&next_capture);
1572 // Read the value from the static offsets vector buffer.
1573 __ lwzu(r6, MemOperand(r5, kIntSize));
1574 // Store the smi value in the last match info.
1575 __ SmiTag(r6);
1576 __ StorePU(r6, MemOperand(r3, kPointerSize));
1577 __ bdnz(&next_capture);
1578
1579 // Return last match info.
1580 __ mr(r3, last_match_info_elements);
1581 __ addi(sp, sp, Operand(4 * kPointerSize));
1582 __ Ret();
1583
1584 // Do the runtime call to execute the regexp.
1585 __ bind(&runtime);
1586 __ TailCallRuntime(Runtime::kRegExpExec);
1587
1588 // Deferred code for string handling.
1589 // (5) Long external string? If not, go to (7).
1590 __ bind(&not_seq_nor_cons);
1591 // Compare flags are still set.
1592 __ bgt(&not_long_external); // Go to (7).
1593
1594 // (6) External string. Make it, offset-wise, look like a sequential string.
1595 __ bind(&external_string);
1596 __ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset));
1597 __ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
1598 if (FLAG_debug_code) {
1599 // Assert that we do not have a cons or slice (indirect strings) here.
1600 // Sequential strings have already been ruled out.
1601 STATIC_ASSERT(kIsIndirectStringMask == 1);
1602 __ andi(r0, r3, Operand(kIsIndirectStringMask));
1603 __ Assert(eq, kExternalStringExpectedButNotFound, cr0);
1604 }
1605 __ LoadP(subject,
1606 FieldMemOperand(subject, ExternalString::kResourceDataOffset));
1607 // Move the pointer so that offset-wise, it looks like a sequential string.
1608 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
1609 __ subi(subject, subject,
1610 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
1611 __ b(&seq_string); // Go to (4).
1612
1613 // (7) Short external string or not a string? If yes, bail out to runtime.
1614 __ bind(&not_long_external);
1615 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag != 0);
1616 __ andi(r0, r4, Operand(kIsNotStringMask | kShortExternalStringMask));
1617 __ bne(&runtime, cr0);
1618
1619 // (8) Sliced or thin string. Replace subject with parent. Go to (4).
1620 Label thin_string;
1621 __ cmpi(r4, Operand(kThinStringTag));
1622 __ beq(&thin_string);
1623 // Load offset into r11 and replace subject string with parent.
1624 __ LoadP(r11, FieldMemOperand(subject, SlicedString::kOffsetOffset));
1625 __ SmiUntag(r11);
1626 __ LoadP(subject, FieldMemOperand(subject, SlicedString::kParentOffset));
1627 __ b(&check_underlying); // Go to (4).
1628
1629 __ bind(&thin_string);
1630 __ LoadP(subject, FieldMemOperand(subject, ThinString::kActualOffset));
1631 __ b(&check_underlying); // Go to (4).
1632 #endif // V8_INTERPRETED_REGEXP 1285 #endif // V8_INTERPRETED_REGEXP
1633 } 1286 }
1634 1287
1635 1288
1636 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { 1289 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) {
1637 // r3 : number of arguments to the construct function 1290 // r3 : number of arguments to the construct function
1638 // r4 : the function to call 1291 // r4 : the function to call
1639 // r5 : feedback vector 1292 // r5 : feedback vector
1640 // r6 : slot in feedback vector (Smi) 1293 // r6 : slot in feedback vector (Smi)
1641 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 1294 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
(...skipping 1881 matching lines...) Expand 10 before | Expand all | Expand 10 after
3523 fp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize); 3176 fp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize);
3524 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, 3177 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
3525 kStackUnwindSpace, NULL, return_value_operand, NULL); 3178 kStackUnwindSpace, NULL, return_value_operand, NULL);
3526 } 3179 }
3527 3180
3528 #undef __ 3181 #undef __
3529 } // namespace internal 3182 } // namespace internal
3530 } // namespace v8 3183 } // namespace v8
3531 3184
3532 #endif // V8_TARGET_ARCH_PPC 3185 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/ppc/interface-descriptors-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698