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

Side by Side Diff: src/isolate.cc

Issue 2274823002: Add flags to FrameArray (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@frame-array
Patch Set: Rebase Created 4 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
« no previous file with comments | « no previous file | src/messages.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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/isolate.h" 5 #include "src/isolate.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include <fstream> // NOLINT(readability/streams) 9 #include <fstream> // NOLINT(readability/streams)
10 #include <sstream> 10 #include <sstream>
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 break; 339 break;
340 case SKIP_UNTIL_SEEN: 340 case SKIP_UNTIL_SEEN:
341 DCHECK(caller_->IsJSFunction()); 341 DCHECK(caller_->IsJSFunction());
342 skip_next_frame_ = true; 342 skip_next_frame_ = true;
343 break; 343 break;
344 case SKIP_NONE: 344 case SKIP_NONE:
345 skip_next_frame_ = false; 345 skip_next_frame_ = false;
346 break; 346 break;
347 } 347 }
348 encountered_strict_function_ = false; 348 encountered_strict_function_ = false;
349 sloppy_frames_ = 0;
350 } 349 }
351 350
351 // Poison stack frames below the first strict mode frame.
352 // The stack trace API should not expose receivers and function 352 // The stack trace API should not expose receivers and function
353 // objects on frames deeper than the top-most one with a strict mode 353 // objects on frames deeper than the top-most one with a strict mode
354 // function. The number of sloppy frames is stored as first element in 354 // function.
355 // the result array. 355 bool IsStrictFrame(JSFunction* fun) {
356 void CountSloppyFrames(JSFunction* fun) {
357 if (!encountered_strict_function_) { 356 if (!encountered_strict_function_) {
358 if (is_strict(fun->shared()->language_mode())) { 357 encountered_strict_function_ = is_strict(fun->shared()->language_mode());
359 encountered_strict_function_ = true;
360 } else {
361 sloppy_frames_++;
362 }
363 } 358 }
359 return encountered_strict_function_;
364 } 360 }
365 361
366 // Determines whether the given stack frame should be displayed in a stack 362 // Determines whether the given stack frame should be displayed in a stack
367 // trace. 363 // trace.
368 bool IsVisibleInStackTrace(JSFunction* fun) { 364 bool IsVisibleInStackTrace(JSFunction* fun) {
369 return ShouldIncludeFrame(fun) && IsNotInNativeScript(fun) && 365 return ShouldIncludeFrame(fun) && IsNotInNativeScript(fun) &&
370 IsInSameSecurityContext(fun); 366 IsInSameSecurityContext(fun);
371 } 367 }
372 368
373 int sloppy_frames() const { return sloppy_frames_; }
374
375 private: 369 private:
376 // This mechanism excludes a number of uninteresting frames from the stack 370 // This mechanism excludes a number of uninteresting frames from the stack
377 // trace. This can be be the first frame (which will be a builtin-exit frame 371 // trace. This can be be the first frame (which will be a builtin-exit frame
378 // for the error constructor builtin) or every frame until encountering a 372 // for the error constructor builtin) or every frame until encountering a
379 // user-specified function. 373 // user-specified function.
380 bool ShouldIncludeFrame(JSFunction* fun) { 374 bool ShouldIncludeFrame(JSFunction* fun) {
381 switch (mode_) { 375 switch (mode_) {
382 case SKIP_NONE: 376 case SKIP_NONE:
383 return true; 377 return true;
384 case SKIP_FIRST: 378 case SKIP_FIRST:
(...skipping 25 matching lines...) Expand all
410 bool IsInSameSecurityContext(JSFunction* fun) { 404 bool IsInSameSecurityContext(JSFunction* fun) {
411 return isolate_->context()->HasSameSecurityTokenAs(fun->context()); 405 return isolate_->context()->HasSameSecurityTokenAs(fun->context());
412 } 406 }
413 407
414 Isolate* isolate_; 408 Isolate* isolate_;
415 409
416 const FrameSkipMode mode_; 410 const FrameSkipMode mode_;
417 const Handle<Object> caller_; 411 const Handle<Object> caller_;
418 bool skip_next_frame_; 412 bool skip_next_frame_;
419 413
420 int sloppy_frames_;
421 bool encountered_strict_function_; 414 bool encountered_strict_function_;
422 }; 415 };
423 416
424 // TODO(jgruber): Fix all cases in which frames give us a hole value (e.g. the 417 // TODO(jgruber): Fix all cases in which frames give us a hole value (e.g. the
425 // receiver in RegExp constructor frames. 418 // receiver in RegExp constructor frames.
426 Handle<Object> TheHoleToUndefined(Isolate* isolate, Handle<Object> in) { 419 Handle<Object> TheHoleToUndefined(Isolate* isolate, Handle<Object> in) {
427 return (in->IsTheHole(isolate)) 420 return (in->IsTheHole(isolate))
428 ? Handle<Object>::cast(isolate->factory()->undefined_value()) 421 ? Handle<Object>::cast(isolate->factory()->undefined_value())
429 : in; 422 : in;
430 } 423 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame); 461 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
469 // Set initial size to the maximum inlining level + 1 for the outermost 462 // Set initial size to the maximum inlining level + 1 for the outermost
470 // function. 463 // function.
471 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); 464 List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
472 js_frame->Summarize(&frames); 465 js_frame->Summarize(&frames);
473 for (int i = frames.length() - 1; i >= 0; i--) { 466 for (int i = frames.length() - 1; i >= 0; i--) {
474 Handle<JSFunction> fun = frames[i].function(); 467 Handle<JSFunction> fun = frames[i].function();
475 468
476 // Filter out internal frames that we do not want to show. 469 // Filter out internal frames that we do not want to show.
477 if (!helper.IsVisibleInStackTrace(*fun)) continue; 470 if (!helper.IsVisibleInStackTrace(*fun)) continue;
478 helper.CountSloppyFrames(*fun);
479 471
480 Handle<Object> recv = frames[i].receiver(); 472 Handle<Object> recv = frames[i].receiver();
481 Handle<AbstractCode> abstract_code = frames[i].abstract_code(); 473 Handle<AbstractCode> abstract_code = frames[i].abstract_code();
474 const int offset = frames[i].code_offset();
475
476 bool force_constructor = false;
482 if (frame->type() == StackFrame::BUILTIN) { 477 if (frame->type() == StackFrame::BUILTIN) {
483 // Help CallSite::IsConstructor correctly detect hand-written 478 // Help CallSite::IsConstructor correctly detect hand-written
484 // construct stubs. 479 // construct stubs.
485 Code* code = Code::cast(*abstract_code); 480 if (Code::cast(*abstract_code)->is_construct_stub()) {
486 if (code->is_construct_stub()) { 481 force_constructor = true;
487 recv = handle(heap()->call_site_constructor_symbol(), this);
488 } 482 }
489 } 483 }
490 const int offset = frames[i].code_offset();
491 484
492 elements = FrameArray::AppendJSFrame(elements, 485 int flags = 0;
493 TheHoleToUndefined(this, recv), 486 if (helper.IsStrictFrame(*fun)) flags |= FrameArray::kIsStrict;
494 fun, abstract_code, offset); 487 if (force_constructor) flags |= FrameArray::kForceConstructor;
488
489 elements = FrameArray::AppendJSFrame(
490 elements, TheHoleToUndefined(this, recv), fun, abstract_code,
491 offset, flags);
495 } 492 }
496 } break; 493 } break;
497 494
498 case StackFrame::BUILTIN_EXIT: { 495 case StackFrame::BUILTIN_EXIT: {
499 BuiltinExitFrame* exit_frame = BuiltinExitFrame::cast(frame); 496 BuiltinExitFrame* exit_frame = BuiltinExitFrame::cast(frame);
500 Handle<JSFunction> fun = handle(exit_frame->function(), this); 497 Handle<JSFunction> fun = handle(exit_frame->function(), this);
501 498
502 // Filter out internal frames that we do not want to show. 499 // Filter out internal frames that we do not want to show.
503 if (!helper.IsVisibleInStackTrace(*fun)) continue; 500 if (!helper.IsVisibleInStackTrace(*fun)) continue;
504 helper.CountSloppyFrames(*fun);
505 501
506 Handle<Code> code = handle(exit_frame->LookupCode(), this); 502 Handle<Object> recv(exit_frame->receiver(), this);
503 Handle<Code> code(exit_frame->LookupCode(), this);
507 int offset = 504 int offset =
508 static_cast<int>(exit_frame->pc() - code->instruction_start()); 505 static_cast<int>(exit_frame->pc() - code->instruction_start());
509 506
510 // In order to help CallSite::IsConstructor detect builtin constructors, 507 int flags = 0;
511 // we reuse the receiver field to pass along a special symbol. 508 if (helper.IsStrictFrame(*fun)) flags |= FrameArray::kIsStrict;
512 Handle<Object> recv; 509 if (exit_frame->IsConstructor()) flags |= FrameArray::kForceConstructor;
513 if (exit_frame->IsConstructor()) {
514 recv = factory()->call_site_constructor_symbol();
515 } else {
516 recv = handle(exit_frame->receiver(), this);
517 }
518 510
519 elements = FrameArray::AppendJSFrame( 511 elements = FrameArray::AppendJSFrame(elements, recv, fun,
520 elements, recv, fun, Handle<AbstractCode>::cast(code), offset); 512 Handle<AbstractCode>::cast(code),
513 offset, flags);
521 } break; 514 } break;
522 515
523 case StackFrame::WASM: { 516 case StackFrame::WASM: {
524 WasmFrame* wasm_frame = WasmFrame::cast(frame); 517 WasmFrame* wasm_frame = WasmFrame::cast(frame);
525 Handle<Object> wasm_object = handle(wasm_frame->wasm_obj(), this); 518 Handle<Object> wasm_object(wasm_frame->wasm_obj(), this);
526 const int wasm_function_index = wasm_frame->function_index(); 519 const int wasm_function_index = wasm_frame->function_index();
527 Code* code = wasm_frame->unchecked_code(); 520 Code* code = wasm_frame->unchecked_code();
528 Handle<AbstractCode> abstract_code = 521 Handle<AbstractCode> abstract_code(AbstractCode::cast(code), this);
529 Handle<AbstractCode>(AbstractCode::cast(code), this);
530 const int offset = 522 const int offset =
531 static_cast<int>(wasm_frame->pc() - code->instruction_start()); 523 static_cast<int>(wasm_frame->pc() - code->instruction_start());
532 524
533 // TODO(wasm): The wasm object returned by the WasmFrame should always 525 // TODO(wasm): The wasm object returned by the WasmFrame should always
534 // be a wasm object. 526 // be a wasm object.
535 DCHECK(wasm::IsWasmObject(*wasm_object) || 527 DCHECK(wasm::IsWasmObject(*wasm_object) ||
536 wasm_object->IsUndefined(this)); 528 wasm_object->IsUndefined(this));
537 529
538 elements = FrameArray::AppendWasmFrame( 530 elements = FrameArray::AppendWasmFrame(
539 elements, wasm_object, wasm_function_index, abstract_code, offset); 531 elements, wasm_object, wasm_function_index, abstract_code, offset,
532 FrameArray::kIsWasmFrame);
540 } break; 533 } break;
541 534
542 default: 535 default:
543 break; 536 break;
544 } 537 }
545 } 538 }
546 539
547 elements->SetSloppyFrameCount(helper.sloppy_frames());
548 elements->ShrinkToFit(); 540 elements->ShrinkToFit();
549 541
550 // TODO(yangguo): Queue this structured stack trace for preprocessing on GC. 542 // TODO(yangguo): Queue this structured stack trace for preprocessing on GC.
551 return factory()->NewJSArrayWithElements(elements); 543 return factory()->NewJSArrayWithElements(elements);
552 } 544 }
553 545
554 MaybeHandle<JSReceiver> Isolate::CaptureAndSetDetailedStackTrace( 546 MaybeHandle<JSReceiver> Isolate::CaptureAndSetDetailedStackTrace(
555 Handle<JSReceiver> error_object) { 547 Handle<JSReceiver> error_object) {
556 if (capture_stack_trace_for_uncaught_exceptions_) { 548 if (capture_stack_trace_for_uncaught_exceptions_) {
557 // Capture stack trace for a detailed exception message. 549 // Capture stack trace for a detailed exception message.
(...skipping 2625 matching lines...) Expand 10 before | Expand all | Expand 10 after
3183 // Then check whether this scope intercepts. 3175 // Then check whether this scope intercepts.
3184 if ((flag & intercept_mask_)) { 3176 if ((flag & intercept_mask_)) {
3185 intercepted_flags_ |= flag; 3177 intercepted_flags_ |= flag;
3186 return true; 3178 return true;
3187 } 3179 }
3188 return false; 3180 return false;
3189 } 3181 }
3190 3182
3191 } // namespace internal 3183 } // namespace internal
3192 } // namespace v8 3184 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/messages.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698