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

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

Issue 252383005: MIPS: CodeStubs contain their corresponding Isolate* now. (part 1) (Closed) Base URL: https://github.com/v8/v8.git@gbl
Patch Set: Created 6 years, 8 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/mips/code-stubs-mips.h ('k') | src/mips/debug-mips.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 Label* rhs_not_nan, 487 Label* rhs_not_nan,
488 Label* slow, 488 Label* slow,
489 bool strict); 489 bool strict);
490 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, 490 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm,
491 Register lhs, 491 Register lhs,
492 Register rhs); 492 Register rhs);
493 493
494 494
495 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { 495 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
496 // Update the static counter each time a new code stub is generated. 496 // Update the static counter each time a new code stub is generated.
497 Isolate* isolate = masm->isolate(); 497 isolate()->counters()->code_stubs()->Increment();
498 isolate->counters()->code_stubs()->Increment();
499 498
500 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate); 499 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate());
501 int param_count = descriptor->register_param_count_; 500 int param_count = descriptor->register_param_count_;
502 { 501 {
503 // Call the runtime system in a fresh internal frame. 502 // Call the runtime system in a fresh internal frame.
504 FrameScope scope(masm, StackFrame::INTERNAL); 503 FrameScope scope(masm, StackFrame::INTERNAL);
505 ASSERT(descriptor->register_param_count_ == 0 || 504 ASSERT(descriptor->register_param_count_ == 0 ||
506 a0.is(descriptor->register_params_[param_count - 1])); 505 a0.is(descriptor->register_params_[param_count - 1]));
507 // Push arguments, adjust sp. 506 // Push arguments, adjust sp.
508 __ Subu(sp, sp, Operand(param_count * kPointerSize)); 507 __ Subu(sp, sp, Operand(param_count * kPointerSize));
509 for (int i = 0; i < param_count; ++i) { 508 for (int i = 0; i < param_count; ++i) {
510 // Store argument to stack. 509 // Store argument to stack.
511 __ sw(descriptor->register_params_[i], 510 __ sw(descriptor->register_params_[i],
512 MemOperand(sp, (param_count-1-i) * kPointerSize)); 511 MemOperand(sp, (param_count-1-i) * kPointerSize));
513 } 512 }
514 ExternalReference miss = descriptor->miss_handler(); 513 ExternalReference miss = descriptor->miss_handler();
515 __ CallExternalReference(miss, descriptor->register_param_count_); 514 __ CallExternalReference(miss, descriptor->register_param_count_);
516 } 515 }
517 516
518 __ Ret(); 517 __ Ret();
519 } 518 }
520 519
521 520
522 // Takes a Smi and converts to an IEEE 64 bit floating point value in two 521 // Takes a Smi and converts to an IEEE 64 bit floating point value in two
523 // registers. The format is 1 sign bit, 11 exponent bits (biased 1023) and 522 // registers. The format is 1 sign bit, 11 exponent bits (biased 1023) and
524 // 52 fraction bits (20 in the first word, 32 in the second). Zeros is a 523 // 52 fraction bits (20 in the first word, 32 in the second). Zeros is a
525 // scratch register. Destroys the source register. No GC occurs during this 524 // scratch register. Destroys the source register. No GC occurs during this
526 // stub so you don't have to set up the frame. 525 // stub so you don't have to set up the frame.
527 class ConvertToDoubleStub : public PlatformCodeStub { 526 class ConvertToDoubleStub : public PlatformCodeStub {
528 public: 527 public:
529 ConvertToDoubleStub(Register result_reg_1, 528 ConvertToDoubleStub(Isolate* isolate,
529 Register result_reg_1,
530 Register result_reg_2, 530 Register result_reg_2,
531 Register source_reg, 531 Register source_reg,
532 Register scratch_reg) 532 Register scratch_reg)
533 : result1_(result_reg_1), 533 : PlatformCodeStub(isolate),
534 result1_(result_reg_1),
534 result2_(result_reg_2), 535 result2_(result_reg_2),
535 source_(source_reg), 536 source_(source_reg),
536 zeros_(scratch_reg) { } 537 zeros_(scratch_reg) { }
537 538
538 private: 539 private:
539 Register result1_; 540 Register result1_;
540 Register result2_; 541 Register result2_;
541 Register source_; 542 Register source_;
542 Register zeros_; 543 Register zeros_;
543 544
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 755
755 __ bind(&done); 756 __ bind(&done);
756 757
757 __ Pop(scratch, scratch2, scratch3); 758 __ Pop(scratch, scratch2, scratch3);
758 __ Ret(); 759 __ Ret();
759 } 760 }
760 761
761 762
762 void WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime( 763 void WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(
763 Isolate* isolate) { 764 Isolate* isolate) {
764 WriteInt32ToHeapNumberStub stub1(a1, v0, a2, a3); 765 WriteInt32ToHeapNumberStub stub1(isolate, a1, v0, a2, a3);
765 WriteInt32ToHeapNumberStub stub2(a2, v0, a3, a0); 766 WriteInt32ToHeapNumberStub stub2(isolate, a2, v0, a3, a0);
766 stub1.GetCode(isolate); 767 stub1.GetCode(isolate);
767 stub2.GetCode(isolate); 768 stub2.GetCode(isolate);
768 } 769 }
769 770
770 771
771 // See comment for class, this does NOT work for int32's that are in Smi range. 772 // See comment for class, this does NOT work for int32's that are in Smi range.
772 void WriteInt32ToHeapNumberStub::Generate(MacroAssembler* masm) { 773 void WriteInt32ToHeapNumberStub::Generate(MacroAssembler* masm) {
773 Label max_negative_int; 774 Label max_negative_int;
774 // the_int_ has the answer which is a signed int32 but not a Smi. 775 // the_int_ has the answer which is a signed int32 but not a Smi.
775 // We test for the special value that has a different exponent. 776 // We test for the special value that has a different exponent.
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 // In cases 3 and 4 we have found out we were dealing with a number-number 1148 // In cases 3 and 4 we have found out we were dealing with a number-number
1148 // comparison and the numbers have been loaded into f12 and f14 as doubles, 1149 // comparison and the numbers have been loaded into f12 and f14 as doubles,
1149 // or in GP registers (a0, a1, a2, a3) depending on the presence of the FPU. 1150 // or in GP registers (a0, a1, a2, a3) depending on the presence of the FPU.
1150 EmitSmiNonsmiComparison(masm, lhs, rhs, 1151 EmitSmiNonsmiComparison(masm, lhs, rhs,
1151 &both_loaded_as_doubles, &slow, strict()); 1152 &both_loaded_as_doubles, &slow, strict());
1152 1153
1153 __ bind(&both_loaded_as_doubles); 1154 __ bind(&both_loaded_as_doubles);
1154 // f12, f14 are the double representations of the left hand side 1155 // f12, f14 are the double representations of the left hand side
1155 // and the right hand side if we have FPU. Otherwise a2, a3 represent 1156 // and the right hand side if we have FPU. Otherwise a2, a3 represent
1156 // left hand side and a0, a1 represent right hand side. 1157 // left hand side and a0, a1 represent right hand side.
1157
1158 Isolate* isolate = masm->isolate();
1159 Label nan; 1158 Label nan;
1160 __ li(t0, Operand(LESS)); 1159 __ li(t0, Operand(LESS));
1161 __ li(t1, Operand(GREATER)); 1160 __ li(t1, Operand(GREATER));
1162 __ li(t2, Operand(EQUAL)); 1161 __ li(t2, Operand(EQUAL));
1163 1162
1164 // Check if either rhs or lhs is NaN. 1163 // Check if either rhs or lhs is NaN.
1165 __ BranchF(NULL, &nan, eq, f12, f14); 1164 __ BranchF(NULL, &nan, eq, f12, f14);
1166 1165
1167 // Check if LESS condition is satisfied. If true, move conditionally 1166 // Check if LESS condition is satisfied. If true, move conditionally
1168 // result to v0. 1167 // result to v0.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 EmitCheckForInternalizedStringsOrObjects( 1222 EmitCheckForInternalizedStringsOrObjects(
1224 masm, lhs, rhs, &flat_string_check, &slow); 1223 masm, lhs, rhs, &flat_string_check, &slow);
1225 } 1224 }
1226 1225
1227 // Check for both being sequential ASCII strings, and inline if that is the 1226 // Check for both being sequential ASCII strings, and inline if that is the
1228 // case. 1227 // case.
1229 __ bind(&flat_string_check); 1228 __ bind(&flat_string_check);
1230 1229
1231 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, a2, a3, &slow); 1230 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, a2, a3, &slow);
1232 1231
1233 __ IncrementCounter(isolate->counters()->string_compare_native(), 1, a2, a3); 1232 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, a2,
1233 a3);
1234 if (cc == eq) { 1234 if (cc == eq) {
1235 StringCompareStub::GenerateFlatAsciiStringEquals(masm, 1235 StringCompareStub::GenerateFlatAsciiStringEquals(masm,
1236 lhs, 1236 lhs,
1237 rhs, 1237 rhs,
1238 a2, 1238 a2,
1239 a3, 1239 a3,
1240 t0); 1240 t0);
1241 } else { 1241 } else {
1242 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, 1242 StringCompareStub::GenerateCompareFlatAsciiStrings(masm,
1243 lhs, 1243 lhs,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1311 __ MultiPush(kJSCallerSaved | ra.bit()); 1311 __ MultiPush(kJSCallerSaved | ra.bit());
1312 if (save_doubles_ == kSaveFPRegs) { 1312 if (save_doubles_ == kSaveFPRegs) {
1313 __ MultiPushFPU(kCallerSavedFPU); 1313 __ MultiPushFPU(kCallerSavedFPU);
1314 } 1314 }
1315 const int argument_count = 1; 1315 const int argument_count = 1;
1316 const int fp_argument_count = 0; 1316 const int fp_argument_count = 0;
1317 const Register scratch = a1; 1317 const Register scratch = a1;
1318 1318
1319 AllowExternalCallThatCantCauseGC scope(masm); 1319 AllowExternalCallThatCantCauseGC scope(masm);
1320 __ PrepareCallCFunction(argument_count, fp_argument_count, scratch); 1320 __ PrepareCallCFunction(argument_count, fp_argument_count, scratch);
1321 __ li(a0, Operand(ExternalReference::isolate_address(masm->isolate()))); 1321 __ li(a0, Operand(ExternalReference::isolate_address(isolate())));
1322 __ CallCFunction( 1322 __ CallCFunction(
1323 ExternalReference::store_buffer_overflow_function(masm->isolate()), 1323 ExternalReference::store_buffer_overflow_function(isolate()),
1324 argument_count); 1324 argument_count);
1325 if (save_doubles_ == kSaveFPRegs) { 1325 if (save_doubles_ == kSaveFPRegs) {
1326 __ MultiPopFPU(kCallerSavedFPU); 1326 __ MultiPopFPU(kCallerSavedFPU);
1327 } 1327 }
1328 1328
1329 __ MultiPop(kJSCallerSaved | ra.bit()); 1329 __ MultiPop(kJSCallerSaved | ra.bit());
1330 __ Ret(); 1330 __ Ret();
1331 } 1331 }
1332 1332
1333 1333
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 __ div_d(double_result, double_result, double_scratch); 1442 __ div_d(double_result, double_result, double_scratch);
1443 __ jmp(&done); 1443 __ jmp(&done);
1444 } 1444 }
1445 1445
1446 __ push(ra); 1446 __ push(ra);
1447 { 1447 {
1448 AllowExternalCallThatCantCauseGC scope(masm); 1448 AllowExternalCallThatCantCauseGC scope(masm);
1449 __ PrepareCallCFunction(0, 2, scratch2); 1449 __ PrepareCallCFunction(0, 2, scratch2);
1450 __ MovToFloatParameters(double_base, double_exponent); 1450 __ MovToFloatParameters(double_base, double_exponent);
1451 __ CallCFunction( 1451 __ CallCFunction(
1452 ExternalReference::power_double_double_function(masm->isolate()), 1452 ExternalReference::power_double_double_function(isolate()),
1453 0, 2); 1453 0, 2);
1454 } 1454 }
1455 __ pop(ra); 1455 __ pop(ra);
1456 __ MovFromFloatResult(double_result); 1456 __ MovFromFloatResult(double_result);
1457 __ jmp(&done); 1457 __ jmp(&done);
1458 1458
1459 __ bind(&int_exponent_convert); 1459 __ bind(&int_exponent_convert);
1460 } 1460 }
1461 1461
1462 // Calculate power with integer exponent. 1462 // Calculate power with integer exponent.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1503 // Test whether result is zero. Bail out to check for subnormal result. 1503 // Test whether result is zero. Bail out to check for subnormal result.
1504 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases. 1504 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases.
1505 __ BranchF(&done, NULL, ne, double_result, kDoubleRegZero); 1505 __ BranchF(&done, NULL, ne, double_result, kDoubleRegZero);
1506 1506
1507 // double_exponent may not contain the exponent value if the input was a 1507 // double_exponent may not contain the exponent value if the input was a
1508 // smi. We set it with exponent value before bailing out. 1508 // smi. We set it with exponent value before bailing out.
1509 __ mtc1(exponent, single_scratch); 1509 __ mtc1(exponent, single_scratch);
1510 __ cvt_d_w(double_exponent, single_scratch); 1510 __ cvt_d_w(double_exponent, single_scratch);
1511 1511
1512 // Returning or bailing out. 1512 // Returning or bailing out.
1513 Counters* counters = masm->isolate()->counters(); 1513 Counters* counters = isolate()->counters();
1514 if (exponent_type_ == ON_STACK) { 1514 if (exponent_type_ == ON_STACK) {
1515 // The arguments are still on the stack. 1515 // The arguments are still on the stack.
1516 __ bind(&call_runtime); 1516 __ bind(&call_runtime);
1517 __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1); 1517 __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1);
1518 1518
1519 // The stub is called from non-optimized code, which expects the result 1519 // The stub is called from non-optimized code, which expects the result
1520 // as heap number in exponent. 1520 // as heap number in exponent.
1521 __ bind(&done); 1521 __ bind(&done);
1522 __ AllocateHeapNumber( 1522 __ AllocateHeapNumber(
1523 heapnumber, scratch, scratch2, heapnumbermap, &call_runtime); 1523 heapnumber, scratch, scratch2, heapnumbermap, &call_runtime);
1524 __ sdc1(double_result, 1524 __ sdc1(double_result,
1525 FieldMemOperand(heapnumber, HeapNumber::kValueOffset)); 1525 FieldMemOperand(heapnumber, HeapNumber::kValueOffset));
1526 ASSERT(heapnumber.is(v0)); 1526 ASSERT(heapnumber.is(v0));
1527 __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2); 1527 __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2);
1528 __ DropAndRet(2); 1528 __ DropAndRet(2);
1529 } else { 1529 } else {
1530 __ push(ra); 1530 __ push(ra);
1531 { 1531 {
1532 AllowExternalCallThatCantCauseGC scope(masm); 1532 AllowExternalCallThatCantCauseGC scope(masm);
1533 __ PrepareCallCFunction(0, 2, scratch); 1533 __ PrepareCallCFunction(0, 2, scratch);
1534 __ MovToFloatParameters(double_base, double_exponent); 1534 __ MovToFloatParameters(double_base, double_exponent);
1535 __ CallCFunction( 1535 __ CallCFunction(
1536 ExternalReference::power_double_double_function(masm->isolate()), 1536 ExternalReference::power_double_double_function(isolate()),
1537 0, 2); 1537 0, 2);
1538 } 1538 }
1539 __ pop(ra); 1539 __ pop(ra);
1540 __ MovFromFloatResult(double_result); 1540 __ MovFromFloatResult(double_result);
1541 1541
1542 __ bind(&done); 1542 __ bind(&done);
1543 __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2); 1543 __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2);
1544 __ Ret(); 1544 __ Ret();
1545 } 1545 }
1546 } 1546 }
(...skipping 13 matching lines...) Expand all
1560 CreateAllocationSiteStub::GenerateAheadOfTime(isolate); 1560 CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
1561 BinaryOpICStub::GenerateAheadOfTime(isolate); 1561 BinaryOpICStub::GenerateAheadOfTime(isolate);
1562 StoreRegistersStateStub::GenerateAheadOfTime(isolate); 1562 StoreRegistersStateStub::GenerateAheadOfTime(isolate);
1563 RestoreRegistersStateStub::GenerateAheadOfTime(isolate); 1563 RestoreRegistersStateStub::GenerateAheadOfTime(isolate);
1564 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate); 1564 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
1565 } 1565 }
1566 1566
1567 1567
1568 void StoreRegistersStateStub::GenerateAheadOfTime( 1568 void StoreRegistersStateStub::GenerateAheadOfTime(
1569 Isolate* isolate) { 1569 Isolate* isolate) {
1570 StoreRegistersStateStub stub1(kDontSaveFPRegs); 1570 StoreRegistersStateStub stub1(isolate, kDontSaveFPRegs);
1571 stub1.GetCode(isolate); 1571 stub1.GetCode(isolate);
1572 // Hydrogen code stubs need stub2 at snapshot time. 1572 // Hydrogen code stubs need stub2 at snapshot time.
1573 StoreRegistersStateStub stub2(kSaveFPRegs); 1573 StoreRegistersStateStub stub2(isolate, kSaveFPRegs);
1574 stub2.GetCode(isolate); 1574 stub2.GetCode(isolate);
1575 } 1575 }
1576 1576
1577 1577
1578 void RestoreRegistersStateStub::GenerateAheadOfTime( 1578 void RestoreRegistersStateStub::GenerateAheadOfTime(
1579 Isolate* isolate) { 1579 Isolate* isolate) {
1580 RestoreRegistersStateStub stub1(kDontSaveFPRegs); 1580 RestoreRegistersStateStub stub1(isolate, kDontSaveFPRegs);
1581 stub1.GetCode(isolate); 1581 stub1.GetCode(isolate);
1582 // Hydrogen code stubs need stub2 at snapshot time. 1582 // Hydrogen code stubs need stub2 at snapshot time.
1583 RestoreRegistersStateStub stub2(kSaveFPRegs); 1583 RestoreRegistersStateStub stub2(isolate, kSaveFPRegs);
1584 stub2.GetCode(isolate); 1584 stub2.GetCode(isolate);
1585 } 1585 }
1586 1586
1587 1587
1588 void CodeStub::GenerateFPStubs(Isolate* isolate) { 1588 void CodeStub::GenerateFPStubs(Isolate* isolate) {
1589 SaveFPRegsMode mode = kSaveFPRegs; 1589 SaveFPRegsMode mode = kSaveFPRegs;
1590 CEntryStub save_doubles(1, mode); 1590 CEntryStub save_doubles(isolate, 1, mode);
1591 StoreBufferOverflowStub stub(mode); 1591 StoreBufferOverflowStub stub(isolate, mode);
1592 // These stubs might already be in the snapshot, detect that and don't 1592 // These stubs might already be in the snapshot, detect that and don't
1593 // regenerate, which would lead to code stub initialization state being messed 1593 // regenerate, which would lead to code stub initialization state being messed
1594 // up. 1594 // up.
1595 Code* save_doubles_code; 1595 Code* save_doubles_code;
1596 if (!save_doubles.FindCodeInCache(&save_doubles_code, isolate)) { 1596 if (!save_doubles.FindCodeInCache(&save_doubles_code, isolate)) {
1597 save_doubles_code = *save_doubles.GetCode(isolate); 1597 save_doubles_code = *save_doubles.GetCode(isolate);
1598 } 1598 }
1599 Code* store_buffer_overflow_code; 1599 Code* store_buffer_overflow_code;
1600 if (!stub.FindCodeInCache(&store_buffer_overflow_code, isolate)) { 1600 if (!stub.FindCodeInCache(&store_buffer_overflow_code, isolate)) {
1601 store_buffer_overflow_code = *stub.GetCode(isolate); 1601 store_buffer_overflow_code = *stub.GetCode(isolate);
1602 } 1602 }
1603 isolate->set_fp_stubs_generated(true); 1603 isolate->set_fp_stubs_generated(true);
1604 } 1604 }
1605 1605
1606 1606
1607 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { 1607 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
1608 CEntryStub stub(1, kDontSaveFPRegs); 1608 CEntryStub stub(isolate, 1, kDontSaveFPRegs);
1609 stub.GetCode(isolate); 1609 stub.GetCode(isolate);
1610 } 1610 }
1611 1611
1612 1612
1613 void CEntryStub::Generate(MacroAssembler* masm) { 1613 void CEntryStub::Generate(MacroAssembler* masm) {
1614 // Called from JavaScript; parameters are on stack as if calling JS function 1614 // Called from JavaScript; parameters are on stack as if calling JS function
1615 // s0: number of arguments including receiver 1615 // s0: number of arguments including receiver
1616 // s1: size of arguments excluding receiver 1616 // s1: size of arguments excluding receiver
1617 // s2: pointer to builtin function 1617 // s2: pointer to builtin function
1618 // fp: frame pointer (restored after C call) 1618 // fp: frame pointer (restored after C call)
(...skipping 11 matching lines...) Expand all
1630 __ Addu(s1, sp, s1); 1630 __ Addu(s1, sp, s1);
1631 1631
1632 // Enter the exit frame that transitions from JavaScript to C++. 1632 // Enter the exit frame that transitions from JavaScript to C++.
1633 FrameScope scope(masm, StackFrame::MANUAL); 1633 FrameScope scope(masm, StackFrame::MANUAL);
1634 __ EnterExitFrame(save_doubles_); 1634 __ EnterExitFrame(save_doubles_);
1635 1635
1636 // s0: number of arguments including receiver (C callee-saved) 1636 // s0: number of arguments including receiver (C callee-saved)
1637 // s1: pointer to first argument (C callee-saved) 1637 // s1: pointer to first argument (C callee-saved)
1638 // s2: pointer to builtin function (C callee-saved) 1638 // s2: pointer to builtin function (C callee-saved)
1639 1639
1640 Isolate* isolate = masm->isolate();
1641
1642 // Prepare arguments for C routine. 1640 // Prepare arguments for C routine.
1643 // a0 = argc 1641 // a0 = argc
1644 __ mov(a0, s0); 1642 __ mov(a0, s0);
1645 // a1 = argv (set in the delay slot after find_ra below). 1643 // a1 = argv (set in the delay slot after find_ra below).
1646 1644
1647 // We are calling compiled C/C++ code. a0 and a1 hold our two arguments. We 1645 // We are calling compiled C/C++ code. a0 and a1 hold our two arguments. We
1648 // also need to reserve the 4 argument slots on the stack. 1646 // also need to reserve the 4 argument slots on the stack.
1649 1647
1650 __ AssertStackIsAligned(); 1648 __ AssertStackIsAligned();
1651 1649
1652 __ li(a2, Operand(ExternalReference::isolate_address(isolate))); 1650 __ li(a2, Operand(ExternalReference::isolate_address(isolate())));
1653 1651
1654 // To let the GC traverse the return address of the exit frames, we need to 1652 // To let the GC traverse the return address of the exit frames, we need to
1655 // know where the return address is. The CEntryStub is unmovable, so 1653 // know where the return address is. The CEntryStub is unmovable, so
1656 // we can store the address on the stack to be able to find it again and 1654 // we can store the address on the stack to be able to find it again and
1657 // we never have to restore it, because it will not change. 1655 // we never have to restore it, because it will not change.
1658 { Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm); 1656 { Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm);
1659 // This branch-and-link sequence is needed to find the current PC on mips, 1657 // This branch-and-link sequence is needed to find the current PC on mips,
1660 // saved to the ra register. 1658 // saved to the ra register.
1661 // Use masm-> here instead of the double-underscore macro since extra 1659 // Use masm-> here instead of the double-underscore macro since extra
1662 // coverage code can interfere with the proper calculation of ra. 1660 // coverage code can interfere with the proper calculation of ra.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1694 __ stop("The hole escaped"); 1692 __ stop("The hole escaped");
1695 __ bind(&okay); 1693 __ bind(&okay);
1696 } 1694 }
1697 1695
1698 // Check result for exception sentinel. 1696 // Check result for exception sentinel.
1699 Label exception_returned; 1697 Label exception_returned;
1700 __ LoadRoot(t0, Heap::kExceptionRootIndex); 1698 __ LoadRoot(t0, Heap::kExceptionRootIndex);
1701 __ Branch(&exception_returned, eq, t0, Operand(v0)); 1699 __ Branch(&exception_returned, eq, t0, Operand(v0));
1702 1700
1703 ExternalReference pending_exception_address( 1701 ExternalReference pending_exception_address(
1704 Isolate::kPendingExceptionAddress, isolate); 1702 Isolate::kPendingExceptionAddress, isolate());
1705 1703
1706 // Check that there is no pending exception, otherwise we 1704 // Check that there is no pending exception, otherwise we
1707 // should have returned the exception sentinel. 1705 // should have returned the exception sentinel.
1708 if (FLAG_debug_code) { 1706 if (FLAG_debug_code) {
1709 Label okay; 1707 Label okay;
1710 __ li(a2, Operand(pending_exception_address)); 1708 __ li(a2, Operand(pending_exception_address));
1711 __ lw(a2, MemOperand(a2)); 1709 __ lw(a2, MemOperand(a2));
1712 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); 1710 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
1713 // Cannot use check here as it attempts to generate call into runtime. 1711 // Cannot use check here as it attempts to generate call into runtime.
1714 __ Branch(&okay, eq, t0, Operand(a2)); 1712 __ Branch(&okay, eq, t0, Operand(a2));
1715 __ stop("Unexpected pending exception"); 1713 __ stop("Unexpected pending exception");
1716 __ bind(&okay); 1714 __ bind(&okay);
1717 } 1715 }
1718 1716
1719 // Exit C frame and return. 1717 // Exit C frame and return.
1720 // v0:v1: result 1718 // v0:v1: result
1721 // sp: stack pointer 1719 // sp: stack pointer
1722 // fp: frame pointer 1720 // fp: frame pointer
1723 // s0: still holds argc (callee-saved). 1721 // s0: still holds argc (callee-saved).
1724 __ LeaveExitFrame(save_doubles_, s0, true, EMIT_RETURN); 1722 __ LeaveExitFrame(save_doubles_, s0, true, EMIT_RETURN);
1725 1723
1726 // Handling of exception. 1724 // Handling of exception.
1727 __ bind(&exception_returned); 1725 __ bind(&exception_returned);
1728 1726
1729 // Retrieve the pending exception. 1727 // Retrieve the pending exception.
1730 __ li(a2, Operand(pending_exception_address)); 1728 __ li(a2, Operand(pending_exception_address));
1731 __ lw(v0, MemOperand(a2)); 1729 __ lw(v0, MemOperand(a2));
1732 1730
1733 // Clear the pending exception. 1731 // Clear the pending exception.
1734 __ li(a3, Operand(isolate->factory()->the_hole_value())); 1732 __ li(a3, Operand(isolate()->factory()->the_hole_value()));
1735 __ sw(a3, MemOperand(a2)); 1733 __ sw(a3, MemOperand(a2));
1736 1734
1737 // Special handling of termination exceptions which are uncatchable 1735 // Special handling of termination exceptions which are uncatchable
1738 // by javascript code. 1736 // by javascript code.
1739 Label throw_termination_exception; 1737 Label throw_termination_exception;
1740 __ LoadRoot(t0, Heap::kTerminationExceptionRootIndex); 1738 __ LoadRoot(t0, Heap::kTerminationExceptionRootIndex);
1741 __ Branch(&throw_termination_exception, eq, v0, Operand(t0)); 1739 __ Branch(&throw_termination_exception, eq, v0, Operand(t0));
1742 1740
1743 // Handle normal exception. 1741 // Handle normal exception.
1744 __ Throw(v0); 1742 __ Throw(v0);
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
2054 // Before null, smi and string value checks, check that the rhs is a function 2052 // Before null, smi and string value checks, check that the rhs is a function
2055 // as for a non-function rhs an exception needs to be thrown. 2053 // as for a non-function rhs an exception needs to be thrown.
2056 __ JumpIfSmi(function, &slow); 2054 __ JumpIfSmi(function, &slow);
2057 __ GetObjectType(function, scratch2, scratch); 2055 __ GetObjectType(function, scratch2, scratch);
2058 __ Branch(&slow, ne, scratch, Operand(JS_FUNCTION_TYPE)); 2056 __ Branch(&slow, ne, scratch, Operand(JS_FUNCTION_TYPE));
2059 2057
2060 // Null is not instance of anything. 2058 // Null is not instance of anything.
2061 __ Branch(&object_not_null, 2059 __ Branch(&object_not_null,
2062 ne, 2060 ne,
2063 scratch, 2061 scratch,
2064 Operand(masm->isolate()->factory()->null_value())); 2062 Operand(isolate()->factory()->null_value()));
2065 __ li(v0, Operand(Smi::FromInt(1))); 2063 __ li(v0, Operand(Smi::FromInt(1)));
2066 __ DropAndRet(HasArgsInRegisters() ? 0 : 2); 2064 __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
2067 2065
2068 __ bind(&object_not_null); 2066 __ bind(&object_not_null);
2069 // Smi values are not instances of anything. 2067 // Smi values are not instances of anything.
2070 __ JumpIfNotSmi(object, &object_not_null_or_smi); 2068 __ JumpIfNotSmi(object, &object_not_null_or_smi);
2071 __ li(v0, Operand(Smi::FromInt(1))); 2069 __ li(v0, Operand(Smi::FromInt(1)));
2072 __ DropAndRet(HasArgsInRegisters() ? 0 : 2); 2070 __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
2073 2071
2074 __ bind(&object_not_null_or_smi); 2072 __ bind(&object_not_null_or_smi);
(...skipping 27 matching lines...) Expand all
2102 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { 2100 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
2103 Label miss; 2101 Label miss;
2104 Register receiver; 2102 Register receiver;
2105 if (kind() == Code::KEYED_LOAD_IC) { 2103 if (kind() == Code::KEYED_LOAD_IC) {
2106 // ----------- S t a t e ------------- 2104 // ----------- S t a t e -------------
2107 // -- ra : return address 2105 // -- ra : return address
2108 // -- a0 : key 2106 // -- a0 : key
2109 // -- a1 : receiver 2107 // -- a1 : receiver
2110 // ----------------------------------- 2108 // -----------------------------------
2111 __ Branch(&miss, ne, a0, 2109 __ Branch(&miss, ne, a0,
2112 Operand(masm->isolate()->factory()->prototype_string())); 2110 Operand(isolate()->factory()->prototype_string()));
2113 receiver = a1; 2111 receiver = a1;
2114 } else { 2112 } else {
2115 ASSERT(kind() == Code::LOAD_IC); 2113 ASSERT(kind() == Code::LOAD_IC);
2116 // ----------- S t a t e ------------- 2114 // ----------- S t a t e -------------
2117 // -- a2 : name 2115 // -- a2 : name
2118 // -- ra : return address 2116 // -- ra : return address
2119 // -- a0 : receiver 2117 // -- a0 : receiver
2120 // -- sp[0] : receiver 2118 // -- sp[0] : receiver
2121 // ----------------------------------- 2119 // -----------------------------------
2122 receiver = a0; 2120 receiver = a0;
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
2543 // sp[0]: last_match_info (expected JSArray) 2541 // sp[0]: last_match_info (expected JSArray)
2544 // sp[4]: previous index 2542 // sp[4]: previous index
2545 // sp[8]: subject string 2543 // sp[8]: subject string
2546 // sp[12]: JSRegExp object 2544 // sp[12]: JSRegExp object
2547 2545
2548 const int kLastMatchInfoOffset = 0 * kPointerSize; 2546 const int kLastMatchInfoOffset = 0 * kPointerSize;
2549 const int kPreviousIndexOffset = 1 * kPointerSize; 2547 const int kPreviousIndexOffset = 1 * kPointerSize;
2550 const int kSubjectOffset = 2 * kPointerSize; 2548 const int kSubjectOffset = 2 * kPointerSize;
2551 const int kJSRegExpOffset = 3 * kPointerSize; 2549 const int kJSRegExpOffset = 3 * kPointerSize;
2552 2550
2553 Isolate* isolate = masm->isolate();
2554
2555 Label runtime; 2551 Label runtime;
2556 // Allocation of registers for this function. These are in callee save 2552 // Allocation of registers for this function. These are in callee save
2557 // registers and will be preserved by the call to the native RegExp code, as 2553 // registers and will be preserved by the call to the native RegExp code, as
2558 // this code is called using the normal C calling convention. When calling 2554 // this code is called using the normal C calling convention. When calling
2559 // directly from generated code the native RegExp code will not do a GC and 2555 // directly from generated code the native RegExp code will not do a GC and
2560 // therefore the content of these registers are safe to use after the call. 2556 // therefore the content of these registers are safe to use after the call.
2561 // MIPS - using s0..s2, since we are not using CEntry Stub. 2557 // MIPS - using s0..s2, since we are not using CEntry Stub.
2562 Register subject = s0; 2558 Register subject = s0;
2563 Register regexp_data = s1; 2559 Register regexp_data = s1;
2564 Register last_match_info_elements = s2; 2560 Register last_match_info_elements = s2;
2565 2561
2566 // Ensure that a RegExp stack is allocated. 2562 // Ensure that a RegExp stack is allocated.
2567 ExternalReference address_of_regexp_stack_memory_address = 2563 ExternalReference address_of_regexp_stack_memory_address =
2568 ExternalReference::address_of_regexp_stack_memory_address( 2564 ExternalReference::address_of_regexp_stack_memory_address(
2569 isolate); 2565 isolate());
2570 ExternalReference address_of_regexp_stack_memory_size = 2566 ExternalReference address_of_regexp_stack_memory_size =
2571 ExternalReference::address_of_regexp_stack_memory_size(isolate); 2567 ExternalReference::address_of_regexp_stack_memory_size(isolate());
2572 __ li(a0, Operand(address_of_regexp_stack_memory_size)); 2568 __ li(a0, Operand(address_of_regexp_stack_memory_size));
2573 __ lw(a0, MemOperand(a0, 0)); 2569 __ lw(a0, MemOperand(a0, 0));
2574 __ Branch(&runtime, eq, a0, Operand(zero_reg)); 2570 __ Branch(&runtime, eq, a0, Operand(zero_reg));
2575 2571
2576 // Check that the first argument is a JSRegExp object. 2572 // Check that the first argument is a JSRegExp object.
2577 __ lw(a0, MemOperand(sp, kJSRegExpOffset)); 2573 __ lw(a0, MemOperand(sp, kJSRegExpOffset));
2578 STATIC_ASSERT(kSmiTag == 0); 2574 STATIC_ASSERT(kSmiTag == 0);
2579 __ JumpIfSmi(a0, &runtime); 2575 __ JumpIfSmi(a0, &runtime);
2580 __ GetObjectType(a0, a1, a1); 2576 __ GetObjectType(a0, a1, a1);
2581 __ Branch(&runtime, ne, a1, Operand(JS_REGEXP_TYPE)); 2577 __ Branch(&runtime, ne, a1, Operand(JS_REGEXP_TYPE));
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
2708 // encoding. If it has, the field contains a code object otherwise it contains 2704 // encoding. If it has, the field contains a code object otherwise it contains
2709 // a smi (code flushing support). 2705 // a smi (code flushing support).
2710 __ JumpIfSmi(t9, &runtime); 2706 __ JumpIfSmi(t9, &runtime);
2711 2707
2712 // a1: previous index 2708 // a1: previous index
2713 // a3: encoding of subject string (1 if ASCII, 0 if two_byte); 2709 // a3: encoding of subject string (1 if ASCII, 0 if two_byte);
2714 // t9: code 2710 // t9: code
2715 // subject: Subject string 2711 // subject: Subject string
2716 // regexp_data: RegExp data (FixedArray) 2712 // regexp_data: RegExp data (FixedArray)
2717 // All checks done. Now push arguments for native regexp code. 2713 // All checks done. Now push arguments for native regexp code.
2718 __ IncrementCounter(isolate->counters()->regexp_entry_native(), 2714 __ IncrementCounter(isolate()->counters()->regexp_entry_native(),
2719 1, a0, a2); 2715 1, a0, a2);
2720 2716
2721 // Isolates: note we add an additional parameter here (isolate pointer). 2717 // Isolates: note we add an additional parameter here (isolate pointer).
2722 const int kRegExpExecuteArguments = 9; 2718 const int kRegExpExecuteArguments = 9;
2723 const int kParameterRegisters = 4; 2719 const int kParameterRegisters = 4;
2724 __ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters); 2720 __ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
2725 2721
2726 // Stack pointer now points to cell where return address is to be written. 2722 // Stack pointer now points to cell where return address is to be written.
2727 // Arguments are before that on the stack or in registers, meaning we 2723 // Arguments are before that on the stack or in registers, meaning we
2728 // treat the return address as argument 5. Thus every argument after that 2724 // treat the return address as argument 5. Thus every argument after that
2729 // needs to be shifted back by 1. Since DirectCEntryStub will handle 2725 // needs to be shifted back by 1. Since DirectCEntryStub will handle
2730 // allocating space for the c argument slots, we don't need to calculate 2726 // allocating space for the c argument slots, we don't need to calculate
2731 // that into the argument positions on the stack. This is how the stack will 2727 // that into the argument positions on the stack. This is how the stack will
2732 // look (sp meaning the value of sp at this moment): 2728 // look (sp meaning the value of sp at this moment):
2733 // [sp + 5] - Argument 9 2729 // [sp + 5] - Argument 9
2734 // [sp + 4] - Argument 8 2730 // [sp + 4] - Argument 8
2735 // [sp + 3] - Argument 7 2731 // [sp + 3] - Argument 7
2736 // [sp + 2] - Argument 6 2732 // [sp + 2] - Argument 6
2737 // [sp + 1] - Argument 5 2733 // [sp + 1] - Argument 5
2738 // [sp + 0] - saved ra 2734 // [sp + 0] - saved ra
2739 2735
2740 // Argument 9: Pass current isolate address. 2736 // Argument 9: Pass current isolate address.
2741 // CFunctionArgumentOperand handles MIPS stack argument slots. 2737 // CFunctionArgumentOperand handles MIPS stack argument slots.
2742 __ li(a0, Operand(ExternalReference::isolate_address(isolate))); 2738 __ li(a0, Operand(ExternalReference::isolate_address(isolate())));
2743 __ sw(a0, MemOperand(sp, 5 * kPointerSize)); 2739 __ sw(a0, MemOperand(sp, 5 * kPointerSize));
2744 2740
2745 // Argument 8: Indicate that this is a direct call from JavaScript. 2741 // Argument 8: Indicate that this is a direct call from JavaScript.
2746 __ li(a0, Operand(1)); 2742 __ li(a0, Operand(1));
2747 __ sw(a0, MemOperand(sp, 4 * kPointerSize)); 2743 __ sw(a0, MemOperand(sp, 4 * kPointerSize));
2748 2744
2749 // Argument 7: Start (high end) of backtracking stack memory area. 2745 // Argument 7: Start (high end) of backtracking stack memory area.
2750 __ li(a0, Operand(address_of_regexp_stack_memory_address)); 2746 __ li(a0, Operand(address_of_regexp_stack_memory_address));
2751 __ lw(a0, MemOperand(a0, 0)); 2747 __ lw(a0, MemOperand(a0, 0));
2752 __ li(a2, Operand(address_of_regexp_stack_memory_size)); 2748 __ li(a2, Operand(address_of_regexp_stack_memory_size));
2753 __ lw(a2, MemOperand(a2, 0)); 2749 __ lw(a2, MemOperand(a2, 0));
2754 __ addu(a0, a0, a2); 2750 __ addu(a0, a0, a2);
2755 __ sw(a0, MemOperand(sp, 3 * kPointerSize)); 2751 __ sw(a0, MemOperand(sp, 3 * kPointerSize));
2756 2752
2757 // Argument 6: Set the number of capture registers to zero to force global 2753 // Argument 6: Set the number of capture registers to zero to force global
2758 // regexps to behave as non-global. This does not affect non-global regexps. 2754 // regexps to behave as non-global. This does not affect non-global regexps.
2759 __ mov(a0, zero_reg); 2755 __ mov(a0, zero_reg);
2760 __ sw(a0, MemOperand(sp, 2 * kPointerSize)); 2756 __ sw(a0, MemOperand(sp, 2 * kPointerSize));
2761 2757
2762 // Argument 5: static offsets vector buffer. 2758 // Argument 5: static offsets vector buffer.
2763 __ li(a0, Operand( 2759 __ li(a0, Operand(
2764 ExternalReference::address_of_static_offsets_vector(isolate))); 2760 ExternalReference::address_of_static_offsets_vector(isolate())));
2765 __ sw(a0, MemOperand(sp, 1 * kPointerSize)); 2761 __ sw(a0, MemOperand(sp, 1 * kPointerSize));
2766 2762
2767 // For arguments 4 and 3 get string length, calculate start of string data 2763 // For arguments 4 and 3 get string length, calculate start of string data
2768 // and calculate the shift of the index (0 for ASCII and 1 for two byte). 2764 // and calculate the shift of the index (0 for ASCII and 1 for two byte).
2769 __ Addu(t2, subject, Operand(SeqString::kHeaderSize - kHeapObjectTag)); 2765 __ Addu(t2, subject, Operand(SeqString::kHeaderSize - kHeapObjectTag));
2770 __ Xor(a3, a3, Operand(1)); // 1 for 2-byte str, 0 for 1-byte. 2766 __ Xor(a3, a3, Operand(1)); // 1 for 2-byte str, 0 for 1-byte.
2771 // Load the length from the original subject string from the previous stack 2767 // Load the length from the original subject string from the previous stack
2772 // frame. Therefore we have to use fp, which points exactly to two pointer 2768 // frame. Therefore we have to use fp, which points exactly to two pointer
2773 // sizes below the previous sp. (Because creating a new stack frame pushes 2769 // sizes below the previous sp. (Because creating a new stack frame pushes
2774 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.) 2770 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.)
(...skipping 12 matching lines...) Expand all
2787 __ sllv(t1, t2, a3); 2783 __ sllv(t1, t2, a3);
2788 __ addu(a3, t0, t1); 2784 __ addu(a3, t0, t1);
2789 // Argument 2 (a1): Previous index. 2785 // Argument 2 (a1): Previous index.
2790 // Already there 2786 // Already there
2791 2787
2792 // Argument 1 (a0): Subject string. 2788 // Argument 1 (a0): Subject string.
2793 __ mov(a0, subject); 2789 __ mov(a0, subject);
2794 2790
2795 // Locate the code entry and call it. 2791 // Locate the code entry and call it.
2796 __ Addu(t9, t9, Operand(Code::kHeaderSize - kHeapObjectTag)); 2792 __ Addu(t9, t9, Operand(Code::kHeaderSize - kHeapObjectTag));
2797 DirectCEntryStub stub; 2793 DirectCEntryStub stub(isolate());
2798 stub.GenerateCall(masm, t9); 2794 stub.GenerateCall(masm, t9);
2799 2795
2800 __ LeaveExitFrame(false, no_reg, true); 2796 __ LeaveExitFrame(false, no_reg, true);
2801 2797
2802 // v0: result 2798 // v0: result
2803 // subject: subject string (callee saved) 2799 // subject: subject string (callee saved)
2804 // regexp_data: RegExp data (callee saved) 2800 // regexp_data: RegExp data (callee saved)
2805 // last_match_info_elements: Last match info elements (callee saved) 2801 // last_match_info_elements: Last match info elements (callee saved)
2806 // Check the result. 2802 // Check the result.
2807 Label success; 2803 Label success;
2808 __ Branch(&success, eq, v0, Operand(1)); 2804 __ Branch(&success, eq, v0, Operand(1));
2809 // We expect exactly one result since we force the called regexp to behave 2805 // We expect exactly one result since we force the called regexp to behave
2810 // as non-global. 2806 // as non-global.
2811 Label failure; 2807 Label failure;
2812 __ Branch(&failure, eq, v0, Operand(NativeRegExpMacroAssembler::FAILURE)); 2808 __ Branch(&failure, eq, v0, Operand(NativeRegExpMacroAssembler::FAILURE));
2813 // If not exception it can only be retry. Handle that in the runtime system. 2809 // If not exception it can only be retry. Handle that in the runtime system.
2814 __ Branch(&runtime, ne, v0, Operand(NativeRegExpMacroAssembler::EXCEPTION)); 2810 __ Branch(&runtime, ne, v0, Operand(NativeRegExpMacroAssembler::EXCEPTION));
2815 // Result must now be exception. If there is no pending exception already a 2811 // Result must now be exception. If there is no pending exception already a
2816 // stack overflow (on the backtrack stack) was detected in RegExp code but 2812 // stack overflow (on the backtrack stack) was detected in RegExp code but
2817 // haven't created the exception yet. Handle that in the runtime system. 2813 // haven't created the exception yet. Handle that in the runtime system.
2818 // TODO(592): Rerunning the RegExp to get the stack overflow exception. 2814 // TODO(592): Rerunning the RegExp to get the stack overflow exception.
2819 __ li(a1, Operand(isolate->factory()->the_hole_value())); 2815 __ li(a1, Operand(isolate()->factory()->the_hole_value()));
2820 __ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, 2816 __ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
2821 isolate))); 2817 isolate())));
2822 __ lw(v0, MemOperand(a2, 0)); 2818 __ lw(v0, MemOperand(a2, 0));
2823 __ Branch(&runtime, eq, v0, Operand(a1)); 2819 __ Branch(&runtime, eq, v0, Operand(a1));
2824 2820
2825 __ sw(a1, MemOperand(a2, 0)); // Clear pending exception. 2821 __ sw(a1, MemOperand(a2, 0)); // Clear pending exception.
2826 2822
2827 // Check if the exception is a termination. If so, throw as uncatchable. 2823 // Check if the exception is a termination. If so, throw as uncatchable.
2828 __ LoadRoot(a0, Heap::kTerminationExceptionRootIndex); 2824 __ LoadRoot(a0, Heap::kTerminationExceptionRootIndex);
2829 Label termination_exception; 2825 Label termination_exception;
2830 __ Branch(&termination_exception, eq, v0, Operand(a0)); 2826 __ Branch(&termination_exception, eq, v0, Operand(a0));
2831 2827
2832 __ Throw(v0); 2828 __ Throw(v0);
2833 2829
2834 __ bind(&termination_exception); 2830 __ bind(&termination_exception);
2835 __ ThrowUncatchable(v0); 2831 __ ThrowUncatchable(v0);
2836 2832
2837 __ bind(&failure); 2833 __ bind(&failure);
2838 // For failure and exception return null. 2834 // For failure and exception return null.
2839 __ li(v0, Operand(isolate->factory()->null_value())); 2835 __ li(v0, Operand(isolate()->factory()->null_value()));
2840 __ DropAndRet(4); 2836 __ DropAndRet(4);
2841 2837
2842 // Process the result from the native regexp code. 2838 // Process the result from the native regexp code.
2843 __ bind(&success); 2839 __ bind(&success);
2844 __ lw(a1, 2840 __ lw(a1,
2845 FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset)); 2841 FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset));
2846 // Calculate number of capture registers (number_of_captures + 1) * 2. 2842 // Calculate number of capture registers (number_of_captures + 1) * 2.
2847 // Multiplying by 2 comes for free since r1 is smi-tagged. 2843 // Multiplying by 2 comes for free since r1 is smi-tagged.
2848 STATIC_ASSERT(kSmiTag == 0); 2844 STATIC_ASSERT(kSmiTag == 0);
2849 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); 2845 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2890 RegExpImpl::kLastInputOffset)); 2886 RegExpImpl::kLastInputOffset));
2891 __ RecordWriteField(last_match_info_elements, 2887 __ RecordWriteField(last_match_info_elements,
2892 RegExpImpl::kLastInputOffset, 2888 RegExpImpl::kLastInputOffset,
2893 subject, 2889 subject,
2894 t3, 2890 t3,
2895 kRAHasNotBeenSaved, 2891 kRAHasNotBeenSaved,
2896 kDontSaveFPRegs); 2892 kDontSaveFPRegs);
2897 2893
2898 // Get the static offsets vector filled by the native regexp code. 2894 // Get the static offsets vector filled by the native regexp code.
2899 ExternalReference address_of_static_offsets_vector = 2895 ExternalReference address_of_static_offsets_vector =
2900 ExternalReference::address_of_static_offsets_vector(isolate); 2896 ExternalReference::address_of_static_offsets_vector(isolate());
2901 __ li(a2, Operand(address_of_static_offsets_vector)); 2897 __ li(a2, Operand(address_of_static_offsets_vector));
2902 2898
2903 // a1: number of capture registers 2899 // a1: number of capture registers
2904 // a2: offsets vector 2900 // a2: offsets vector
2905 Label next_capture, done; 2901 Label next_capture, done;
2906 // Capture register counter starts from number of capture registers and 2902 // Capture register counter starts from number of capture registers and
2907 // counts down until wrapping after zero. 2903 // counts down until wrapping after zero.
2908 __ Addu(a0, 2904 __ Addu(a0,
2909 last_match_info_elements, 2905 last_match_info_elements,
2910 Operand(RegExpImpl::kFirstCaptureOffset - kHeapObjectTag)); 2906 Operand(RegExpImpl::kFirstCaptureOffset - kHeapObjectTag));
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
3043 const RegList kSavedRegs = 3039 const RegList kSavedRegs =
3044 1 << 4 | // a0 3040 1 << 4 | // a0
3045 1 << 5 | // a1 3041 1 << 5 | // a1
3046 1 << 6 | // a2 3042 1 << 6 | // a2
3047 1 << 7; // a3 3043 1 << 7; // a3
3048 3044
3049 // Arguments register must be smi-tagged to call out. 3045 // Arguments register must be smi-tagged to call out.
3050 __ SmiTag(a0); 3046 __ SmiTag(a0);
3051 __ MultiPush(kSavedRegs); 3047 __ MultiPush(kSavedRegs);
3052 3048
3053 CreateAllocationSiteStub create_stub; 3049 CreateAllocationSiteStub create_stub(masm->isolate());
3054 __ CallStub(&create_stub); 3050 __ CallStub(&create_stub);
3055 3051
3056 __ MultiPop(kSavedRegs); 3052 __ MultiPop(kSavedRegs);
3057 __ SmiUntag(a0); 3053 __ SmiUntag(a0);
3058 } 3054 }
3059 __ Branch(&done); 3055 __ Branch(&done);
3060 3056
3061 __ bind(&not_array_function); 3057 __ bind(&not_array_function);
3062 } 3058 }
3063 3059
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3131 } 3127 }
3132 __ InvokeFunction(a1, actual, JUMP_FUNCTION, NullCallWrapper()); 3128 __ InvokeFunction(a1, actual, JUMP_FUNCTION, NullCallWrapper());
3133 3129
3134 if (NeedsChecks()) { 3130 if (NeedsChecks()) {
3135 // Slow-case: Non-function called. 3131 // Slow-case: Non-function called.
3136 __ bind(&slow); 3132 __ bind(&slow);
3137 if (RecordCallTarget()) { 3133 if (RecordCallTarget()) {
3138 // If there is a call target cache, mark it megamorphic in the 3134 // If there is a call target cache, mark it megamorphic in the
3139 // non-function case. MegamorphicSentinel is an immortal immovable 3135 // non-function case. MegamorphicSentinel is an immortal immovable
3140 // object (megamorphic symbol) so no write barrier is needed. 3136 // object (megamorphic symbol) so no write barrier is needed.
3141 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()), 3137 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(isolate()),
3142 masm->isolate()->heap()->megamorphic_symbol()); 3138 isolate()->heap()->megamorphic_symbol());
3143 __ sll(t1, a3, kPointerSizeLog2 - kSmiTagSize); 3139 __ sll(t1, a3, kPointerSizeLog2 - kSmiTagSize);
3144 __ Addu(t1, a2, Operand(t1)); 3140 __ Addu(t1, a2, Operand(t1));
3145 __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex); 3141 __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex);
3146 __ sw(at, FieldMemOperand(t1, FixedArray::kHeaderSize)); 3142 __ sw(at, FieldMemOperand(t1, FixedArray::kHeaderSize));
3147 } 3143 }
3148 // Check for function proxy. 3144 // Check for function proxy.
3149 __ Branch(&non_function, ne, t0, Operand(JS_FUNCTION_PROXY_TYPE)); 3145 __ Branch(&non_function, ne, t0, Operand(JS_FUNCTION_PROXY_TYPE));
3150 __ push(a1); // Put proxy as additional argument. 3146 __ push(a1); // Put proxy as additional argument.
3151 __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32)); 3147 __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32));
3152 __ li(a2, Operand(0, RelocInfo::NONE32)); 3148 __ li(a2, Operand(0, RelocInfo::NONE32));
3153 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY); 3149 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY);
3154 { 3150 {
3155 Handle<Code> adaptor = 3151 Handle<Code> adaptor =
3156 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); 3152 isolate()->builtins()->ArgumentsAdaptorTrampoline();
3157 __ Jump(adaptor, RelocInfo::CODE_TARGET); 3153 __ Jump(adaptor, RelocInfo::CODE_TARGET);
3158 } 3154 }
3159 3155
3160 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead 3156 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
3161 // of the original receiver from the call site). 3157 // of the original receiver from the call site).
3162 __ bind(&non_function); 3158 __ bind(&non_function);
3163 __ sw(a1, MemOperand(sp, argc_ * kPointerSize)); 3159 __ sw(a1, MemOperand(sp, argc_ * kPointerSize));
3164 __ li(a0, Operand(argc_)); // Set up the number of arguments. 3160 __ li(a0, Operand(argc_)); // Set up the number of arguments.
3165 __ li(a2, Operand(0, RelocInfo::NONE32)); 3161 __ li(a2, Operand(0, RelocInfo::NONE32));
3166 __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION); 3162 __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION);
3167 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 3163 __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(),
3168 RelocInfo::CODE_TARGET); 3164 RelocInfo::CODE_TARGET);
3169 } 3165 }
3170 3166
3171 if (CallAsMethod()) { 3167 if (CallAsMethod()) {
3172 __ bind(&wrap); 3168 __ bind(&wrap);
3173 // Wrap the receiver and patch it back onto the stack. 3169 // Wrap the receiver and patch it back onto the stack.
3174 { FrameScope frame_scope(masm, StackFrame::INTERNAL); 3170 { FrameScope frame_scope(masm, StackFrame::INTERNAL);
3175 __ Push(a1, a3); 3171 __ Push(a1, a3);
3176 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 3172 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
3177 __ pop(a1); 3173 __ pop(a1);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3235 __ bind(&slow); 3231 __ bind(&slow);
3236 __ Branch(&non_function_call, ne, t0, Operand(JS_FUNCTION_PROXY_TYPE)); 3232 __ Branch(&non_function_call, ne, t0, Operand(JS_FUNCTION_PROXY_TYPE));
3237 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); 3233 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
3238 __ jmp(&do_call); 3234 __ jmp(&do_call);
3239 3235
3240 __ bind(&non_function_call); 3236 __ bind(&non_function_call);
3241 __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); 3237 __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
3242 __ bind(&do_call); 3238 __ bind(&do_call);
3243 // Set expected number of arguments to zero (not changing r0). 3239 // Set expected number of arguments to zero (not changing r0).
3244 __ li(a2, Operand(0, RelocInfo::NONE32)); 3240 __ li(a2, Operand(0, RelocInfo::NONE32));
3245 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 3241 __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(),
3246 RelocInfo::CODE_TARGET); 3242 RelocInfo::CODE_TARGET);
3247 } 3243 }
3248 3244
3249 3245
3250 // StringCharCodeAtGenerator. 3246 // StringCharCodeAtGenerator.
3251 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 3247 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
3252 Label flat_string; 3248 Label flat_string;
3253 Label ascii_string; 3249 Label ascii_string;
3254 Label got_char_code; 3250 Label got_char_code;
3255 Label sliced_string; 3251 Label sliced_string;
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
3763 3759
3764 // v0: result string. 3760 // v0: result string.
3765 // a1: first character of result. 3761 // a1: first character of result.
3766 // a2: result length. 3762 // a2: result length.
3767 // t1: first character of substring to copy. 3763 // t1: first character of substring to copy.
3768 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); 3764 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
3769 StringHelper::GenerateCopyCharactersLong( 3765 StringHelper::GenerateCopyCharactersLong(
3770 masm, a1, t1, a2, a3, t0, t2, t3, t4, DEST_ALWAYS_ALIGNED); 3766 masm, a1, t1, a2, a3, t0, t2, t3, t4, DEST_ALWAYS_ALIGNED);
3771 3767
3772 __ bind(&return_v0); 3768 __ bind(&return_v0);
3773 Counters* counters = masm->isolate()->counters(); 3769 Counters* counters = isolate()->counters();
3774 __ IncrementCounter(counters->sub_string_native(), 1, a3, t0); 3770 __ IncrementCounter(counters->sub_string_native(), 1, a3, t0);
3775 __ DropAndRet(3); 3771 __ DropAndRet(3);
3776 3772
3777 // Just jump to runtime to create the sub string. 3773 // Just jump to runtime to create the sub string.
3778 __ bind(&runtime); 3774 __ bind(&runtime);
3779 __ TailCallRuntime(Runtime::kHiddenSubString, 3, 1); 3775 __ TailCallRuntime(Runtime::kHiddenSubString, 3, 1);
3780 3776
3781 __ bind(&single_char); 3777 __ bind(&single_char);
3782 // v0: original string 3778 // v0: original string
3783 // a1: instance type 3779 // a1: instance type
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
3907 __ lbu(scratch2, MemOperand(scratch3)); 3903 __ lbu(scratch2, MemOperand(scratch3));
3908 __ Branch(chars_not_equal, ne, scratch1, Operand(scratch2)); 3904 __ Branch(chars_not_equal, ne, scratch1, Operand(scratch2));
3909 __ Addu(index, index, 1); 3905 __ Addu(index, index, 1);
3910 __ Branch(&loop, ne, index, Operand(zero_reg)); 3906 __ Branch(&loop, ne, index, Operand(zero_reg));
3911 } 3907 }
3912 3908
3913 3909
3914 void StringCompareStub::Generate(MacroAssembler* masm) { 3910 void StringCompareStub::Generate(MacroAssembler* masm) {
3915 Label runtime; 3911 Label runtime;
3916 3912
3917 Counters* counters = masm->isolate()->counters(); 3913 Counters* counters = isolate()->counters();
3918 3914
3919 // Stack frame on entry. 3915 // Stack frame on entry.
3920 // sp[0]: right string 3916 // sp[0]: right string
3921 // sp[4]: left string 3917 // sp[4]: left string
3922 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); // Left. 3918 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); // Left.
3923 __ lw(a0, MemOperand(sp, 0 * kPointerSize)); // Right. 3919 __ lw(a0, MemOperand(sp, 0 * kPointerSize)); // Right.
3924 3920
3925 Label not_same; 3921 Label not_same;
3926 __ Branch(&not_same, ne, a0, Operand(a1)); 3922 __ Branch(&not_same, ne, a0, Operand(a1));
3927 STATIC_ASSERT(EQUAL == 0); 3923 STATIC_ASSERT(EQUAL == 0);
(...skipping 16 matching lines...) Expand all
3944 __ TailCallRuntime(Runtime::kHiddenStringCompare, 2, 1); 3940 __ TailCallRuntime(Runtime::kHiddenStringCompare, 2, 1);
3945 } 3941 }
3946 3942
3947 3943
3948 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { 3944 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
3949 // ----------- S t a t e ------------- 3945 // ----------- S t a t e -------------
3950 // -- a1 : left 3946 // -- a1 : left
3951 // -- a0 : right 3947 // -- a0 : right
3952 // -- ra : return address 3948 // -- ra : return address
3953 // ----------------------------------- 3949 // -----------------------------------
3954 Isolate* isolate = masm->isolate();
3955 3950
3956 // Load a2 with the allocation site. We stick an undefined dummy value here 3951 // Load a2 with the allocation site. We stick an undefined dummy value here
3957 // and replace it with the real allocation site later when we instantiate this 3952 // and replace it with the real allocation site later when we instantiate this
3958 // stub in BinaryOpICWithAllocationSiteStub::GetCodeCopyFromTemplate(). 3953 // stub in BinaryOpICWithAllocationSiteStub::GetCodeCopyFromTemplate().
3959 __ li(a2, handle(isolate->heap()->undefined_value())); 3954 __ li(a2, handle(isolate()->heap()->undefined_value()));
3960 3955
3961 // Make sure that we actually patched the allocation site. 3956 // Make sure that we actually patched the allocation site.
3962 if (FLAG_debug_code) { 3957 if (FLAG_debug_code) {
3963 __ And(at, a2, Operand(kSmiTagMask)); 3958 __ And(at, a2, Operand(kSmiTagMask));
3964 __ Assert(ne, kExpectedAllocationSite, at, Operand(zero_reg)); 3959 __ Assert(ne, kExpectedAllocationSite, at, Operand(zero_reg));
3965 __ lw(t0, FieldMemOperand(a2, HeapObject::kMapOffset)); 3960 __ lw(t0, FieldMemOperand(a2, HeapObject::kMapOffset));
3966 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); 3961 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex);
3967 __ Assert(eq, kExpectedAllocationSite, t0, Operand(at)); 3962 __ Assert(eq, kExpectedAllocationSite, t0, Operand(at));
3968 } 3963 }
3969 3964
3970 // Tail call into the stub that handles binary operations with allocation 3965 // Tail call into the stub that handles binary operations with allocation
3971 // sites. 3966 // sites.
3972 BinaryOpWithAllocationSiteStub stub(state_); 3967 BinaryOpWithAllocationSiteStub stub(isolate(), state_);
3973 __ TailCallStub(&stub); 3968 __ TailCallStub(&stub);
3974 } 3969 }
3975 3970
3976 3971
3977 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { 3972 void ICCompareStub::GenerateSmis(MacroAssembler* masm) {
3978 ASSERT(state_ == CompareIC::SMI); 3973 ASSERT(state_ == CompareIC::SMI);
3979 Label miss; 3974 Label miss;
3980 __ Or(a2, a1, a0); 3975 __ Or(a2, a1, a0);
3981 __ JumpIfNotSmi(a2, &miss); 3976 __ JumpIfNotSmi(a2, &miss);
3982 3977
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
4058 __ bind(&fpu_eq); 4053 __ bind(&fpu_eq);
4059 __ Ret(USE_DELAY_SLOT); 4054 __ Ret(USE_DELAY_SLOT);
4060 __ li(v0, Operand(EQUAL)); 4055 __ li(v0, Operand(EQUAL));
4061 4056
4062 __ bind(&fpu_lt); 4057 __ bind(&fpu_lt);
4063 __ Ret(USE_DELAY_SLOT); 4058 __ Ret(USE_DELAY_SLOT);
4064 __ li(v0, Operand(LESS)); 4059 __ li(v0, Operand(LESS));
4065 4060
4066 __ bind(&unordered); 4061 __ bind(&unordered);
4067 __ bind(&generic_stub); 4062 __ bind(&generic_stub);
4068 ICCompareStub stub(op_, CompareIC::GENERIC, CompareIC::GENERIC, 4063 ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC,
4069 CompareIC::GENERIC); 4064 CompareIC::GENERIC);
4070 __ Jump(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET); 4065 __ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
4071 4066
4072 __ bind(&maybe_undefined1); 4067 __ bind(&maybe_undefined1);
4073 if (Token::IsOrderedRelationalCompareOp(op_)) { 4068 if (Token::IsOrderedRelationalCompareOp(op_)) {
4074 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 4069 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
4075 __ Branch(&miss, ne, a0, Operand(at)); 4070 __ Branch(&miss, ne, a0, Operand(at));
4076 __ JumpIfSmi(a1, &unordered); 4071 __ JumpIfSmi(a1, &unordered);
4077 __ GetObjectType(a1, a2, a2); 4072 __ GetObjectType(a1, a2, a2);
4078 __ Branch(&maybe_undefined2, ne, a2, Operand(HEAP_NUMBER_TYPE)); 4073 __ Branch(&maybe_undefined2, ne, a2, Operand(HEAP_NUMBER_TYPE));
4079 __ jmp(&unordered); 4074 __ jmp(&unordered);
4080 } 4075 }
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
4294 4289
4295 __ bind(&miss); 4290 __ bind(&miss);
4296 GenerateMiss(masm); 4291 GenerateMiss(masm);
4297 } 4292 }
4298 4293
4299 4294
4300 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { 4295 void ICCompareStub::GenerateMiss(MacroAssembler* masm) {
4301 { 4296 {
4302 // Call the runtime system in a fresh internal frame. 4297 // Call the runtime system in a fresh internal frame.
4303 ExternalReference miss = 4298 ExternalReference miss =
4304 ExternalReference(IC_Utility(IC::kCompareIC_Miss), masm->isolate()); 4299 ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate());
4305 FrameScope scope(masm, StackFrame::INTERNAL); 4300 FrameScope scope(masm, StackFrame::INTERNAL);
4306 __ Push(a1, a0); 4301 __ Push(a1, a0);
4307 __ Push(ra, a1, a0); 4302 __ Push(ra, a1, a0);
4308 __ li(t0, Operand(Smi::FromInt(op_))); 4303 __ li(t0, Operand(Smi::FromInt(op_)));
4309 __ addiu(sp, sp, -kPointerSize); 4304 __ addiu(sp, sp, -kPointerSize);
4310 __ CallExternalReference(miss, 3, USE_DELAY_SLOT); 4305 __ CallExternalReference(miss, 3, USE_DELAY_SLOT);
4311 __ sw(t0, MemOperand(sp)); // In the delay slot. 4306 __ sw(t0, MemOperand(sp)); // In the delay slot.
4312 // Compute the entry point of the rewritten stub. 4307 // Compute the entry point of the rewritten stub.
4313 __ Addu(a2, v0, Operand(Code::kHeaderSize - kHeapObjectTag)); 4308 __ Addu(a2, v0, Operand(Code::kHeaderSize - kHeapObjectTag));
4314 // Restore registers. 4309 // Restore registers.
(...skipping 24 matching lines...) Expand all
4339 __ Assert(ne, kReceivedInvalidReturnAddress, t0, 4334 __ Assert(ne, kReceivedInvalidReturnAddress, t0,
4340 Operand(reinterpret_cast<uint32_t>(kZapValue))); 4335 Operand(reinterpret_cast<uint32_t>(kZapValue)));
4341 } 4336 }
4342 __ Jump(t9); 4337 __ Jump(t9);
4343 } 4338 }
4344 4339
4345 4340
4346 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, 4341 void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
4347 Register target) { 4342 Register target) {
4348 intptr_t loc = 4343 intptr_t loc =
4349 reinterpret_cast<intptr_t>(GetCode(masm->isolate()).location()); 4344 reinterpret_cast<intptr_t>(GetCode(isolate()).location());
4350 __ Move(t9, target); 4345 __ Move(t9, target);
4351 __ li(ra, Operand(loc, RelocInfo::CODE_TARGET), CONSTANT_SIZE); 4346 __ li(ra, Operand(loc, RelocInfo::CODE_TARGET), CONSTANT_SIZE);
4352 __ Call(ra); 4347 __ Call(ra);
4353 } 4348 }
4354 4349
4355 4350
4356 void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, 4351 void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
4357 Label* miss, 4352 Label* miss,
4358 Label* done, 4353 Label* done,
4359 Register receiver, 4354 Register receiver,
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
4414 FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 4409 FieldMemOperand(receiver, JSObject::kPropertiesOffset));
4415 } 4410 }
4416 4411
4417 const int spill_mask = 4412 const int spill_mask =
4418 (ra.bit() | t2.bit() | t1.bit() | t0.bit() | a3.bit() | 4413 (ra.bit() | t2.bit() | t1.bit() | t0.bit() | a3.bit() |
4419 a2.bit() | a1.bit() | a0.bit() | v0.bit()); 4414 a2.bit() | a1.bit() | a0.bit() | v0.bit());
4420 4415
4421 __ MultiPush(spill_mask); 4416 __ MultiPush(spill_mask);
4422 __ lw(a0, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 4417 __ lw(a0, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
4423 __ li(a1, Operand(Handle<Name>(name))); 4418 __ li(a1, Operand(Handle<Name>(name)));
4424 NameDictionaryLookupStub stub(NEGATIVE_LOOKUP); 4419 NameDictionaryLookupStub stub(masm->isolate(), NEGATIVE_LOOKUP);
4425 __ CallStub(&stub); 4420 __ CallStub(&stub);
4426 __ mov(at, v0); 4421 __ mov(at, v0);
4427 __ MultiPop(spill_mask); 4422 __ MultiPop(spill_mask);
4428 4423
4429 __ Branch(done, eq, at, Operand(zero_reg)); 4424 __ Branch(done, eq, at, Operand(zero_reg));
4430 __ Branch(miss, ne, at, Operand(zero_reg)); 4425 __ Branch(miss, ne, at, Operand(zero_reg));
4431 } 4426 }
4432 4427
4433 4428
4434 // Probe the name dictionary in the |elements| register. Jump to the 4429 // Probe the name dictionary in the |elements| register. Jump to the
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
4493 4488
4494 __ MultiPush(spill_mask); 4489 __ MultiPush(spill_mask);
4495 if (name.is(a0)) { 4490 if (name.is(a0)) {
4496 ASSERT(!elements.is(a1)); 4491 ASSERT(!elements.is(a1));
4497 __ Move(a1, name); 4492 __ Move(a1, name);
4498 __ Move(a0, elements); 4493 __ Move(a0, elements);
4499 } else { 4494 } else {
4500 __ Move(a0, elements); 4495 __ Move(a0, elements);
4501 __ Move(a1, name); 4496 __ Move(a1, name);
4502 } 4497 }
4503 NameDictionaryLookupStub stub(POSITIVE_LOOKUP); 4498 NameDictionaryLookupStub stub(masm->isolate(), POSITIVE_LOOKUP);
4504 __ CallStub(&stub); 4499 __ CallStub(&stub);
4505 __ mov(scratch2, a2); 4500 __ mov(scratch2, a2);
4506 __ mov(at, v0); 4501 __ mov(at, v0);
4507 __ MultiPop(spill_mask); 4502 __ MultiPop(spill_mask);
4508 4503
4509 __ Branch(done, ne, at, Operand(zero_reg)); 4504 __ Branch(done, ne, at, Operand(zero_reg));
4510 __ Branch(miss, eq, at, Operand(zero_reg)); 4505 __ Branch(miss, eq, at, Operand(zero_reg));
4511 } 4506 }
4512 4507
4513 4508
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
4601 __ li(result, 1); 4596 __ li(result, 1);
4602 4597
4603 __ bind(&not_in_dictionary); 4598 __ bind(&not_in_dictionary);
4604 __ Ret(USE_DELAY_SLOT); 4599 __ Ret(USE_DELAY_SLOT);
4605 __ mov(result, zero_reg); 4600 __ mov(result, zero_reg);
4606 } 4601 }
4607 4602
4608 4603
4609 void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime( 4604 void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
4610 Isolate* isolate) { 4605 Isolate* isolate) {
4611 StoreBufferOverflowStub stub1(kDontSaveFPRegs); 4606 StoreBufferOverflowStub stub1(isolate, kDontSaveFPRegs);
4612 stub1.GetCode(isolate); 4607 stub1.GetCode(isolate);
4613 // Hydrogen code stubs need stub2 at snapshot time. 4608 // Hydrogen code stubs need stub2 at snapshot time.
4614 StoreBufferOverflowStub stub2(kSaveFPRegs); 4609 StoreBufferOverflowStub stub2(isolate, kSaveFPRegs);
4615 stub2.GetCode(isolate); 4610 stub2.GetCode(isolate);
4616 } 4611 }
4617 4612
4618 4613
4619 bool CodeStub::CanUseFPRegisters() { 4614 bool CodeStub::CanUseFPRegisters() {
4620 return true; // FPU is a base requirement for V8. 4615 return true; // FPU is a base requirement for V8.
4621 } 4616 }
4622 4617
4623 4618
4624 // Takes the input in 3 registers: address_ value_ and object_. A pointer to 4619 // Takes the input in 3 registers: address_ value_ and object_. A pointer to
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
4707 regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_); 4702 regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_);
4708 int argument_count = 3; 4703 int argument_count = 3;
4709 __ PrepareCallCFunction(argument_count, regs_.scratch0()); 4704 __ PrepareCallCFunction(argument_count, regs_.scratch0());
4710 Register address = 4705 Register address =
4711 a0.is(regs_.address()) ? regs_.scratch0() : regs_.address(); 4706 a0.is(regs_.address()) ? regs_.scratch0() : regs_.address();
4712 ASSERT(!address.is(regs_.object())); 4707 ASSERT(!address.is(regs_.object()));
4713 ASSERT(!address.is(a0)); 4708 ASSERT(!address.is(a0));
4714 __ Move(address, regs_.address()); 4709 __ Move(address, regs_.address());
4715 __ Move(a0, regs_.object()); 4710 __ Move(a0, regs_.object());
4716 __ Move(a1, address); 4711 __ Move(a1, address);
4717 __ li(a2, Operand(ExternalReference::isolate_address(masm->isolate()))); 4712 __ li(a2, Operand(ExternalReference::isolate_address(isolate())));
4718 4713
4719 AllowExternalCallThatCantCauseGC scope(masm); 4714 AllowExternalCallThatCantCauseGC scope(masm);
4720 __ CallCFunction( 4715 __ CallCFunction(
4721 ExternalReference::incremental_marking_record_write_function( 4716 ExternalReference::incremental_marking_record_write_function(isolate()),
4722 masm->isolate()),
4723 argument_count); 4717 argument_count);
4724 regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_); 4718 regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_);
4725 } 4719 }
4726 4720
4727 4721
4728 void RecordWriteStub::CheckNeedsToInformIncrementalMarker( 4722 void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
4729 MacroAssembler* masm, 4723 MacroAssembler* masm,
4730 OnNoNeedToInformIncrementalMarker on_no_need, 4724 OnNoNeedToInformIncrementalMarker on_no_need,
4731 Mode mode) { 4725 Mode mode) {
4732 Label on_black; 4726 Label on_black;
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
4872 // Array literal has ElementsKind of FAST_*_DOUBLE_ELEMENTS. 4866 // Array literal has ElementsKind of FAST_*_DOUBLE_ELEMENTS.
4873 __ bind(&double_elements); 4867 __ bind(&double_elements);
4874 __ lw(t1, FieldMemOperand(a1, JSObject::kElementsOffset)); 4868 __ lw(t1, FieldMemOperand(a1, JSObject::kElementsOffset));
4875 __ StoreNumberToDoubleElements(a0, a3, t1, t3, t5, a2, &slow_elements); 4869 __ StoreNumberToDoubleElements(a0, a3, t1, t3, t5, a2, &slow_elements);
4876 __ Ret(USE_DELAY_SLOT); 4870 __ Ret(USE_DELAY_SLOT);
4877 __ mov(v0, a0); 4871 __ mov(v0, a0);
4878 } 4872 }
4879 4873
4880 4874
4881 void StubFailureTrampolineStub::Generate(MacroAssembler* masm) { 4875 void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
4882 CEntryStub ces(1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs); 4876 CEntryStub ces(isolate(), 1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
4883 __ Call(ces.GetCode(masm->isolate()), RelocInfo::CODE_TARGET); 4877 __ Call(ces.GetCode(isolate()), RelocInfo::CODE_TARGET);
4884 int parameter_count_offset = 4878 int parameter_count_offset =
4885 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; 4879 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
4886 __ lw(a1, MemOperand(fp, parameter_count_offset)); 4880 __ lw(a1, MemOperand(fp, parameter_count_offset));
4887 if (function_mode_ == JS_FUNCTION_STUB_MODE) { 4881 if (function_mode_ == JS_FUNCTION_STUB_MODE) {
4888 __ Addu(a1, a1, Operand(1)); 4882 __ Addu(a1, a1, Operand(1));
4889 } 4883 }
4890 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); 4884 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
4891 __ sll(a1, a1, kPointerSizeLog2); 4885 __ sll(a1, a1, kPointerSizeLog2);
4892 __ Ret(USE_DELAY_SLOT); 4886 __ Ret(USE_DELAY_SLOT);
4893 __ Addu(sp, sp, a1); 4887 __ Addu(sp, sp, a1);
4894 } 4888 }
4895 4889
4896 4890
4897 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { 4891 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
4898 if (masm->isolate()->function_entry_hook() != NULL) { 4892 if (masm->isolate()->function_entry_hook() != NULL) {
4899 ProfileEntryHookStub stub; 4893 ProfileEntryHookStub stub(masm->isolate());
4900 __ push(ra); 4894 __ push(ra);
4901 __ CallStub(&stub); 4895 __ CallStub(&stub);
4902 __ pop(ra); 4896 __ pop(ra);
4903 } 4897 }
4904 } 4898 }
4905 4899
4906 4900
4907 void ProfileEntryHookStub::Generate(MacroAssembler* masm) { 4901 void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
4908 // The entry hook is a "push ra" instruction, followed by a call. 4902 // The entry hook is a "push ra" instruction, followed by a call.
4909 // Note: on MIPS "push" is 2 instruction 4903 // Note: on MIPS "push" is 2 instruction
(...skipping 21 matching lines...) Expand all
4931 // Align the stack if necessary. 4925 // Align the stack if necessary.
4932 int frame_alignment = masm->ActivationFrameAlignment(); 4926 int frame_alignment = masm->ActivationFrameAlignment();
4933 if (frame_alignment > kPointerSize) { 4927 if (frame_alignment > kPointerSize) {
4934 __ mov(s5, sp); 4928 __ mov(s5, sp);
4935 ASSERT(IsPowerOf2(frame_alignment)); 4929 ASSERT(IsPowerOf2(frame_alignment));
4936 __ And(sp, sp, Operand(-frame_alignment)); 4930 __ And(sp, sp, Operand(-frame_alignment));
4937 } 4931 }
4938 __ Subu(sp, sp, kCArgsSlotsSize); 4932 __ Subu(sp, sp, kCArgsSlotsSize);
4939 #if defined(V8_HOST_ARCH_MIPS) 4933 #if defined(V8_HOST_ARCH_MIPS)
4940 int32_t entry_hook = 4934 int32_t entry_hook =
4941 reinterpret_cast<int32_t>(masm->isolate()->function_entry_hook()); 4935 reinterpret_cast<int32_t>(isolate()->function_entry_hook());
4942 __ li(t9, Operand(entry_hook)); 4936 __ li(t9, Operand(entry_hook));
4943 #else 4937 #else
4944 // Under the simulator we need to indirect the entry hook through a 4938 // Under the simulator we need to indirect the entry hook through a
4945 // trampoline function at a known address. 4939 // trampoline function at a known address.
4946 // It additionally takes an isolate as a third parameter. 4940 // It additionally takes an isolate as a third parameter.
4947 __ li(a2, Operand(ExternalReference::isolate_address(masm->isolate()))); 4941 __ li(a2, Operand(ExternalReference::isolate_address(isolate())));
4948 4942
4949 ApiFunction dispatcher(FUNCTION_ADDR(EntryHookTrampoline)); 4943 ApiFunction dispatcher(FUNCTION_ADDR(EntryHookTrampoline));
4950 __ li(t9, Operand(ExternalReference(&dispatcher, 4944 __ li(t9, Operand(ExternalReference(&dispatcher,
4951 ExternalReference::BUILTIN_CALL, 4945 ExternalReference::BUILTIN_CALL,
4952 masm->isolate()))); 4946 isolate())));
4953 #endif 4947 #endif
4954 // Call C function through t9 to conform ABI for PIC. 4948 // Call C function through t9 to conform ABI for PIC.
4955 __ Call(t9); 4949 __ Call(t9);
4956 4950
4957 // Restore the stack pointer if needed. 4951 // Restore the stack pointer if needed.
4958 if (frame_alignment > kPointerSize) { 4952 if (frame_alignment > kPointerSize) {
4959 __ mov(sp, s5); 4953 __ mov(sp, s5);
4960 } else { 4954 } else {
4961 __ Addu(sp, sp, kCArgsSlotsSize); 4955 __ Addu(sp, sp, kCArgsSlotsSize);
4962 } 4956 }
4963 4957
4964 // Also pop ra to get Ret(0). 4958 // Also pop ra to get Ret(0).
4965 __ MultiPop(kSavedRegs | ra.bit()); 4959 __ MultiPop(kSavedRegs | ra.bit());
4966 __ Ret(); 4960 __ Ret();
4967 } 4961 }
4968 4962
4969 4963
4970 template<class T> 4964 template<class T>
4971 static void CreateArrayDispatch(MacroAssembler* masm, 4965 static void CreateArrayDispatch(MacroAssembler* masm,
4972 AllocationSiteOverrideMode mode) { 4966 AllocationSiteOverrideMode mode) {
4973 if (mode == DISABLE_ALLOCATION_SITES) { 4967 if (mode == DISABLE_ALLOCATION_SITES) {
4974 T stub(GetInitialFastElementsKind(), mode); 4968 T stub(masm->isolate(), GetInitialFastElementsKind(), mode);
4975 __ TailCallStub(&stub); 4969 __ TailCallStub(&stub);
4976 } else if (mode == DONT_OVERRIDE) { 4970 } else if (mode == DONT_OVERRIDE) {
4977 int last_index = GetSequenceIndexFromFastElementsKind( 4971 int last_index = GetSequenceIndexFromFastElementsKind(
4978 TERMINAL_FAST_ELEMENTS_KIND); 4972 TERMINAL_FAST_ELEMENTS_KIND);
4979 for (int i = 0; i <= last_index; ++i) { 4973 for (int i = 0; i <= last_index; ++i) {
4980 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 4974 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
4981 T stub(kind); 4975 T stub(masm->isolate(), kind);
4982 __ TailCallStub(&stub, eq, a3, Operand(kind)); 4976 __ TailCallStub(&stub, eq, a3, Operand(kind));
4983 } 4977 }
4984 4978
4985 // If we reached this point there is a problem. 4979 // If we reached this point there is a problem.
4986 __ Abort(kUnexpectedElementsKindInArrayConstructor); 4980 __ Abort(kUnexpectedElementsKindInArrayConstructor);
4987 } else { 4981 } else {
4988 UNREACHABLE(); 4982 UNREACHABLE();
4989 } 4983 }
4990 } 4984 }
4991 4985
(...skipping 20 matching lines...) Expand all
5012 } 5006 }
5013 5007
5014 // look at the first argument 5008 // look at the first argument
5015 __ lw(t1, MemOperand(sp, 0)); 5009 __ lw(t1, MemOperand(sp, 0));
5016 __ Branch(&normal_sequence, eq, t1, Operand(zero_reg)); 5010 __ Branch(&normal_sequence, eq, t1, Operand(zero_reg));
5017 5011
5018 if (mode == DISABLE_ALLOCATION_SITES) { 5012 if (mode == DISABLE_ALLOCATION_SITES) {
5019 ElementsKind initial = GetInitialFastElementsKind(); 5013 ElementsKind initial = GetInitialFastElementsKind();
5020 ElementsKind holey_initial = GetHoleyElementsKind(initial); 5014 ElementsKind holey_initial = GetHoleyElementsKind(initial);
5021 5015
5022 ArraySingleArgumentConstructorStub stub_holey(holey_initial, 5016 ArraySingleArgumentConstructorStub stub_holey(masm->isolate(),
5017 holey_initial,
5023 DISABLE_ALLOCATION_SITES); 5018 DISABLE_ALLOCATION_SITES);
5024 __ TailCallStub(&stub_holey); 5019 __ TailCallStub(&stub_holey);
5025 5020
5026 __ bind(&normal_sequence); 5021 __ bind(&normal_sequence);
5027 ArraySingleArgumentConstructorStub stub(initial, 5022 ArraySingleArgumentConstructorStub stub(masm->isolate(),
5023 initial,
5028 DISABLE_ALLOCATION_SITES); 5024 DISABLE_ALLOCATION_SITES);
5029 __ TailCallStub(&stub); 5025 __ TailCallStub(&stub);
5030 } else if (mode == DONT_OVERRIDE) { 5026 } else if (mode == DONT_OVERRIDE) {
5031 // We are going to create a holey array, but our kind is non-holey. 5027 // We are going to create a holey array, but our kind is non-holey.
5032 // Fix kind and retry (only if we have an allocation site in the slot). 5028 // Fix kind and retry (only if we have an allocation site in the slot).
5033 __ Addu(a3, a3, Operand(1)); 5029 __ Addu(a3, a3, Operand(1));
5034 5030
5035 if (FLAG_debug_code) { 5031 if (FLAG_debug_code) {
5036 __ lw(t1, FieldMemOperand(a2, 0)); 5032 __ lw(t1, FieldMemOperand(a2, 0));
5037 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); 5033 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex);
5038 __ Assert(eq, kExpectedAllocationSite, t1, Operand(at)); 5034 __ Assert(eq, kExpectedAllocationSite, t1, Operand(at));
5039 } 5035 }
5040 5036
5041 // Save the resulting elements kind in type info. We can't just store a3 5037 // Save the resulting elements kind in type info. We can't just store a3
5042 // in the AllocationSite::transition_info field because elements kind is 5038 // in the AllocationSite::transition_info field because elements kind is
5043 // restricted to a portion of the field...upper bits need to be left alone. 5039 // restricted to a portion of the field...upper bits need to be left alone.
5044 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); 5040 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0);
5045 __ lw(t0, FieldMemOperand(a2, AllocationSite::kTransitionInfoOffset)); 5041 __ lw(t0, FieldMemOperand(a2, AllocationSite::kTransitionInfoOffset));
5046 __ Addu(t0, t0, Operand(Smi::FromInt(kFastElementsKindPackedToHoley))); 5042 __ Addu(t0, t0, Operand(Smi::FromInt(kFastElementsKindPackedToHoley)));
5047 __ sw(t0, FieldMemOperand(a2, AllocationSite::kTransitionInfoOffset)); 5043 __ sw(t0, FieldMemOperand(a2, AllocationSite::kTransitionInfoOffset));
5048 5044
5049 5045
5050 __ bind(&normal_sequence); 5046 __ bind(&normal_sequence);
5051 int last_index = GetSequenceIndexFromFastElementsKind( 5047 int last_index = GetSequenceIndexFromFastElementsKind(
5052 TERMINAL_FAST_ELEMENTS_KIND); 5048 TERMINAL_FAST_ELEMENTS_KIND);
5053 for (int i = 0; i <= last_index; ++i) { 5049 for (int i = 0; i <= last_index; ++i) {
5054 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 5050 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
5055 ArraySingleArgumentConstructorStub stub(kind); 5051 ArraySingleArgumentConstructorStub stub(masm->isolate(), kind);
5056 __ TailCallStub(&stub, eq, a3, Operand(kind)); 5052 __ TailCallStub(&stub, eq, a3, Operand(kind));
5057 } 5053 }
5058 5054
5059 // If we reached this point there is a problem. 5055 // If we reached this point there is a problem.
5060 __ Abort(kUnexpectedElementsKindInArrayConstructor); 5056 __ Abort(kUnexpectedElementsKindInArrayConstructor);
5061 } else { 5057 } else {
5062 UNREACHABLE(); 5058 UNREACHABLE();
5063 } 5059 }
5064 } 5060 }
5065 5061
5066 5062
5067 template<class T> 5063 template<class T>
5068 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { 5064 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
5069 int to_index = GetSequenceIndexFromFastElementsKind( 5065 int to_index = GetSequenceIndexFromFastElementsKind(
5070 TERMINAL_FAST_ELEMENTS_KIND); 5066 TERMINAL_FAST_ELEMENTS_KIND);
5071 for (int i = 0; i <= to_index; ++i) { 5067 for (int i = 0; i <= to_index; ++i) {
5072 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 5068 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
5073 T stub(kind); 5069 T stub(isolate, kind);
5074 stub.GetCode(isolate); 5070 stub.GetCode(isolate);
5075 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { 5071 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
5076 T stub1(kind, DISABLE_ALLOCATION_SITES); 5072 T stub1(isolate, kind, DISABLE_ALLOCATION_SITES);
5077 stub1.GetCode(isolate); 5073 stub1.GetCode(isolate);
5078 } 5074 }
5079 } 5075 }
5080 } 5076 }
5081 5077
5082 5078
5083 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { 5079 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
5084 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( 5080 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
5085 isolate); 5081 isolate);
5086 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>( 5082 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
5087 isolate); 5083 isolate);
5088 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>( 5084 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
5089 isolate); 5085 isolate);
5090 } 5086 }
5091 5087
5092 5088
5093 void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime( 5089 void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
5094 Isolate* isolate) { 5090 Isolate* isolate) {
5095 ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS }; 5091 ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
5096 for (int i = 0; i < 2; i++) { 5092 for (int i = 0; i < 2; i++) {
5097 // For internal arrays we only need a few things. 5093 // For internal arrays we only need a few things.
5098 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]); 5094 InternalArrayNoArgumentConstructorStub stubh1(isolate, kinds[i]);
5099 stubh1.GetCode(isolate); 5095 stubh1.GetCode(isolate);
5100 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]); 5096 InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
5101 stubh2.GetCode(isolate); 5097 stubh2.GetCode(isolate);
5102 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]); 5098 InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
5103 stubh3.GetCode(isolate); 5099 stubh3.GetCode(isolate);
5104 } 5100 }
5105 } 5101 }
5106 5102
5107 5103
5108 void ArrayConstructorStub::GenerateDispatchToArrayStub( 5104 void ArrayConstructorStub::GenerateDispatchToArrayStub(
5109 MacroAssembler* masm, 5105 MacroAssembler* masm,
5110 AllocationSiteOverrideMode mode) { 5106 AllocationSiteOverrideMode mode) {
5111 if (argument_count_ == ANY) { 5107 if (argument_count_ == ANY) {
5112 Label not_zero_case, not_one_case; 5108 Label not_zero_case, not_one_case;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
5171 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); 5167 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
5172 5168
5173 __ bind(&no_info); 5169 __ bind(&no_info);
5174 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); 5170 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES);
5175 } 5171 }
5176 5172
5177 5173
5178 void InternalArrayConstructorStub::GenerateCase( 5174 void InternalArrayConstructorStub::GenerateCase(
5179 MacroAssembler* masm, ElementsKind kind) { 5175 MacroAssembler* masm, ElementsKind kind) {
5180 5176
5181 InternalArrayNoArgumentConstructorStub stub0(kind); 5177 InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
5182 __ TailCallStub(&stub0, lo, a0, Operand(1)); 5178 __ TailCallStub(&stub0, lo, a0, Operand(1));
5183 5179
5184 InternalArrayNArgumentsConstructorStub stubN(kind); 5180 InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
5185 __ TailCallStub(&stubN, hi, a0, Operand(1)); 5181 __ TailCallStub(&stubN, hi, a0, Operand(1));
5186 5182
5187 if (IsFastPackedElementsKind(kind)) { 5183 if (IsFastPackedElementsKind(kind)) {
5188 // We might need to create a holey array 5184 // We might need to create a holey array
5189 // look at the first argument. 5185 // look at the first argument.
5190 __ lw(at, MemOperand(sp, 0)); 5186 __ lw(at, MemOperand(sp, 0));
5191 5187
5192 InternalArraySingleArgumentConstructorStub 5188 InternalArraySingleArgumentConstructorStub
5193 stub1_holey(GetHoleyElementsKind(kind)); 5189 stub1_holey(isolate(), GetHoleyElementsKind(kind));
5194 __ TailCallStub(&stub1_holey, ne, at, Operand(zero_reg)); 5190 __ TailCallStub(&stub1_holey, ne, at, Operand(zero_reg));
5195 } 5191 }
5196 5192
5197 InternalArraySingleArgumentConstructorStub stub1(kind); 5193 InternalArraySingleArgumentConstructorStub stub1(isolate(), kind);
5198 __ TailCallStub(&stub1); 5194 __ TailCallStub(&stub1);
5199 } 5195 }
5200 5196
5201 5197
5202 void InternalArrayConstructorStub::Generate(MacroAssembler* masm) { 5198 void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
5203 // ----------- S t a t e ------------- 5199 // ----------- S t a t e -------------
5204 // -- a0 : argc 5200 // -- a0 : argc
5205 // -- a1 : constructor 5201 // -- a1 : constructor
5206 // -- sp[0] : return address 5202 // -- sp[0] : return address
5207 // -- sp[4] : last argument 5203 // -- sp[4] : last argument
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
5277 5273
5278 STATIC_ASSERT(FCA::kContextSaveIndex == 6); 5274 STATIC_ASSERT(FCA::kContextSaveIndex == 6);
5279 STATIC_ASSERT(FCA::kCalleeIndex == 5); 5275 STATIC_ASSERT(FCA::kCalleeIndex == 5);
5280 STATIC_ASSERT(FCA::kDataIndex == 4); 5276 STATIC_ASSERT(FCA::kDataIndex == 4);
5281 STATIC_ASSERT(FCA::kReturnValueOffset == 3); 5277 STATIC_ASSERT(FCA::kReturnValueOffset == 3);
5282 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); 5278 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
5283 STATIC_ASSERT(FCA::kIsolateIndex == 1); 5279 STATIC_ASSERT(FCA::kIsolateIndex == 1);
5284 STATIC_ASSERT(FCA::kHolderIndex == 0); 5280 STATIC_ASSERT(FCA::kHolderIndex == 0);
5285 STATIC_ASSERT(FCA::kArgsLength == 7); 5281 STATIC_ASSERT(FCA::kArgsLength == 7);
5286 5282
5287 Isolate* isolate = masm->isolate();
5288
5289 // Save context, callee and call data. 5283 // Save context, callee and call data.
5290 __ Push(context, callee, call_data); 5284 __ Push(context, callee, call_data);
5291 // Load context from callee. 5285 // Load context from callee.
5292 __ lw(context, FieldMemOperand(callee, JSFunction::kContextOffset)); 5286 __ lw(context, FieldMemOperand(callee, JSFunction::kContextOffset));
5293 5287
5294 Register scratch = call_data; 5288 Register scratch = call_data;
5295 if (!call_data_undefined) { 5289 if (!call_data_undefined) {
5296 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); 5290 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
5297 } 5291 }
5298 // Push return value and default return value. 5292 // Push return value and default return value.
5299 __ Push(scratch, scratch); 5293 __ Push(scratch, scratch);
5300 __ li(scratch, 5294 __ li(scratch,
5301 Operand(ExternalReference::isolate_address(isolate))); 5295 Operand(ExternalReference::isolate_address(isolate())));
5302 // Push isolate and holder. 5296 // Push isolate and holder.
5303 __ Push(scratch, holder); 5297 __ Push(scratch, holder);
5304 5298
5305 // Prepare arguments. 5299 // Prepare arguments.
5306 __ mov(scratch, sp); 5300 __ mov(scratch, sp);
5307 5301
5308 // Allocate the v8::Arguments structure in the arguments' space since 5302 // Allocate the v8::Arguments structure in the arguments' space since
5309 // it's not controlled by GC. 5303 // it's not controlled by GC.
5310 const int kApiStackSpace = 4; 5304 const int kApiStackSpace = 4;
5311 5305
(...skipping 13 matching lines...) Expand all
5325 __ li(at, Operand(argc)); 5319 __ li(at, Operand(argc));
5326 __ sw(at, MemOperand(a0, 2 * kPointerSize)); 5320 __ sw(at, MemOperand(a0, 2 * kPointerSize));
5327 // FunctionCallbackInfo::is_construct_call = 0 5321 // FunctionCallbackInfo::is_construct_call = 0
5328 __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize)); 5322 __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize));
5329 5323
5330 const int kStackUnwindSpace = argc + FCA::kArgsLength + 1; 5324 const int kStackUnwindSpace = argc + FCA::kArgsLength + 1;
5331 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); 5325 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
5332 ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL; 5326 ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
5333 ApiFunction thunk_fun(thunk_address); 5327 ApiFunction thunk_fun(thunk_address);
5334 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, 5328 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
5335 masm->isolate()); 5329 isolate());
5336 5330
5337 AllowExternalCallThatCantCauseGC scope(masm); 5331 AllowExternalCallThatCantCauseGC scope(masm);
5338 MemOperand context_restore_operand( 5332 MemOperand context_restore_operand(
5339 fp, (2 + FCA::kContextSaveIndex) * kPointerSize); 5333 fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
5340 // Stores return the first js argument. 5334 // Stores return the first js argument.
5341 int return_value_offset = 0; 5335 int return_value_offset = 0;
5342 if (is_store) { 5336 if (is_store) {
5343 return_value_offset = 2 + FCA::kArgsLength; 5337 return_value_offset = 2 + FCA::kArgsLength;
5344 } else { 5338 } else {
5345 return_value_offset = 2 + FCA::kReturnValueOffset; 5339 return_value_offset = 2 + FCA::kReturnValueOffset;
(...skipping 30 matching lines...) Expand all
5376 __ sw(a1, MemOperand(sp, 1 * kPointerSize)); 5370 __ sw(a1, MemOperand(sp, 1 * kPointerSize));
5377 __ Addu(a1, sp, Operand(1 * kPointerSize)); // a1 = AccessorInfo& 5371 __ Addu(a1, sp, Operand(1 * kPointerSize)); // a1 = AccessorInfo&
5378 5372
5379 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; 5373 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
5380 5374
5381 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); 5375 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
5382 ExternalReference::Type thunk_type = 5376 ExternalReference::Type thunk_type =
5383 ExternalReference::PROFILING_GETTER_CALL; 5377 ExternalReference::PROFILING_GETTER_CALL;
5384 ApiFunction thunk_fun(thunk_address); 5378 ApiFunction thunk_fun(thunk_address);
5385 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, 5379 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
5386 masm->isolate()); 5380 isolate());
5387 __ CallApiFunctionAndReturn(api_function_address, 5381 __ CallApiFunctionAndReturn(api_function_address,
5388 thunk_ref, 5382 thunk_ref,
5389 kStackUnwindSpace, 5383 kStackUnwindSpace,
5390 MemOperand(fp, 6 * kPointerSize), 5384 MemOperand(fp, 6 * kPointerSize),
5391 NULL); 5385 NULL);
5392 } 5386 }
5393 5387
5394 5388
5395 #undef __ 5389 #undef __
5396 5390
5397 } } // namespace v8::internal 5391 } } // namespace v8::internal
5398 5392
5399 #endif // V8_TARGET_ARCH_MIPS 5393 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/code-stubs-mips.h ('k') | src/mips/debug-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698