Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 825 // Force constant pool emission at the end of the deferred code to make | 825 // Force constant pool emission at the end of the deferred code to make |
| 826 // sure that no constant pools are emitted after deferred code because | 826 // sure that no constant pools are emitted after deferred code because |
| 827 // deferred code generation is the last step which generates code. The two | 827 // deferred code generation is the last step which generates code. The two |
| 828 // following steps will only output data used by crakshaft. | 828 // following steps will only output data used by crakshaft. |
| 829 masm()->CheckConstPool(true, false); | 829 masm()->CheckConstPool(true, false); |
| 830 | 830 |
| 831 return !is_aborted(); | 831 return !is_aborted(); |
| 832 } | 832 } |
| 833 | 833 |
| 834 | 834 |
| 835 bool LCodeGen::GenerateDeoptJumpTable() { | 835 bool LCodeGen::GenerateDeoptJumpTable() { |
|
jochen (gone - plz use gerrit)
2014/02/05 08:57:38
ARM has a check that the table is not too far away
Rodolph Perfetta (ARM)
2014/02/05 10:52:43
Right, but in the mean time a debug check may save
| |
| 836 TODO_UNIMPLEMENTED("generate level 1 deopt table"); | 836 if (deopt_jump_table_.length() > 0) { |
| 837 Comment(";;; -------------------- Jump table --------------------"); | |
| 838 } | |
| 839 Label table_start; | |
| 840 __ bind(&table_start); | |
|
ulan
2014/02/05 10:25:41
Use Bind instead.
| |
| 841 Label needs_frame; | |
| 842 for (int i = 0; i < deopt_jump_table_.length(); i++) { | |
| 843 __ Bind(&deopt_jump_table_[i].label); | |
| 844 Address entry = deopt_jump_table_[i].address; | |
| 845 Deoptimizer::BailoutType type = deopt_jump_table_[i].bailout_type; | |
| 846 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); | |
| 847 if (id == Deoptimizer::kNotDeoptimizationEntry) { | |
| 848 Comment(";;; jump table entry %d.", i); | |
| 849 } else { | |
| 850 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); | |
| 851 } | |
| 852 if (deopt_jump_table_[i].needs_frame) { | |
| 853 __ Mov(__ Tmp0(), Operand(ExternalReference::ForDeoptEntry(entry))); | |
|
ulan
2014/02/05 10:25:41
I am not sure that we can use Tmp0, Tmp1 here. Rod
jochen (gone - plz use gerrit)
2014/02/05 10:34:17
Tmp1() was uses in the old code (see line 1009) so
Rodolph Perfetta (ARM)
2014/02/05 10:52:43
In Theory it is never safe to use them outside the
| |
| 854 if (needs_frame.is_bound()) { | |
| 855 __ B(&needs_frame); | |
| 856 } else { | |
| 857 __ Bind(&needs_frame); | |
| 858 // This variant of deopt can only be used with stubs. Since we don't | |
| 859 // have a function pointer to install in the stack frame that we're | |
| 860 // building, install a special marker there instead. | |
| 861 ASSERT(info()->IsStub()); | |
| 862 __ Mov(__ Tmp1(), Operand(Smi::FromInt(StackFrame::STUB))); | |
| 863 __ Push(lr, fp, cp, __ Tmp1()); | |
| 864 __ Add(fp, __ StackPointer(), 2 * kPointerSize); | |
| 865 __ Call(__ Tmp0()); | |
| 866 } | |
| 867 } else { | |
| 868 __ Call(entry, RelocInfo::RUNTIME_ENTRY); | |
| 869 } | |
| 870 masm()->CheckConstPool(false, false); | |
| 871 } | |
| 837 | 872 |
| 838 // TODO(jbramley): On ARM, the deopt entry for stubs is different in that it | 873 // Force constant pool emission at the end of the deopt jump table to make |
| 839 // inserts a special marker instead of a function pointer. We need to do that | 874 // sure that no constant pools are emitted after. |
| 840 // same on A64, but since we don't use the jump table, we have to do it | 875 masm()->CheckConstPool(true, false); |
| 841 // in LCodeGen::Deoptimize(). | |
| 842 | 876 |
| 843 // The deoptimization jump table is the last part of the instruction | 877 // The deoptimization jump table is the last part of the instruction |
| 844 // sequence. Mark the generated code as done unless we bailed out. | 878 // sequence. Mark the generated code as done unless we bailed out. |
| 845 if (!is_aborted()) status_ = DONE; | 879 if (!is_aborted()) status_ = DONE; |
| 846 return !is_aborted(); | 880 return !is_aborted(); |
| 847 } | 881 } |
| 848 | 882 |
| 849 | 883 |
| 850 bool LCodeGen::GenerateSafepointTable() { | 884 bool LCodeGen::GenerateSafepointTable() { |
| 851 ASSERT(is_done()); | 885 ASSERT(is_done()); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 988 ASSERT(frame_is_built_); | 1022 ASSERT(frame_is_built_); |
| 989 __ Call(entry, RelocInfo::RUNTIME_ENTRY); | 1023 __ Call(entry, RelocInfo::RUNTIME_ENTRY); |
| 990 return; | 1024 return; |
| 991 } | 1025 } |
| 992 | 1026 |
| 993 if (info()->ShouldTrapOnDeopt()) { | 1027 if (info()->ShouldTrapOnDeopt()) { |
| 994 __ Debug("trap_on_deopt", __LINE__, BREAK); | 1028 __ Debug("trap_on_deopt", __LINE__, BREAK); |
| 995 } | 1029 } |
| 996 | 1030 |
| 997 | 1031 |
| 998 // TODO(all): Currently this code directly jump to the second level deopt | |
| 999 // table entry. This code need to be updated if we decide to use the | |
| 1000 // 2 levels of table. | |
| 1001 ASSERT(info()->IsStub() || frame_is_built_); | 1032 ASSERT(info()->IsStub() || frame_is_built_); |
| 1002 if (frame_is_built_) { | 1033 if (frame_is_built_) { |
| 1003 __ Call(entry, RelocInfo::RUNTIME_ENTRY); | 1034 __ Call(entry, RelocInfo::RUNTIME_ENTRY); |
| 1004 } else { | 1035 } else { |
| 1005 // We need to build a frame to deoptimize a stub. Because stubs don't have a | 1036 // We often have several deopts to the same entry, reuse the last |
| 1006 // function pointer to put in the frame, put a special marker there instead. | 1037 // jump entry if this is the case. |
| 1007 // TODO(jbramley): In other architectures, this happens in the jump table. | 1038 if (deopt_jump_table_.is_empty() || |
| 1008 // This is a temporary hack until we implement jump tables in A64. | 1039 (deopt_jump_table_.last().address != entry) || |
| 1009 __ Mov(__ Tmp1(), Operand(Smi::FromInt(StackFrame::STUB))); | 1040 (deopt_jump_table_.last().bailout_type != bailout_type) || |
| 1010 __ Push(lr, fp, cp, __ Tmp1()); | 1041 (deopt_jump_table_.last().needs_frame != !frame_is_built_)) { |
| 1011 __ Add(fp, __ StackPointer(), 2 * kPointerSize); | 1042 Deoptimizer::JumpTableEntry table_entry(entry, |
| 1012 // TODO(jbramley): Can this be a jump, rather than a call? | 1043 bailout_type, |
| 1013 __ Call(entry, RelocInfo::RUNTIME_ENTRY); | 1044 !frame_is_built_); |
| 1045 deopt_jump_table_.Add(table_entry, zone()); | |
| 1046 } | |
| 1047 __ B(&deopt_jump_table_.last().label); | |
| 1014 } | 1048 } |
| 1015 } | 1049 } |
| 1016 | 1050 |
| 1017 | 1051 |
| 1018 void LCodeGen::Deoptimize(LEnvironment* environment) { | 1052 void LCodeGen::Deoptimize(LEnvironment* environment) { |
| 1019 Deoptimizer::BailoutType bailout_type = info()->IsStub() ? Deoptimizer::LAZY | 1053 Deoptimizer::BailoutType bailout_type = info()->IsStub() ? Deoptimizer::LAZY |
| 1020 : Deoptimizer::EAGER; | 1054 : Deoptimizer::EAGER; |
| 1021 Deoptimize(environment, bailout_type); | 1055 Deoptimize(environment, bailout_type); |
| 1022 } | 1056 } |
| 1023 | 1057 |
| (...skipping 4573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5597 __ Bind(&out_of_object); | 5631 __ Bind(&out_of_object); |
| 5598 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5632 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 5599 // Index is equal to negated out of object property index plus 1. | 5633 // Index is equal to negated out of object property index plus 1. |
| 5600 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5634 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 5601 __ Ldr(result, FieldMemOperand(result, | 5635 __ Ldr(result, FieldMemOperand(result, |
| 5602 FixedArray::kHeaderSize - kPointerSize)); | 5636 FixedArray::kHeaderSize - kPointerSize)); |
| 5603 __ Bind(&done); | 5637 __ Bind(&done); |
| 5604 } | 5638 } |
| 5605 | 5639 |
| 5606 } } // namespace v8::internal | 5640 } } // namespace v8::internal |
| OLD | NEW |