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

Side by Side Diff: src/arm/deoptimizer-arm.cc

Issue 23526069: Refactor back edge table related code into a new class. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 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
« no previous file with comments | « no previous file | src/arm/full-codegen-arm.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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 ASSERT(prev_call_address == NULL || 74 ASSERT(prev_call_address == NULL ||
75 call_address >= prev_call_address + patch_size()); 75 call_address >= prev_call_address + patch_size());
76 ASSERT(call_address + patch_size() <= code->instruction_end()); 76 ASSERT(call_address + patch_size() <= code->instruction_end());
77 #ifdef DEBUG 77 #ifdef DEBUG
78 prev_call_address = call_address; 78 prev_call_address = call_address;
79 #endif 79 #endif
80 } 80 }
81 } 81 }
82 82
83 83
84 static const int32_t kBranchBeforeInterrupt = 0x5a000004;
85
86 // The back edge bookkeeping code matches the pattern:
87 //
88 // <decrement profiling counter>
89 // 2a 00 00 01 bpl ok
90 // e5 9f c? ?? ldr ip, [pc, <interrupt stub address>]
91 // e1 2f ff 3c blx ip
92 // ok-label
93 //
94 // We patch the code to the following form:
95 //
96 // <decrement profiling counter>
97 // e1 a0 00 00 mov r0, r0 (NOP)
98 // e5 9f c? ?? ldr ip, [pc, <on-stack replacement address>]
99 // e1 2f ff 3c blx ip
100 // ok-label
101
102 void Deoptimizer::PatchInterruptCodeAt(Code* unoptimized_code,
103 Address pc_after,
104 Code* replacement_code) {
105 static const int kInstrSize = Assembler::kInstrSize;
106 // Turn the jump into nops.
107 CodePatcher patcher(pc_after - 3 * kInstrSize, 1);
108 patcher.masm()->nop();
109 // Replace the call address.
110 uint32_t interrupt_address_offset = Memory::uint16_at(pc_after -
111 2 * kInstrSize) & 0xfff;
112 Address interrupt_address_pointer = pc_after + interrupt_address_offset;
113 Memory::uint32_at(interrupt_address_pointer) =
114 reinterpret_cast<uint32_t>(replacement_code->entry());
115
116 unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch(
117 unoptimized_code, pc_after - 2 * kInstrSize, replacement_code);
118 }
119
120
121 void Deoptimizer::RevertInterruptCodeAt(Code* unoptimized_code,
122 Address pc_after,
123 Code* interrupt_code) {
124 static const int kInstrSize = Assembler::kInstrSize;
125 // Restore the original jump.
126 CodePatcher patcher(pc_after - 3 * kInstrSize, 1);
127 patcher.masm()->b(4 * kInstrSize, pl); // ok-label is 4 instructions later.
128 ASSERT_EQ(kBranchBeforeInterrupt,
129 Memory::int32_at(pc_after - 3 * kInstrSize));
130 // Restore the original call address.
131 uint32_t interrupt_address_offset = Memory::uint16_at(pc_after -
132 2 * kInstrSize) & 0xfff;
133 Address interrupt_address_pointer = pc_after + interrupt_address_offset;
134 Memory::uint32_at(interrupt_address_pointer) =
135 reinterpret_cast<uint32_t>(interrupt_code->entry());
136
137 interrupt_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch(
138 unoptimized_code, pc_after - 2 * kInstrSize, interrupt_code);
139 }
140
141
142 #ifdef DEBUG
143 Deoptimizer::InterruptPatchState Deoptimizer::GetInterruptPatchState(
144 Isolate* isolate,
145 Code* unoptimized_code,
146 Address pc_after) {
147 static const int kInstrSize = Assembler::kInstrSize;
148 ASSERT(Memory::int32_at(pc_after - kInstrSize) == kBlxIp);
149
150 uint32_t interrupt_address_offset =
151 Memory::uint16_at(pc_after - 2 * kInstrSize) & 0xfff;
152 Address interrupt_address_pointer = pc_after + interrupt_address_offset;
153
154 if (Assembler::IsNop(Assembler::instr_at(pc_after - 3 * kInstrSize))) {
155 ASSERT(Assembler::IsLdrPcImmediateOffset(
156 Assembler::instr_at(pc_after - 2 * kInstrSize)));
157 Code* osr_builtin =
158 isolate->builtins()->builtin(Builtins::kOnStackReplacement);
159 ASSERT(reinterpret_cast<uint32_t>(osr_builtin->entry()) ==
160 Memory::uint32_at(interrupt_address_pointer));
161 return PATCHED_FOR_OSR;
162 } else {
163 // Get the interrupt stub code object to match against from cache.
164 Code* interrupt_builtin =
165 isolate->builtins()->builtin(Builtins::kInterruptCheck);
166 ASSERT(Assembler::IsLdrPcImmediateOffset(
167 Assembler::instr_at(pc_after - 2 * kInstrSize)));
168 ASSERT_EQ(kBranchBeforeInterrupt,
169 Memory::int32_at(pc_after - 3 * kInstrSize));
170 ASSERT(reinterpret_cast<uint32_t>(interrupt_builtin->entry()) ==
171 Memory::uint32_at(interrupt_address_pointer));
172 return NOT_PATCHED;
173 }
174 }
175 #endif // DEBUG
176
177
178 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { 84 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
179 // Set the register values. The values are not important as there are no 85 // Set the register values. The values are not important as there are no
180 // callee saved registers in JavaScript frames, so all registers are 86 // callee saved registers in JavaScript frames, so all registers are
181 // spilled. Registers fp and sp are set to the correct values though. 87 // spilled. Registers fp and sp are set to the correct values though.
182 88
183 for (int i = 0; i < Register::kNumRegisters; i++) { 89 for (int i = 0; i < Register::kNumRegisters; i++) {
184 input_->SetRegister(i, i * 4); 90 input_->SetRegister(i, i * 4);
185 } 91 }
186 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp())); 92 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
187 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp())); 93 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 344
439 345
440 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { 346 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
441 SetFrameSlot(offset, value); 347 SetFrameSlot(offset, value);
442 } 348 }
443 349
444 350
445 #undef __ 351 #undef __
446 352
447 } } // namespace v8::internal 353 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/arm/full-codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698