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

Side by Side Diff: src/frames.cc

Issue 142813003: A64: Synchronize with r15358. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 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 | « src/frames.h ('k') | src/frames-inl.h » ('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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 private: 81 private:
82 const Address limit_; 82 const Address limit_;
83 StackHandler* handler_; 83 StackHandler* handler_;
84 }; 84 };
85 85
86 86
87 // ------------------------------------------------------------------------- 87 // -------------------------------------------------------------------------
88 88
89 89
90 #define INITIALIZE_SINGLETON(type, field) field##_(this), 90 #define INITIALIZE_SINGLETON(type, field) field##_(this),
91 StackFrameIterator::StackFrameIterator(Isolate* isolate) 91 StackFrameIteratorBase::StackFrameIteratorBase(Isolate* isolate,
92 bool can_access_heap_objects)
92 : isolate_(isolate), 93 : isolate_(isolate),
93 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) 94 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
94 frame_(NULL), handler_(NULL), 95 frame_(NULL), handler_(NULL),
95 thread_(isolate_->thread_local_top()), 96 can_access_heap_objects_(can_access_heap_objects) {
96 fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) {
97 Reset();
98 } 97 }
99 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
100 : isolate_(isolate),
101 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
102 frame_(NULL), handler_(NULL), thread_(t),
103 fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) {
104 Reset();
105 }
106 StackFrameIterator::StackFrameIterator(Isolate* isolate,
107 bool use_top, Address fp, Address sp)
108 : isolate_(isolate),
109 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
110 frame_(NULL), handler_(NULL),
111 thread_(use_top ? isolate_->thread_local_top() : NULL),
112 fp_(use_top ? NULL : fp), sp_(sp),
113 advance_(use_top ? &StackFrameIterator::AdvanceWithHandler :
114 &StackFrameIterator::AdvanceWithoutHandler) {
115 if (use_top || fp != NULL) {
116 Reset();
117 }
118 }
119
120 #undef INITIALIZE_SINGLETON 98 #undef INITIALIZE_SINGLETON
121 99
122 100
123 void StackFrameIterator::AdvanceWithHandler() { 101 StackFrameIterator::StackFrameIterator(Isolate* isolate)
102 : StackFrameIteratorBase(isolate, true) {
103 Reset(isolate->thread_local_top());
104 }
105
106
107 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
108 : StackFrameIteratorBase(isolate, true) {
109 Reset(t);
110 }
111
112
113 void StackFrameIterator::Advance() {
124 ASSERT(!done()); 114 ASSERT(!done());
125 // Compute the state of the calling frame before restoring 115 // Compute the state of the calling frame before restoring
126 // callee-saved registers and unwinding handlers. This allows the 116 // callee-saved registers and unwinding handlers. This allows the
127 // frame code that computes the caller state to access the top 117 // frame code that computes the caller state to access the top
128 // handler and the value of any callee-saved register if needed. 118 // handler and the value of any callee-saved register if needed.
129 StackFrame::State state; 119 StackFrame::State state;
130 StackFrame::Type type = frame_->GetCallerState(&state); 120 StackFrame::Type type = frame_->GetCallerState(&state);
131 121
132 // Unwind handlers corresponding to the current frame. 122 // Unwind handlers corresponding to the current frame.
133 StackHandlerIterator it(frame_, handler_); 123 StackHandlerIterator it(frame_, handler_);
134 while (!it.done()) it.Advance(); 124 while (!it.done()) it.Advance();
135 handler_ = it.handler(); 125 handler_ = it.handler();
136 126
137 // Advance to the calling frame. 127 // Advance to the calling frame.
138 frame_ = SingletonFor(type, &state); 128 frame_ = SingletonFor(type, &state);
139 129
140 // When we're done iterating over the stack frames, the handler 130 // When we're done iterating over the stack frames, the handler
141 // chain must have been completely unwound. 131 // chain must have been completely unwound.
142 ASSERT(!done() || handler_ == NULL); 132 ASSERT(!done() || handler_ == NULL);
143 } 133 }
144 134
145 135
146 void StackFrameIterator::AdvanceWithoutHandler() { 136 void StackFrameIterator::Reset(ThreadLocalTop* top) {
147 // A simpler version of Advance which doesn't care about handler.
148 ASSERT(!done());
149 StackFrame::State state; 137 StackFrame::State state;
150 StackFrame::Type type = frame_->GetCallerState(&state); 138 StackFrame::Type type = ExitFrame::GetStateForFramePointer(
151 frame_ = SingletonFor(type, &state); 139 Isolate::c_entry_fp(top), &state);
152 } 140 handler_ = StackHandler::FromAddress(Isolate::handler(top));
153
154
155 void StackFrameIterator::Reset() {
156 StackFrame::State state;
157 StackFrame::Type type;
158 if (thread_ != NULL) {
159 type = ExitFrame::GetStateForFramePointer(
160 Isolate::c_entry_fp(thread_), &state);
161 handler_ = StackHandler::FromAddress(
162 Isolate::handler(thread_));
163 } else {
164 ASSERT(fp_ != NULL);
165 state.fp = fp_;
166 state.sp = sp_;
167 state.pc_address = ResolveReturnAddressLocation(
168 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)));
169 type = StackFrame::ComputeType(isolate(), &state);
170 }
171 if (SingletonFor(type) == NULL) return; 141 if (SingletonFor(type) == NULL) return;
172 frame_ = SingletonFor(type, &state); 142 frame_ = SingletonFor(type, &state);
173 } 143 }
174 144
175 145
176 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type, 146 StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type,
177 StackFrame::State* state) { 147 StackFrame::State* state) {
178 if (type == StackFrame::NONE) return NULL; 148 if (type == StackFrame::NONE) return NULL;
179 StackFrame* result = SingletonFor(type); 149 StackFrame* result = SingletonFor(type);
180 ASSERT(result != NULL); 150 ASSERT(result != NULL);
181 result->state_ = *state; 151 result->state_ = *state;
182 return result; 152 return result;
183 } 153 }
184 154
185 155
186 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type) { 156 StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type) {
187 #define FRAME_TYPE_CASE(type, field) \ 157 #define FRAME_TYPE_CASE(type, field) \
188 case StackFrame::type: result = &field##_; break; 158 case StackFrame::type: result = &field##_; break;
189 159
190 StackFrame* result = NULL; 160 StackFrame* result = NULL;
191 switch (type) { 161 switch (type) {
192 case StackFrame::NONE: return NULL; 162 case StackFrame::NONE: return NULL;
193 STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE) 163 STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
194 default: break; 164 default: break;
195 } 165 }
196 return result; 166 return result;
197 167
198 #undef FRAME_TYPE_CASE 168 #undef FRAME_TYPE_CASE
199 } 169 }
200 170
201 171
202 // ------------------------------------------------------------------------- 172 // -------------------------------------------------------------------------
203 173
204 174
175 JavaScriptFrameIterator::JavaScriptFrameIterator(
176 Isolate* isolate, StackFrame::Id id)
177 : iterator_(isolate) {
178 while (!done()) {
179 Advance();
180 if (frame()->id() == id) return;
181 }
182 }
183
184
185 void JavaScriptFrameIterator::Advance() {
186 do {
187 iterator_.Advance();
188 } while (!iterator_.done() && !iterator_.frame()->is_java_script());
189 }
190
191
192 void JavaScriptFrameIterator::AdvanceToArgumentsFrame() {
193 if (!frame()->has_adapted_arguments()) return;
194 iterator_.Advance();
195 ASSERT(iterator_.frame()->is_arguments_adaptor());
196 }
197
198
199 // -------------------------------------------------------------------------
200
201
205 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate) 202 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
206 : JavaScriptFrameIterator(isolate) { 203 : JavaScriptFrameIterator(isolate) {
207 if (!done() && !IsValidFrame()) Advance(); 204 if (!done() && !IsValidFrame()) Advance();
208 } 205 }
209 206
210 207
211 void StackTraceFrameIterator::Advance() { 208 void StackTraceFrameIterator::Advance() {
212 while (true) { 209 while (true) {
213 JavaScriptFrameIterator::Advance(); 210 JavaScriptFrameIterator::Advance();
214 if (done()) return; 211 if (done()) return;
215 if (IsValidFrame()) return; 212 if (IsValidFrame()) return;
216 } 213 }
217 } 214 }
218 215
219 bool StackTraceFrameIterator::IsValidFrame() { 216 bool StackTraceFrameIterator::IsValidFrame() {
220 if (!frame()->function()->IsJSFunction()) return false; 217 if (!frame()->function()->IsJSFunction()) return false;
221 Object* script = JSFunction::cast(frame()->function())->shared()->script(); 218 Object* script = JSFunction::cast(frame()->function())->shared()->script();
222 // Don't show functions from native scripts to user. 219 // Don't show functions from native scripts to user.
223 return (script->IsScript() && 220 return (script->IsScript() &&
224 Script::TYPE_NATIVE != Script::cast(script)->type()->value()); 221 Script::TYPE_NATIVE != Script::cast(script)->type()->value());
225 } 222 }
226 223
227 224
228 // ------------------------------------------------------------------------- 225 // -------------------------------------------------------------------------
229 226
230 227
231 bool SafeStackFrameIterator::ExitFrameValidator::IsValidFP(Address fp) {
232 if (!validator_.IsValid(fp)) return false;
233 Address sp = ExitFrame::ComputeStackPointer(fp);
234 if (!validator_.IsValid(sp)) return false;
235 StackFrame::State state;
236 ExitFrame::FillState(fp, sp, &state);
237 if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) {
238 return false;
239 }
240 return *state.pc_address != NULL;
241 }
242
243
244 SafeStackFrameIterator::ActiveCountMaintainer::ActiveCountMaintainer(
245 Isolate* isolate)
246 : isolate_(isolate) {
247 isolate_->set_safe_stack_iterator_counter(
248 isolate_->safe_stack_iterator_counter() + 1);
249 }
250
251
252 SafeStackFrameIterator::ActiveCountMaintainer::~ActiveCountMaintainer() {
253 isolate_->set_safe_stack_iterator_counter(
254 isolate_->safe_stack_iterator_counter() - 1);
255 }
256
257
258 SafeStackFrameIterator::SafeStackFrameIterator( 228 SafeStackFrameIterator::SafeStackFrameIterator(
259 Isolate* isolate, 229 Isolate* isolate,
260 Address fp, Address sp, Address low_bound, Address high_bound) : 230 Address fp, Address sp, Address low_bound, Address high_bound) :
261 maintainer_(isolate), 231 StackFrameIteratorBase(isolate, false),
262 stack_validator_(low_bound, high_bound), 232 low_bound_(low_bound), high_bound_(high_bound) {
263 is_valid_top_(IsValidTop(isolate, low_bound, high_bound)), 233 StackFrame::State state;
264 is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), 234 StackFrame::Type type;
265 is_working_iterator_(is_valid_top_ || is_valid_fp_), 235 ThreadLocalTop* top = isolate->thread_local_top();
266 iteration_done_(!is_working_iterator_), 236 if (IsValidTop(top)) {
267 iterator_(isolate, is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { 237 type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
268 } 238 } else if (IsValidStackAddress(fp)) {
239 ASSERT(fp != NULL);
240 state.fp = fp;
241 state.sp = sp;
242 state.pc_address = ResolveReturnAddressLocation(
243 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
244 type = StackFrame::ComputeType(this, &state);
245 } else {
246 return;
247 }
248 if (SingletonFor(type) == NULL) return;
249 frame_ = SingletonFor(type, &state);
269 250
270 bool SafeStackFrameIterator::is_active(Isolate* isolate) { 251 if (!done()) Advance();
271 return isolate->safe_stack_iterator_counter() > 0;
272 } 252 }
273 253
274 254
275 bool SafeStackFrameIterator::IsValidTop(Isolate* isolate, 255 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const {
276 Address low_bound, Address high_bound) {
277 ThreadLocalTop* top = isolate->thread_local_top();
278 Address fp = Isolate::c_entry_fp(top); 256 Address fp = Isolate::c_entry_fp(top);
279 ExitFrameValidator validator(low_bound, high_bound); 257 if (!IsValidExitFrame(fp)) return false;
280 if (!validator.IsValidFP(fp)) return false; 258 // There should be at least one JS_ENTRY stack handler.
281 return Isolate::handler(top) != NULL; 259 return Isolate::handler(top) != NULL;
282 } 260 }
283 261
284 262
285 void SafeStackFrameIterator::Advance() { 263 void SafeStackFrameIterator::AdvanceOneFrame() {
286 ASSERT(is_working_iterator_);
287 ASSERT(!done()); 264 ASSERT(!done());
288 StackFrame* last_frame = iterator_.frame(); 265 StackFrame* last_frame = frame_;
289 Address last_sp = last_frame->sp(), last_fp = last_frame->fp(); 266 Address last_sp = last_frame->sp(), last_fp = last_frame->fp();
290 // Before advancing to the next stack frame, perform pointer validity tests 267 // Before advancing to the next stack frame, perform pointer validity tests.
291 iteration_done_ = !IsValidFrame(last_frame) || 268 if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) {
292 !CanIterateHandles(last_frame, iterator_.handler()) || 269 frame_ = NULL;
293 !IsValidCaller(last_frame); 270 return;
294 if (iteration_done_) return; 271 }
295 272
296 iterator_.Advance(); 273 // Advance to the previous frame.
297 if (iterator_.done()) return; 274 StackFrame::State state;
298 // Check that we have actually moved to the previous frame in the stack 275 StackFrame::Type type = frame_->GetCallerState(&state);
299 StackFrame* prev_frame = iterator_.frame(); 276 frame_ = SingletonFor(type, &state);
300 iteration_done_ = prev_frame->sp() < last_sp || prev_frame->fp() < last_fp; 277 if (frame_ == NULL) return;
278
279 // Check that we have actually moved to the previous frame in the stack.
280 if (frame_->sp() < last_sp || frame_->fp() < last_fp) {
281 frame_ = NULL;
282 }
301 } 283 }
302 284
303 285
304 bool SafeStackFrameIterator::CanIterateHandles(StackFrame* frame,
305 StackHandler* handler) {
306 // If StackIterator iterates over StackHandles, verify that
307 // StackHandlerIterator can be instantiated (see StackHandlerIterator
308 // constructor.)
309 return !is_valid_top_ || (frame->sp() <= handler->address());
310 }
311
312
313 bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const { 286 bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const {
314 return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp()); 287 return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp());
315 } 288 }
316 289
317 290
318 bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) { 291 bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) {
319 StackFrame::State state; 292 StackFrame::State state;
320 if (frame->is_entry() || frame->is_entry_construct()) { 293 if (frame->is_entry() || frame->is_entry_construct()) {
321 // See EntryFrame::GetCallerState. It computes the caller FP address 294 // See EntryFrame::GetCallerState. It computes the caller FP address
322 // and calls ExitFrame::GetStateForFramePointer on it. We need to be 295 // and calls ExitFrame::GetStateForFramePointer on it. We need to be
323 // sure that caller FP address is valid. 296 // sure that caller FP address is valid.
324 Address caller_fp = Memory::Address_at( 297 Address caller_fp = Memory::Address_at(
325 frame->fp() + EntryFrameConstants::kCallerFPOffset); 298 frame->fp() + EntryFrameConstants::kCallerFPOffset);
326 ExitFrameValidator validator(stack_validator_); 299 if (!IsValidExitFrame(caller_fp)) return false;
327 if (!validator.IsValidFP(caller_fp)) return false;
328 } else if (frame->is_arguments_adaptor()) { 300 } else if (frame->is_arguments_adaptor()) {
329 // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that 301 // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that
330 // the number of arguments is stored on stack as Smi. We need to check 302 // the number of arguments is stored on stack as Smi. We need to check
331 // that it really an Smi. 303 // that it really an Smi.
332 Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)-> 304 Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)->
333 GetExpression(0); 305 GetExpression(0);
334 if (!number_of_args->IsSmi()) { 306 if (!number_of_args->IsSmi()) {
335 return false; 307 return false;
336 } 308 }
337 } 309 }
338 frame->ComputeCallerState(&state); 310 frame->ComputeCallerState(&state);
339 return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) && 311 return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) &&
340 iterator_.SingletonFor(frame->GetCallerState(&state)) != NULL; 312 SingletonFor(frame->GetCallerState(&state)) != NULL;
341 } 313 }
342 314
343 315
344 void SafeStackFrameIterator::Reset() { 316 bool SafeStackFrameIterator::IsValidExitFrame(Address fp) const {
345 if (is_working_iterator_) { 317 if (!IsValidStackAddress(fp)) return false;
346 iterator_.Reset(); 318 Address sp = ExitFrame::ComputeStackPointer(fp);
347 iteration_done_ = false; 319 if (!IsValidStackAddress(sp)) return false;
320 StackFrame::State state;
321 ExitFrame::FillState(fp, sp, &state);
322 if (!IsValidStackAddress(reinterpret_cast<Address>(state.pc_address))) {
323 return false;
324 }
325 return *state.pc_address != NULL;
326 }
327
328
329 void SafeStackFrameIterator::Advance() {
330 while (true) {
331 AdvanceOneFrame();
332 if (done()) return;
333 if (frame_->is_java_script()) return;
348 } 334 }
349 } 335 }
350 336
351 337
352 // ------------------------------------------------------------------------- 338 // -------------------------------------------------------------------------
353 339
354 340
355 SafeStackTraceFrameIterator::SafeStackTraceFrameIterator(
356 Isolate* isolate,
357 Address fp, Address sp, Address low_bound, Address high_bound) :
358 SafeJavaScriptFrameIterator(isolate, fp, sp, low_bound, high_bound) {
359 if (!done() && !frame()->is_java_script()) Advance();
360 }
361
362
363 void SafeStackTraceFrameIterator::Advance() {
364 while (true) {
365 SafeJavaScriptFrameIterator::Advance();
366 if (done()) return;
367 if (frame()->is_java_script()) return;
368 }
369 }
370
371
372 Code* StackFrame::GetSafepointData(Isolate* isolate, 341 Code* StackFrame::GetSafepointData(Isolate* isolate,
373 Address inner_pointer, 342 Address inner_pointer,
374 SafepointEntry* safepoint_entry, 343 SafepointEntry* safepoint_entry,
375 unsigned* stack_slots) { 344 unsigned* stack_slots) {
376 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry = 345 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry =
377 isolate->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer); 346 isolate->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer);
378 if (!entry->safepoint_entry.is_valid()) { 347 if (!entry->safepoint_entry.is_valid()) {
379 entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer); 348 entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer);
380 ASSERT(entry->safepoint_entry.is_valid()); 349 ASSERT(entry->safepoint_entry.is_valid());
381 } else { 350 } else {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 } 387 }
419 388
420 389
421 void StackFrame::SetReturnAddressLocationResolver( 390 void StackFrame::SetReturnAddressLocationResolver(
422 ReturnAddressLocationResolver resolver) { 391 ReturnAddressLocationResolver resolver) {
423 ASSERT(return_address_location_resolver == NULL); 392 ASSERT(return_address_location_resolver == NULL);
424 return_address_location_resolver = resolver; 393 return_address_location_resolver = resolver;
425 } 394 }
426 395
427 396
428 StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) { 397 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
398 State* state) {
429 ASSERT(state->fp != NULL); 399 ASSERT(state->fp != NULL);
430 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { 400 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
431 return ARGUMENTS_ADAPTOR; 401 return ARGUMENTS_ADAPTOR;
432 } 402 }
433 // The marker and function offsets overlap. If the marker isn't a 403 // The marker and function offsets overlap. If the marker isn't a
434 // smi then the frame is a JavaScript frame -- and the marker is 404 // smi then the frame is a JavaScript frame -- and the marker is
435 // really the function. 405 // really the function.
436 const int offset = StandardFrameConstants::kMarkerOffset; 406 const int offset = StandardFrameConstants::kMarkerOffset;
437 Object* marker = Memory::Object_at(state->fp + offset); 407 Object* marker = Memory::Object_at(state->fp + offset);
438 if (!marker->IsSmi()) { 408 if (!marker->IsSmi()) {
439 // If we're using a "safe" stack iterator, we treat optimized 409 // If we're using a "safe" stack iterator, we treat optimized
440 // frames as normal JavaScript frames to avoid having to look 410 // frames as normal JavaScript frames to avoid having to look
441 // into the heap to determine the state. This is safe as long 411 // into the heap to determine the state. This is safe as long
442 // as nobody tries to GC... 412 // as nobody tries to GC...
443 if (SafeStackFrameIterator::is_active(isolate)) return JAVA_SCRIPT; 413 if (!iterator->can_access_heap_objects_) return JAVA_SCRIPT;
444 Code::Kind kind = GetContainingCode(isolate, *(state->pc_address))->kind(); 414 Code::Kind kind = GetContainingCode(iterator->isolate(),
415 *(state->pc_address))->kind();
445 ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION); 416 ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION);
446 return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT; 417 return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT;
447 } 418 }
448 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); 419 return static_cast<StackFrame::Type>(Smi::cast(marker)->value());
449 } 420 }
450 421
451 422
423 #ifdef DEBUG
424 bool StackFrame::can_access_heap_objects() const {
425 return iterator_->can_access_heap_objects_;
426 }
427 #endif
428
452 429
453 StackFrame::Type StackFrame::GetCallerState(State* state) const { 430 StackFrame::Type StackFrame::GetCallerState(State* state) const {
454 ComputeCallerState(state); 431 ComputeCallerState(state);
455 return ComputeType(isolate(), state); 432 return ComputeType(iterator_, state);
456 } 433 }
457 434
458 435
459 Address StackFrame::UnpaddedFP() const { 436 Address StackFrame::UnpaddedFP() const {
460 #if defined(V8_TARGET_ARCH_IA32) 437 #if defined(V8_TARGET_ARCH_IA32)
461 if (!is_optimized()) return fp(); 438 if (!is_optimized()) return fp();
462 int32_t alignment_state = Memory::int32_at( 439 int32_t alignment_state = Memory::int32_at(
463 fp() + JavaScriptFrameConstants::kDynamicAlignmentStateOffset); 440 fp() + JavaScriptFrameConstants::kDynamicAlignmentStateOffset);
464 441
465 return (alignment_state == kAlignmentPaddingPushed) ? 442 return (alignment_state == kAlignmentPaddingPushed) ?
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 515
539 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { 516 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) {
540 if (fp == 0) return NONE; 517 if (fp == 0) return NONE;
541 Address sp = ComputeStackPointer(fp); 518 Address sp = ComputeStackPointer(fp);
542 FillState(fp, sp, state); 519 FillState(fp, sp, state);
543 ASSERT(*state->pc_address != NULL); 520 ASSERT(*state->pc_address != NULL);
544 return EXIT; 521 return EXIT;
545 } 522 }
546 523
547 524
525 Address ExitFrame::ComputeStackPointer(Address fp) {
526 return Memory::Address_at(fp + ExitFrameConstants::kSPOffset);
527 }
528
529
548 void ExitFrame::FillState(Address fp, Address sp, State* state) { 530 void ExitFrame::FillState(Address fp, Address sp, State* state) {
549 state->sp = sp; 531 state->sp = sp;
550 state->fp = fp; 532 state->fp = fp;
551 state->pc_address = ResolveReturnAddressLocation( 533 state->pc_address = ResolveReturnAddressLocation(
552 reinterpret_cast<Address*>(sp - 1 * kPointerSize)); 534 reinterpret_cast<Address*>(sp - 1 * kPointerSize));
553 } 535 }
554 536
555 537
556 Address StandardFrame::GetExpressionAddress(int n) const { 538 Address StandardFrame::GetExpressionAddress(int n) const {
557 const int offset = StandardFrameConstants::kExpressionsOffset; 539 const int offset = StandardFrameConstants::kExpressionsOffset;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { 582 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
601 if (it.handler()->includes(address)) return true; 583 if (it.handler()->includes(address)) return true;
602 } 584 }
603 return false; 585 return false;
604 } 586 }
605 587
606 588
607 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const { 589 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
608 // Make sure that we're not doing "safe" stack frame iteration. We cannot 590 // Make sure that we're not doing "safe" stack frame iteration. We cannot
609 // possibly find pointers in optimized frames in that state. 591 // possibly find pointers in optimized frames in that state.
610 ASSERT(!SafeStackFrameIterator::is_active(isolate())); 592 ASSERT(can_access_heap_objects());
611 593
612 // Compute the safepoint information. 594 // Compute the safepoint information.
613 unsigned stack_slots = 0; 595 unsigned stack_slots = 0;
614 SafepointEntry safepoint_entry; 596 SafepointEntry safepoint_entry;
615 Code* code = StackFrame::GetSafepointData( 597 Code* code = StackFrame::GetSafepointData(
616 isolate(), pc(), &safepoint_entry, &stack_slots); 598 isolate(), pc(), &safepoint_entry, &stack_slots);
617 unsigned slot_space = stack_slots * kPointerSize; 599 unsigned slot_space = stack_slots * kPointerSize;
618 600
619 // Visit the outgoing parameters. 601 // Visit the outgoing parameters.
620 Object** parameters_base = &Memory::Object_at(sp()); 602 Object** parameters_base = &Memory::Object_at(sp());
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 if (has_adapted_arguments()) { 709 if (has_adapted_arguments()) {
728 return Smi::cast(GetExpression(caller_fp(), 0))->value(); 710 return Smi::cast(GetExpression(caller_fp(), 0))->value();
729 } else { 711 } else {
730 return GetNumberOfIncomingArguments(); 712 return GetNumberOfIncomingArguments();
731 } 713 }
732 } 714 }
733 715
734 716
735 Code* JavaScriptFrame::unchecked_code() const { 717 Code* JavaScriptFrame::unchecked_code() const {
736 JSFunction* function = JSFunction::cast(this->function()); 718 JSFunction* function = JSFunction::cast(this->function());
737 return function->unchecked_code(); 719 return function->code();
738 } 720 }
739 721
740 722
741 int JavaScriptFrame::GetNumberOfIncomingArguments() const { 723 int JavaScriptFrame::GetNumberOfIncomingArguments() const {
742 ASSERT(!SafeStackFrameIterator::is_active(isolate()) && 724 ASSERT(can_access_heap_objects() &&
743 isolate()->heap()->gc_state() == Heap::NOT_IN_GC); 725 isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
744 726
745 JSFunction* function = JSFunction::cast(this->function()); 727 JSFunction* function = JSFunction::cast(this->function());
746 return function->shared()->formal_parameter_count(); 728 return function->shared()->formal_parameter_count();
747 } 729 }
748 730
749 731
750 Address JavaScriptFrame::GetCallerStackPointer() const { 732 Address JavaScriptFrame::GetCallerStackPointer() const {
751 return fp() + StandardFrameConstants::kCallerSPOffset; 733 return fp() + StandardFrameConstants::kCallerSPOffset;
752 } 734 }
(...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after
1614 ZoneList<StackFrame*> list(10, zone); 1596 ZoneList<StackFrame*> list(10, zone);
1615 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { 1597 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
1616 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); 1598 StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
1617 list.Add(frame, zone); 1599 list.Add(frame, zone);
1618 } 1600 }
1619 return list.ToVector(); 1601 return list.ToVector();
1620 } 1602 }
1621 1603
1622 1604
1623 } } // namespace v8::internal 1605 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/frames.h ('k') | src/frames-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698