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

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 6347067: Fix potential overwriting of debug jumps of following code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge/build-x64
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 181
182 // Deferred code is the last part of the instruction sequence. Mark 182 // Deferred code is the last part of the instruction sequence. Mark
183 // the generated code as done unless we bailed out. 183 // the generated code as done unless we bailed out.
184 if (!is_aborted()) status_ = DONE; 184 if (!is_aborted()) status_ = DONE;
185 return !is_aborted(); 185 return !is_aborted();
186 } 186 }
187 187
188 188
189 bool LCodeGen::GenerateSafepointTable() { 189 bool LCodeGen::GenerateSafepointTable() {
190 ASSERT(is_done()); 190 ASSERT(is_done());
191 // Ensure that patching a deoptimization point won't overwrite the table. 191 // Ensure that there is space at the end of the code to write a number
192 for (int i = 0; i < Assembler::kCallInstructionLength; i++) { 192 // of jump instructions, as well as to afford writing a call near the end
193 masm()->int3(); 193 // of the code.
194 // The jumps are used when there isn't room in the code stream to write
195 // a long call instruction. Instead it writes a shorter call to a nearby
196 // jump instruction.
fschneider 2011/02/02 12:54:16 The comment should say that this is used for lazy
Lasse Reichstein 2011/02/03 14:14:12 done.
197 int short_deopts = safepoints_.CountShortDeoptimizationIntervals(
198 static_cast<unsigned>(MacroAssembler::kJumpInstructionLength));
199 int byte_count = MacroAssembler::kCallInstructionLength +
200 (short_deopts) * MacroAssembler::kJumpInstructionLength;
201 while (byte_count > 0) {
202 __ int3();
203 byte_count--;
194 } 204 }
195 safepoints_.Emit(masm(), StackSlotCount()); 205 safepoints_.Emit(masm(), StackSlotCount());
196 return !is_aborted(); 206 return !is_aborted();
197 } 207 }
198 208
199 209
200 Register LCodeGen::ToRegister(int index) const { 210 Register LCodeGen::ToRegister(int index) const {
201 return Register::FromAllocationIndex(index); 211 return Register::FromAllocationIndex(index);
202 } 212 }
203 213
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 inlined_function_count_ = deoptimization_literals_.length(); 508 inlined_function_count_ = deoptimization_literals_.length();
499 } 509 }
500 510
501 511
502 void LCodeGen::RecordSafepoint( 512 void LCodeGen::RecordSafepoint(
503 LPointerMap* pointers, 513 LPointerMap* pointers,
504 Safepoint::Kind kind, 514 Safepoint::Kind kind,
505 int arguments, 515 int arguments,
506 int deoptimization_index) { 516 int deoptimization_index) {
507 const ZoneList<LOperand*>* operands = pointers->operands(); 517 const ZoneList<LOperand*>* operands = pointers->operands();
518
508 Safepoint safepoint = safepoints_.DefineSafepoint(masm(), 519 Safepoint safepoint = safepoints_.DefineSafepoint(masm(),
509 kind, arguments, deoptimization_index); 520 kind, arguments, deoptimization_index);
510 for (int i = 0; i < operands->length(); i++) { 521 for (int i = 0; i < operands->length(); i++) {
511 LOperand* pointer = operands->at(i); 522 LOperand* pointer = operands->at(i);
512 if (pointer->IsStackSlot()) { 523 if (pointer->IsStackSlot()) {
513 safepoint.DefinePointerSlot(pointer->index()); 524 safepoint.DefinePointerSlot(pointer->index());
514 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { 525 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) {
515 safepoint.DefinePointerRegister(ToRegister(pointer)); 526 safepoint.DefinePointerRegister(ToRegister(pointer));
516 } 527 }
517 } 528 }
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 } 673 }
663 674
664 675
665 void LCodeGen::DoConstantT(LConstantT* instr) { 676 void LCodeGen::DoConstantT(LConstantT* instr) {
666 ASSERT(instr->result()->IsRegister()); 677 ASSERT(instr->result()->IsRegister());
667 __ Move(ToRegister(instr->result()), instr->value()); 678 __ Move(ToRegister(instr->result()), instr->value());
668 } 679 }
669 680
670 681
671 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 682 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
672 Abort("Unimplemented: %s", "DoJSArrayLength"); 683 Register result = ToRegister(instr->result());
684 Register array = ToRegister(instr->InputAt(0));
685 __ movq(result, FieldOperand(array, JSArray::kLengthOffset));
673 } 686 }
674 687
675 688
676 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) { 689 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
677 Abort("Unimplemented: %s", "DoFixedArrayLength"); 690 Abort("Unimplemented: %s", "DoFixedArrayLength");
678 } 691 }
679 692
680 693
681 void LCodeGen::DoValueOf(LValueOf* instr) { 694 void LCodeGen::DoValueOf(LValueOf* instr) {
682 Abort("Unimplemented: %s", "DoValueOf"); 695 Abort("Unimplemented: %s", "DoValueOf");
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 __ push(rax); 1401 __ push(rax);
1389 __ CallRuntime(Runtime::kTraceExit, 1); 1402 __ CallRuntime(Runtime::kTraceExit, 1);
1390 } 1403 }
1391 __ movq(rsp, rbp); 1404 __ movq(rsp, rbp);
1392 __ pop(rbp); 1405 __ pop(rbp);
1393 __ ret((ParameterCount() + 1) * kPointerSize); 1406 __ ret((ParameterCount() + 1) * kPointerSize);
1394 } 1407 }
1395 1408
1396 1409
1397 void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) { 1410 void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) {
1398 Register result = ToRegister(instr->result()); 1411 Abort("Unimplemented: %s", "DoLoadGlobal");
1399 if (result.is(rax)) {
1400 __ load_rax(instr->hydrogen()->cell().location(),
1401 RelocInfo::GLOBAL_PROPERTY_CELL);
1402 } else {
1403 __ movq(result, instr->hydrogen()->cell(), RelocInfo::GLOBAL_PROPERTY_CELL);
1404 __ movq(result, Operand(result, 0));
1405 }
1406 if (instr->hydrogen()->check_hole_value()) {
1407 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
1408 DeoptimizeIf(equal, instr->environment());
1409 }
1410 } 1412 }
1411 1413
1412 1414
1413 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { 1415 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) {
1414 Register value = ToRegister(instr->InputAt(0)); 1416 Abort("Unimplemented: %s", "DoStoreGlobal");
1415 if (value.is(rax)) {
1416 __ store_rax(instr->hydrogen()->cell().location(),
1417 RelocInfo::GLOBAL_PROPERTY_CELL);
1418 } else {
1419 __ movq(kScratchRegister,
1420 Handle<Object>::cast(instr->hydrogen()->cell()),
1421 RelocInfo::GLOBAL_PROPERTY_CELL);
1422 __ movq(Operand(kScratchRegister, 0), value);
1423 }
1424 } 1417 }
1425 1418
1426 1419
1427 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 1420 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
1428 Abort("Unimplemented: %s", "DoLoadContextSlot"); 1421 Abort("Unimplemented: %s", "DoLoadContextSlot");
1429 } 1422 }
1430 1423
1431 1424
1432 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 1425 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
1433 Register object = ToRegister(instr->InputAt(0)); 1426 Register object = ToRegister(instr->InputAt(0));
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1519 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { 1512 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
1520 Register result = ToRegister(instr->result()); 1513 Register result = ToRegister(instr->result());
1521 __ movq(result, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); 1514 __ movq(result, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
1522 __ movq(result, FieldOperand(result, GlobalObject::kGlobalReceiverOffset)); 1515 __ movq(result, FieldOperand(result, GlobalObject::kGlobalReceiverOffset));
1523 } 1516 }
1524 1517
1525 1518
1526 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, 1519 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
1527 int arity, 1520 int arity,
1528 LInstruction* instr) { 1521 LInstruction* instr) {
1529 Abort("Unimplemented: %s", "CallKnownFunction"); 1522 // Change context if needed.
1523 bool change_context =
1524 (graph()->info()->closure()->context() != function->context()) ||
1525 scope()->contains_with() ||
1526 (scope()->num_heap_slots() > 0);
1527 if (change_context) {
1528 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
1529 }
1530
1531 // Set rax to arguments count if adaption is not needed. Assumes that rax
1532 // is available to write to at this point.
1533 if (!function->NeedsArgumentsAdaption()) {
1534 __ Set(rax, arity);
1535 }
1536
1537 LPointerMap* pointers = instr->pointer_map();
1538 RecordPosition(pointers->position());
1539
1540 // Invoke function.
1541 if (*function == *graph()->info()->closure()) {
1542 __ CallSelf();
1543 } else {
1544 __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset));
1545 }
1546
1547 // Setup deoptimization.
1548 RegisterLazyDeoptimization(instr);
1549
1550 // Restore context.
1551 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1530 } 1552 }
1531 1553
1532 1554
1533 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 1555 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
1534 Abort("Unimplemented: %s", "DoCallConstantFunction"); 1556 Abort("Unimplemented: %s", "DoCallConstantFunction");
1535 } 1557 }
1536 1558
1537 1559
1538 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 1560 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
1539 Abort("Unimplemented: %s", "DoDeferredMathAbsTaggedHeapNumber"); 1561 Abort("Unimplemented: %s", "DoDeferredMathAbsTaggedHeapNumber");
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 Abort("Unimplemented: %s", "DoCallFunction"); 1626 Abort("Unimplemented: %s", "DoCallFunction");
1605 } 1627 }
1606 1628
1607 1629
1608 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { 1630 void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
1609 Abort("Unimplemented: %s", "DoCallGlobal"); 1631 Abort("Unimplemented: %s", "DoCallGlobal");
1610 } 1632 }
1611 1633
1612 1634
1613 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { 1635 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
1614 Abort("Unimplemented: %s", "DoCallKnownGlobal"); 1636 ASSERT(ToRegister(instr->result()).is(rax));
1637 __ Move(rdi, instr->target());
1638 CallKnownFunction(instr->target(), instr->arity(), instr);
1615 } 1639 }
1616 1640
1617 1641
1618 void LCodeGen::DoCallNew(LCallNew* instr) { 1642 void LCodeGen::DoCallNew(LCallNew* instr) {
1619 ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); 1643 ASSERT(ToRegister(instr->InputAt(0)).is(rdi));
1620 ASSERT(ToRegister(instr->result()).is(rax)); 1644 ASSERT(ToRegister(instr->result()).is(rax));
1621 1645
1622 Handle<Code> builtin(Builtins::builtin(Builtins::JSConstructCall)); 1646 Handle<Code> builtin(Builtins::builtin(Builtins::JSConstructCall));
1623 __ Set(rax, instr->arity()); 1647 __ Set(rax, instr->arity());
1624 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); 1648 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1810 ASSERT(input->IsRegister()); 1834 ASSERT(input->IsRegister());
1811 Condition cc = masm()->CheckSmi(ToRegister(input)); 1835 Condition cc = masm()->CheckSmi(ToRegister(input));
1812 if (instr->condition() != equal) { 1836 if (instr->condition() != equal) {
1813 cc = NegateCondition(cc); 1837 cc = NegateCondition(cc);
1814 } 1838 }
1815 DeoptimizeIf(cc, instr->environment()); 1839 DeoptimizeIf(cc, instr->environment());
1816 } 1840 }
1817 1841
1818 1842
1819 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 1843 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
1820 Abort("Unimplemented: %s", "DoCheckInstanceType"); 1844 Register input = ToRegister(instr->InputAt(0));
1845 InstanceType first = instr->hydrogen()->first();
1846 InstanceType last = instr->hydrogen()->last();
1847
1848 __ movq(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset));
1849
1850 // If there is only one type in the interval check for equality.
1851 if (first == last) {
1852 __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset),
1853 Immediate(static_cast<int8_t>(first)));
1854 DeoptimizeIf(not_equal, instr->environment());
1855 } else if (first == FIRST_STRING_TYPE && last == LAST_STRING_TYPE) {
1856 // String has a dedicated bit in instance type.
1857 __ testb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset),
1858 Immediate(kIsNotStringMask));
1859 DeoptimizeIf(not_zero, instr->environment());
1860 } else {
1861 __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset),
1862 Immediate(static_cast<int8_t>(first)));
1863 DeoptimizeIf(below, instr->environment());
1864 // Omit check for the last type.
1865 if (last != LAST_TYPE) {
1866 __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset),
1867 Immediate(static_cast<int8_t>(last)));
1868 DeoptimizeIf(above, instr->environment());
1869 }
1870 }
1821 } 1871 }
1822 1872
1823 1873
1824 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { 1874 void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
1825 ASSERT(instr->InputAt(0)->IsRegister()); 1875 ASSERT(instr->InputAt(0)->IsRegister());
1826 Register reg = ToRegister(instr->InputAt(0)); 1876 Register reg = ToRegister(instr->InputAt(0));
1827 __ Cmp(reg, instr->hydrogen()->target()); 1877 __ Cmp(reg, instr->hydrogen()->target());
1828 DeoptimizeIf(not_equal, instr->environment()); 1878 DeoptimizeIf(not_equal, instr->environment());
1829 } 1879 }
1830 1880
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
2012 2062
2013 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { 2063 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
2014 Abort("Unimplemented: %s", "DoOsrEntry"); 2064 Abort("Unimplemented: %s", "DoOsrEntry");
2015 } 2065 }
2016 2066
2017 #undef __ 2067 #undef __
2018 2068
2019 } } // namespace v8::internal 2069 } } // namespace v8::internal
2020 2070
2021 #endif // V8_TARGET_ARCH_X64 2071 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/x64/deoptimizer-x64.cc ('K') | « src/x64/frames-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698