OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 10 matching lines...) Expand all Loading... |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #include "frames-inl.h" | 30 #include "frames-inl.h" |
| 31 #include "mark-compact.h" |
31 #include "scopeinfo.h" | 32 #include "scopeinfo.h" |
32 #include "string-stream.h" | 33 #include "string-stream.h" |
33 #include "top.h" | 34 #include "top.h" |
34 #include "zone-inl.h" | 35 #include "zone-inl.h" |
35 | 36 |
36 namespace v8 { namespace internal { | 37 namespace v8 { namespace internal { |
37 | 38 |
38 // Iterator that supports traversing the stack handlers of a | 39 // Iterator that supports traversing the stack handlers of a |
39 // particular frame. Needs to know the top of the handler chain. | 40 // particular frame. Needs to know the top of the handler chain. |
40 class StackHandlerIterator BASE_EMBEDDED { | 41 class StackHandlerIterator BASE_EMBEDDED { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 void JavaScriptFrameIterator::Reset() { | 156 void JavaScriptFrameIterator::Reset() { |
156 iterator_.Reset(); | 157 iterator_.Reset(); |
157 Advance(); | 158 Advance(); |
158 } | 159 } |
159 | 160 |
160 | 161 |
161 // ------------------------------------------------------------------------- | 162 // ------------------------------------------------------------------------- |
162 | 163 |
163 | 164 |
164 void StackHandler::Cook(Code* code) { | 165 void StackHandler::Cook(Code* code) { |
| 166 ASSERT(MarkCompactCollector::IsCompacting()); |
165 ASSERT(code->contains(pc())); | 167 ASSERT(code->contains(pc())); |
166 set_pc(AddressFrom<Address>(pc() - code->instruction_start())); | 168 set_pc(AddressFrom<Address>(pc() - code->instruction_start())); |
167 } | 169 } |
168 | 170 |
169 | 171 |
170 void StackHandler::Uncook(Code* code) { | 172 void StackHandler::Uncook(Code* code) { |
| 173 ASSERT(MarkCompactCollector::IsCompacting()); |
171 set_pc(code->instruction_start() + OffsetFrom(pc())); | 174 set_pc(code->instruction_start() + OffsetFrom(pc())); |
172 ASSERT(code->contains(pc())); | 175 ASSERT(code->contains(pc())); |
173 } | 176 } |
174 | 177 |
175 | 178 |
176 // ------------------------------------------------------------------------- | 179 // ------------------------------------------------------------------------- |
177 | 180 |
178 | 181 |
179 bool StackFrame::HasHandler() const { | 182 bool StackFrame::HasHandler() const { |
180 StackHandlerIterator it(this, top_handler()); | 183 StackHandlerIterator it(this, top_handler()); |
181 return !it.done(); | 184 return !it.done(); |
182 } | 185 } |
183 | 186 |
184 | 187 |
185 void StackFrame::CookFramesForThread(ThreadLocalTop* thread) { | 188 void StackFrame::CookFramesForThread(ThreadLocalTop* thread) { |
| 189 // Only cooking frames when the collector is compacting and thus moving code |
| 190 // around. |
| 191 ASSERT(MarkCompactCollector::IsCompacting()); |
186 ASSERT(!thread->stack_is_cooked()); | 192 ASSERT(!thread->stack_is_cooked()); |
187 for (StackFrameIterator it(thread); !it.done(); it.Advance()) { | 193 for (StackFrameIterator it(thread); !it.done(); it.Advance()) { |
188 it.frame()->Cook(); | 194 it.frame()->Cook(); |
189 } | 195 } |
190 thread->set_stack_is_cooked(true); | 196 thread->set_stack_is_cooked(true); |
191 } | 197 } |
192 | 198 |
193 | 199 |
194 void StackFrame::UncookFramesForThread(ThreadLocalTop* thread) { | 200 void StackFrame::UncookFramesForThread(ThreadLocalTop* thread) { |
| 201 // Only uncooking frames when the collector is compacting and thus moving code |
| 202 // around. |
| 203 ASSERT(MarkCompactCollector::IsCompacting()); |
195 ASSERT(thread->stack_is_cooked()); | 204 ASSERT(thread->stack_is_cooked()); |
196 for (StackFrameIterator it(thread); !it.done(); it.Advance()) { | 205 for (StackFrameIterator it(thread); !it.done(); it.Advance()) { |
197 it.frame()->Uncook(); | 206 it.frame()->Uncook(); |
198 } | 207 } |
199 thread->set_stack_is_cooked(false); | 208 thread->set_stack_is_cooked(false); |
200 } | 209 } |
201 | 210 |
202 | 211 |
203 void StackFrame::Cook() { | 212 void StackFrame::Cook() { |
204 Code* code = FindCode(); | 213 Code* code = this->code(); |
205 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { | 214 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { |
206 it.handler()->Cook(code); | 215 it.handler()->Cook(code); |
207 } | 216 } |
208 ASSERT(code->contains(pc())); | 217 ASSERT(code->contains(pc())); |
209 set_pc(AddressFrom<Address>(pc() - code->instruction_start())); | 218 set_pc(AddressFrom<Address>(pc() - code->instruction_start())); |
210 } | 219 } |
211 | 220 |
212 | 221 |
213 void StackFrame::Uncook() { | 222 void StackFrame::Uncook() { |
214 Code* code = FindCode(); | 223 Code* code = this->code(); |
215 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { | 224 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { |
216 it.handler()->Uncook(code); | 225 it.handler()->Uncook(code); |
217 } | 226 } |
218 set_pc(code->instruction_start() + OffsetFrom(pc())); | 227 set_pc(code->instruction_start() + OffsetFrom(pc())); |
219 ASSERT(code->contains(pc())); | 228 ASSERT(code->contains(pc())); |
220 } | 229 } |
221 | 230 |
222 | 231 |
223 Code* EntryFrame::FindCode() const { | 232 Code* EntryFrame::code() const { |
224 return Heap::js_entry_code(); | 233 return Heap::js_entry_code(); |
225 } | 234 } |
226 | 235 |
227 | 236 |
228 StackFrame::Type EntryFrame::GetCallerState(State* state) const { | 237 StackFrame::Type EntryFrame::GetCallerState(State* state) const { |
229 const int offset = EntryFrameConstants::kCallerFPOffset; | 238 const int offset = EntryFrameConstants::kCallerFPOffset; |
230 Address fp = Memory::Address_at(this->fp() + offset); | 239 Address fp = Memory::Address_at(this->fp() + offset); |
231 return ExitFrame::GetStateForFramePointer(fp, state); | 240 return ExitFrame::GetStateForFramePointer(fp, state); |
232 } | 241 } |
233 | 242 |
234 | 243 |
235 Code* EntryConstructFrame::FindCode() const { | 244 Code* EntryConstructFrame::code() const { |
236 return Heap::js_construct_entry_code(); | 245 return Heap::js_construct_entry_code(); |
237 } | 246 } |
238 | 247 |
239 | 248 |
240 Code* ExitFrame::FindCode() const { | 249 Code* ExitFrame::code() const { |
241 return Heap::c_entry_code(); | 250 return Heap::c_entry_code(); |
242 } | 251 } |
243 | 252 |
244 | 253 |
245 StackFrame::Type ExitFrame::GetCallerState(State* state) const { | 254 StackFrame::Type ExitFrame::GetCallerState(State* state) const { |
246 // Setup the caller state. | 255 // Setup the caller state. |
247 state->sp = pp(); | 256 state->sp = pp(); |
248 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); | 257 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); |
249 state->pc_address | 258 state->pc_address |
250 = reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset); | 259 = reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset); |
251 return ComputeType(state); | 260 return ComputeType(state); |
252 } | 261 } |
253 | 262 |
254 | 263 |
255 Address ExitFrame::GetCallerStackPointer() const { | 264 Address ExitFrame::GetCallerStackPointer() const { |
256 return fp() + ExitFrameConstants::kPPDisplacement; | 265 return fp() + ExitFrameConstants::kPPDisplacement; |
257 } | 266 } |
258 | 267 |
259 | 268 |
260 Code* ExitDebugFrame::FindCode() const { | 269 Code* ExitDebugFrame::code() const { |
261 return Heap::c_entry_debug_break_code(); | 270 return Heap::c_entry_debug_break_code(); |
262 } | 271 } |
263 | 272 |
264 | 273 |
265 Address StandardFrame::GetExpressionAddress(int n) const { | 274 Address StandardFrame::GetExpressionAddress(int n) const { |
266 const int offset = StandardFrameConstants::kExpressionsOffset; | 275 const int offset = StandardFrameConstants::kExpressionsOffset; |
267 return fp() + offset - n * kPointerSize; | 276 return fp() + offset - n * kPointerSize; |
268 } | 277 } |
269 | 278 |
270 | 279 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 bool JavaScriptFrame::IsConstructor() const { | 322 bool JavaScriptFrame::IsConstructor() const { |
314 Address fp = caller_fp(); | 323 Address fp = caller_fp(); |
315 if (has_adapted_arguments()) { | 324 if (has_adapted_arguments()) { |
316 // Skip the arguments adaptor frame and look at the real caller. | 325 // Skip the arguments adaptor frame and look at the real caller. |
317 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); | 326 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); |
318 } | 327 } |
319 return IsConstructFrame(fp); | 328 return IsConstructFrame(fp); |
320 } | 329 } |
321 | 330 |
322 | 331 |
323 Code* ArgumentsAdaptorFrame::FindCode() const { | 332 Code* JavaScriptFrame::code() const { |
| 333 JSFunction* function = JSFunction::cast(this->function()); |
| 334 return function->shared()->code(); |
| 335 } |
| 336 |
| 337 |
| 338 Code* ArgumentsAdaptorFrame::code() const { |
324 return Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline); | 339 return Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline); |
325 } | 340 } |
326 | 341 |
327 | 342 |
328 Code* InternalFrame::FindCode() const { | 343 Code* InternalFrame::code() const { |
329 const int offset = InternalFrameConstants::kCodeOffset; | 344 const int offset = InternalFrameConstants::kCodeOffset; |
330 Object* code = Memory::Object_at(fp() + offset); | 345 Object* code = Memory::Object_at(fp() + offset); |
331 if (code == NULL) { | |
332 // The code object isn't set; find it and set it. | |
333 code = Heap::FindCodeObject(pc()); | |
334 ASSERT(!code->IsFailure()); | |
335 Memory::Object_at(fp() + offset) = code; | |
336 } | |
337 ASSERT(code != NULL); | 346 ASSERT(code != NULL); |
338 return Code::cast(code); | 347 return Code::cast(code); |
339 } | 348 } |
340 | 349 |
341 | 350 |
342 void StackFrame::PrintIndex(StringStream* accumulator, | 351 void StackFrame::PrintIndex(StringStream* accumulator, |
343 PrintMode mode, | 352 PrintMode mode, |
344 int index) { | 353 int index) { |
345 accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index); | 354 accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index); |
346 } | 355 } |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 reg_code[i++] = r; | 589 reg_code[i++] = r; |
581 | 590 |
582 ASSERT(i == kNumJSCallerSaved); | 591 ASSERT(i == kNumJSCallerSaved); |
583 } | 592 } |
584 ASSERT(0 <= n && n < kNumJSCallerSaved); | 593 ASSERT(0 <= n && n < kNumJSCallerSaved); |
585 return reg_code[n]; | 594 return reg_code[n]; |
586 } | 595 } |
587 | 596 |
588 | 597 |
589 } } // namespace v8::internal | 598 } } // namespace v8::internal |
OLD | NEW |