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

Side by Side Diff: src/isolate.cc

Issue 2230953002: Use a custom Struct for stack trace storage (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Tweaks Created 4 years, 4 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 | « src/isolate.h ('k') | src/messages.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 // 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 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 break; 349 break;
350 case SKIP_UNTIL_SEEN: 350 case SKIP_UNTIL_SEEN:
351 DCHECK(caller_->IsJSFunction()); 351 DCHECK(caller_->IsJSFunction());
352 skip_next_frame_ = true; 352 skip_next_frame_ = true;
353 break; 353 break;
354 case SKIP_NONE: 354 case SKIP_NONE:
355 skip_next_frame_ = false; 355 skip_next_frame_ = false;
356 break; 356 break;
357 } 357 }
358 encountered_strict_function_ = false; 358 encountered_strict_function_ = false;
359 sloppy_frames_ = 0;
360 } 359 }
361 360
362 // The stack trace API should not expose receivers and function 361 // The stack trace API should not expose receivers and function
363 // objects on frames deeper than the top-most one with a strict mode 362 // objects on frames deeper than the top-most one with a strict mode
364 // function. The number of sloppy frames is stored as first element in 363 // function.
365 // the result array. 364 bool IsStrictFrame(JSFunction* fun) {
366 void CountSloppyFrames(JSFunction* fun) {
367 if (!encountered_strict_function_) { 365 if (!encountered_strict_function_) {
368 if (is_strict(fun->shared()->language_mode())) { 366 encountered_strict_function_ = is_strict(fun->shared()->language_mode());
369 encountered_strict_function_ = true;
370 } else {
371 sloppy_frames_++;
372 }
373 } 367 }
368 return encountered_strict_function_;
374 } 369 }
375 370
376 // Determines whether the given stack frame should be displayed in a stack 371 // Determines whether the given stack frame should be displayed in a stack
377 // trace. 372 // trace.
378 bool IsVisibleInStackTrace(JSFunction* fun) { 373 bool IsVisibleInStackTrace(JSFunction* fun) {
379 return ShouldIncludeFrame(fun) && IsNotInNativeScript(fun) && 374 return ShouldIncludeFrame(fun) && IsNotInNativeScript(fun) &&
380 IsInSameSecurityContext(fun); 375 IsInSameSecurityContext(fun);
381 } 376 }
382 377
383 int sloppy_frames() const { return sloppy_frames_; }
384
385 private: 378 private:
386 // This mechanism excludes a number of uninteresting frames from the stack 379 // This mechanism excludes a number of uninteresting frames from the stack
387 // trace. This can be be the first frame (which will be a builtin-exit frame 380 // trace. This can be be the first frame (which will be a builtin-exit frame
388 // for the error constructor builtin) or every frame until encountering a 381 // for the error constructor builtin) or every frame until encountering a
389 // user-specified function. 382 // user-specified function.
390 bool ShouldIncludeFrame(JSFunction* fun) { 383 bool ShouldIncludeFrame(JSFunction* fun) {
391 switch (mode_) { 384 switch (mode_) {
392 case SKIP_NONE: 385 case SKIP_NONE:
393 return true; 386 return true;
394 case SKIP_FIRST: 387 case SKIP_FIRST:
(...skipping 25 matching lines...) Expand all
420 bool IsInSameSecurityContext(JSFunction* fun) { 413 bool IsInSameSecurityContext(JSFunction* fun) {
421 return isolate_->context()->HasSameSecurityTokenAs(fun->context()); 414 return isolate_->context()->HasSameSecurityTokenAs(fun->context());
422 } 415 }
423 416
424 Isolate* isolate_; 417 Isolate* isolate_;
425 418
426 const FrameSkipMode mode_; 419 const FrameSkipMode mode_;
427 const Handle<Object> caller_; 420 const Handle<Object> caller_;
428 bool skip_next_frame_; 421 bool skip_next_frame_;
429 422
430 int sloppy_frames_;
431 bool encountered_strict_function_; 423 bool encountered_strict_function_;
432 }; 424 };
433 425
434 namespace { 426 namespace {
435 427
436 // TODO(jgruber): Fix all cases in which frames give us a hole value (e.g. the 428 // TODO(jgruber): Fix all cases in which frames give us a hole value (e.g. the
437 // receiver in RegExp constructor frames. 429 // receiver in RegExp constructor frames.
438 Handle<Object> TheHoleToUndefined(Isolate* isolate, Handle<Object> in) { 430 Handle<Object> TheHoleToUndefined(Isolate* isolate, Handle<Object> in) {
439 return (in->IsTheHole(isolate)) 431 return (in->IsTheHole(isolate))
440 ? Handle<Object>::cast(isolate->factory()->undefined_value()) 432 ? Handle<Object>::cast(isolate->factory()->undefined_value())
441 : in; 433 : in;
442 } 434 }
435
436 bool GetStackTraceLimit(Isolate* isolate, int* result) {
437 Handle<JSObject> error = isolate->error_function();
438 Handle<String> stackTraceLimit =
439 isolate->factory()->InternalizeUtf8String("stackTraceLimit");
440 DCHECK(!stackTraceLimit.is_null());
441
442 Handle<Object> stack_trace_limit =
443 JSReceiver::GetDataProperty(error, stackTraceLimit);
444 if (!stack_trace_limit->IsNumber()) return false;
445
446 // Ensure that limit is not negative.
447 *result = Max(FastD2IChecked(stack_trace_limit->Number()), 0);
448 return true;
443 } 449 }
444 450
451 } // namespace
452
445 Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object, 453 Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object,
446 FrameSkipMode mode, 454 FrameSkipMode mode,
447 Handle<Object> caller) { 455 Handle<Object> caller) {
448 DisallowJavascriptExecution no_js(this); 456 DisallowJavascriptExecution no_js(this);
449 457
450 // Get stack trace limit. 458 int limit;
451 Handle<JSObject> error = error_function(); 459 if (!GetStackTraceLimit(this, &limit)) return factory()->undefined_value();
452 Handle<String> stackTraceLimit =
453 factory()->InternalizeUtf8String("stackTraceLimit");
454 DCHECK(!stackTraceLimit.is_null());
455 Handle<Object> stack_trace_limit =
456 JSReceiver::GetDataProperty(error, stackTraceLimit);
457 if (!stack_trace_limit->IsNumber()) return factory()->undefined_value();
458 int limit = FastD2IChecked(stack_trace_limit->Number());
459 limit = Max(limit, 0); // Ensure that limit is not negative.
460 460
461 int initial_size = Min(limit, 10); 461 using ESTF = EncodedStackTraceFrame;
462 Handle<FixedArray> elements = 462 int initial_size = Min(limit, 10) * ESTF::kElementsPerFrame;
463 factory()->NewFixedArrayWithHoles(initial_size * 4 + 1); 463 Handle<FixedArray> elements = factory()->NewFixedArrayWithHoles(initial_size);
464 464
465 int cursor = 0;
466 int frames_seen = 0;
465 StackTraceHelper helper(this, mode, caller); 467 StackTraceHelper helper(this, mode, caller);
466 468
467 // First element is reserved to store the number of sloppy frames.
468 int cursor = 1;
469 int frames_seen = 0;
470 for (StackFrameIterator iter(this); !iter.done() && frames_seen < limit; 469 for (StackFrameIterator iter(this); !iter.done() && frames_seen < limit;
471 iter.Advance()) { 470 iter.Advance()) {
472 StackFrame* frame = iter.frame(); 471 StackFrame* frame = iter.frame();
473 472
474 switch (frame->type()) { 473 switch (frame->type()) {
475 case StackFrame::JAVA_SCRIPT: 474 case StackFrame::JAVA_SCRIPT:
476 case StackFrame::OPTIMIZED: 475 case StackFrame::OPTIMIZED:
477 case StackFrame::INTERPRETED: 476 case StackFrame::INTERPRETED:
478 case StackFrame::BUILTIN: { 477 case StackFrame::BUILTIN: {
479 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame); 478 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
480 // Set initial size to the maximum inlining level + 1 for the outermost 479 // Set initial size to the maximum inlining level + 1 for the outermost
481 // function. 480 // function.
482 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); 481 List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
483 js_frame->Summarize(&frames); 482 js_frame->Summarize(&frames);
484 for (int i = frames.length() - 1; i >= 0; i--) { 483 for (int i = frames.length() - 1; i >= 0; i--) {
485 Handle<JSFunction> fun = frames[i].function(); 484 Handle<JSFunction> fun = frames[i].function();
486 485
487 // Filter out internal frames that we do not want to show. 486 // Filter out internal frames that we do not want to show.
488 if (!helper.IsVisibleInStackTrace(*fun)) continue; 487 if (!helper.IsVisibleInStackTrace(*fun)) continue;
489 helper.CountSloppyFrames(*fun);
490 488
491 Handle<Object> recv = frames[i].receiver(); 489 Handle<Object> recv = frames[i].receiver();
492 Handle<AbstractCode> abstract_code = frames[i].abstract_code(); 490 Handle<AbstractCode> abstract_code = frames[i].abstract_code();
491 const int offset = frames[i].code_offset();
492
493 bool force_constructor = false;
493 if (frame->type() == StackFrame::BUILTIN) { 494 if (frame->type() == StackFrame::BUILTIN) {
494 // Help CallSite::IsConstructor correctly detect hand-written 495 // Help CallSite::IsConstructor correctly detect hand-written
495 // construct stubs. 496 // construct stubs.
496 Code* code = Code::cast(*abstract_code); 497 if (Code::cast(*abstract_code)->is_construct_stub()) {
497 if (code->is_construct_stub()) { 498 force_constructor = true;
498 recv = handle(heap()->call_site_constructor_symbol(), this);
499 } 499 }
500 } 500 }
501 Handle<Smi> offset(Smi::FromInt(frames[i].code_offset()), this);
502 501
503 elements = MaybeGrow(this, elements, cursor, cursor + 4); 502 int flags = 0;
503 if (helper.IsStrictFrame(*fun)) flags |= StackTraceFrame::kIsStrict;
504 if (force_constructor) flags |= StackTraceFrame::kForceConstructor;
505
506 elements = MaybeGrow(this, elements, cursor,
507 cursor + ESTF::kElementsPerFrame);
504 elements->set(cursor++, *TheHoleToUndefined(this, recv)); 508 elements->set(cursor++, *TheHoleToUndefined(this, recv));
505 elements->set(cursor++, *fun); 509 elements->set(cursor++, *fun);
506 elements->set(cursor++, *abstract_code); 510 elements->set(cursor++, *abstract_code);
507 elements->set(cursor++, *offset); 511 elements->set(cursor++, Smi::FromInt(offset));
512 elements->set(cursor++, Smi::FromInt(flags));
508 frames_seen++; 513 frames_seen++;
509 } 514 }
510 } break; 515 } break;
511 516
512 case StackFrame::BUILTIN_EXIT: { 517 case StackFrame::BUILTIN_EXIT: {
513 BuiltinExitFrame* exit_frame = BuiltinExitFrame::cast(frame); 518 BuiltinExitFrame* exit_frame = BuiltinExitFrame::cast(frame);
514 Handle<JSFunction> fun = handle(exit_frame->function(), this); 519 Handle<JSFunction> fun = handle(exit_frame->function(), this);
515 520
516 // Filter out internal frames that we do not want to show. 521 // Filter out internal frames that we do not want to show.
517 if (!helper.IsVisibleInStackTrace(*fun)) continue; 522 if (!helper.IsVisibleInStackTrace(*fun)) continue;
518 helper.CountSloppyFrames(*fun);
519 523
524 Handle<Object> recv = handle(exit_frame->receiver(), this);
520 Handle<Code> code = handle(exit_frame->LookupCode(), this); 525 Handle<Code> code = handle(exit_frame->LookupCode(), this);
521 int offset = 526 const int offset =
522 static_cast<int>(exit_frame->pc() - code->instruction_start()); 527 static_cast<int>(exit_frame->pc() - code->instruction_start());
523 528
524 // In order to help CallSite::IsConstructor detect builtin constructors, 529 int flags = 0;
525 // we reuse the receiver field to pass along a special symbol. 530 if (helper.IsStrictFrame(*fun)) flags |= StackTraceFrame::kIsStrict;
526 Handle<Object> recv; 531 if (exit_frame->IsConstructor())
527 if (exit_frame->IsConstructor()) { 532 flags |= StackTraceFrame::kForceConstructor;
528 recv = factory()->call_site_constructor_symbol();
529 } else {
530 recv = handle(exit_frame->receiver(), this);
531 }
532 533
533 elements = MaybeGrow(this, elements, cursor, cursor + 4); 534 elements =
535 MaybeGrow(this, elements, cursor, cursor + ESTF::kElementsPerFrame);
534 elements->set(cursor++, *recv); 536 elements->set(cursor++, *recv);
535 elements->set(cursor++, *fun); 537 elements->set(cursor++, *fun);
536 elements->set(cursor++, *code); 538 elements->set(cursor++, *code);
537 elements->set(cursor++, Smi::FromInt(offset)); 539 elements->set(cursor++, Smi::FromInt(offset));
540 elements->set(cursor++, Smi::FromInt(flags));
538 frames_seen++; 541 frames_seen++;
539 } break; 542 } break;
540 543
541 case StackFrame::WASM: { 544 case StackFrame::WASM: {
542 WasmFrame* wasm_frame = WasmFrame::cast(frame); 545 WasmFrame* wasm_frame = WasmFrame::cast(frame);
543 Code* code = wasm_frame->unchecked_code(); 546 Code* code = wasm_frame->unchecked_code();
544 Handle<AbstractCode> abstract_code = 547 Handle<AbstractCode> abstract_code =
545 Handle<AbstractCode>(AbstractCode::cast(code), this); 548 Handle<AbstractCode>(AbstractCode::cast(code), this);
546 int offset = 549 const int offset =
547 static_cast<int>(wasm_frame->pc() - code->instruction_start()); 550 static_cast<int>(wasm_frame->pc() - code->instruction_start());
548 elements = MaybeGrow(this, elements, cursor, cursor + 4); 551
552 // TODO(wasm): The wasm object returned by the WasmFrame should always
553 // be a wasm object.
554 DCHECK(wasm::IsWasmObject(wasm_frame->wasm_obj()) ||
555 wasm_frame->wasm_obj()->IsUndefined(this));
556
557 elements =
558 MaybeGrow(this, elements, cursor, cursor + ESTF::kElementsPerFrame);
549 elements->set(cursor++, wasm_frame->wasm_obj()); 559 elements->set(cursor++, wasm_frame->wasm_obj());
550 elements->set(cursor++, Smi::FromInt(wasm_frame->function_index())); 560 elements->set(cursor++, Smi::FromInt(wasm_frame->function_index()));
551 elements->set(cursor++, *abstract_code); 561 elements->set(cursor++, *abstract_code);
552 elements->set(cursor++, Smi::FromInt(offset)); 562 elements->set(cursor++, Smi::FromInt(offset));
563 elements->set(cursor++, Smi::FromInt(StackTraceFrame::kIsWasmFrame));
553 frames_seen++; 564 frames_seen++;
554 } break; 565 } break;
555 566
556 default: 567 default:
557 break; 568 break;
558 } 569 }
559 } 570 }
560 elements->set(0, Smi::FromInt(helper.sloppy_frames())); 571
572 DCHECK_EQ(0, cursor % ESTF::kElementsPerFrame);
561 elements->Shrink(cursor); 573 elements->Shrink(cursor);
562 Handle<JSArray> result = factory()->NewJSArrayWithElements(elements); 574 Handle<JSArray> result = factory()->NewJSArrayWithElements(elements);
563 result->set_length(Smi::FromInt(cursor)); 575 result->set_length(Smi::FromInt(cursor));
576
564 // TODO(yangguo): Queue this structured stack trace for preprocessing on GC. 577 // TODO(yangguo): Queue this structured stack trace for preprocessing on GC.
565 return result; 578 return result;
566 } 579 }
567 580
568 MaybeHandle<JSReceiver> Isolate::CaptureAndSetDetailedStackTrace( 581 MaybeHandle<JSReceiver> Isolate::CaptureAndSetDetailedStackTrace(
569 Handle<JSReceiver> error_object) { 582 Handle<JSReceiver> error_object) {
570 if (capture_stack_trace_for_uncaught_exceptions_) { 583 if (capture_stack_trace_for_uncaught_exceptions_) {
571 // Capture stack trace for a detailed exception message. 584 // Capture stack trace for a detailed exception message.
572 Handle<Name> key = factory()->detailed_stack_trace_symbol(); 585 Handle<Name> key = factory()->detailed_stack_trace_symbol();
573 Handle<JSArray> stack_trace = CaptureCurrentStackTrace( 586 Handle<JSArray> stack_trace = CaptureCurrentStackTrace(
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 Handle<String> column_key_; 775 Handle<String> column_key_;
763 Handle<String> line_key_; 776 Handle<String> line_key_;
764 Handle<String> script_id_key_; 777 Handle<String> script_id_key_;
765 Handle<String> script_name_key_; 778 Handle<String> script_name_key_;
766 Handle<String> script_name_or_source_url_key_; 779 Handle<String> script_name_or_source_url_key_;
767 Handle<String> function_key_; 780 Handle<String> function_key_;
768 Handle<String> eval_key_; 781 Handle<String> eval_key_;
769 Handle<String> constructor_key_; 782 Handle<String> constructor_key_;
770 }; 783 };
771 784
772
773 int PositionFromStackTrace(Handle<FixedArray> elements, int index) {
774 DisallowHeapAllocation no_gc;
775 Object* maybe_code = elements->get(index + 2);
776 if (maybe_code->IsSmi()) {
777 return Smi::cast(maybe_code)->value();
778 } else {
779 AbstractCode* abstract_code = AbstractCode::cast(maybe_code);
780 int code_offset = Smi::cast(elements->get(index + 3))->value();
781 return abstract_code->SourcePosition(code_offset);
782 }
783 }
784
785 Handle<JSArray> Isolate::CaptureCurrentStackTrace( 785 Handle<JSArray> Isolate::CaptureCurrentStackTrace(
786 int frame_limit, StackTrace::StackTraceOptions options) { 786 int frame_limit, StackTrace::StackTraceOptions options) {
787 DisallowJavascriptExecution no_js(this); 787 DisallowJavascriptExecution no_js(this);
788 CaptureStackTraceHelper helper(this, options); 788 CaptureStackTraceHelper helper(this, options);
789 789
790 // Ensure no negative values. 790 // Ensure no negative values.
791 int limit = Max(frame_limit, 0); 791 int limit = Max(frame_limit, 0);
792 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); 792 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit);
793 Handle<FixedArray> stack_trace_elems( 793 Handle<FixedArray> stack_trace_elems(
794 FixedArray::cast(stack_trace->elements()), this); 794 FixedArray::cast(stack_trace->elements()), this);
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 1419
1420 Object* Isolate::PromoteScheduledException() { 1420 Object* Isolate::PromoteScheduledException() {
1421 Object* thrown = scheduled_exception(); 1421 Object* thrown = scheduled_exception();
1422 clear_scheduled_exception(); 1422 clear_scheduled_exception();
1423 // Re-throw the exception to avoid getting repeated error reporting. 1423 // Re-throw the exception to avoid getting repeated error reporting.
1424 return ReThrow(thrown); 1424 return ReThrow(thrown);
1425 } 1425 }
1426 1426
1427 1427
1428 void Isolate::PrintCurrentStackTrace(FILE* out) { 1428 void Isolate::PrintCurrentStackTrace(FILE* out) {
1429 StackTraceFrameIterator it(this); 1429 for (StackTraceFrameIterator it(this); !it.done(); it.Advance()) {
1430 while (!it.done()) { 1430 if (!it.is_javascript()) continue;
1431
1431 HandleScope scope(this); 1432 HandleScope scope(this);
1433 JavaScriptFrame* frame = it.javascript_frame();
1434
1432 // Find code position if recorded in relocation info. 1435 // Find code position if recorded in relocation info.
1433 StandardFrame* frame = it.frame(); 1436 AbstractCode* abstract_code = AbstractCode::cast(frame->LookupCode());
1434 AbstractCode* abstract_code; 1437 const int code_offset =
1435 int code_offset; 1438 static_cast<int>(frame->pc() - abstract_code->instruction_start());
1436 if (frame->is_interpreted()) { 1439
1437 InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame); 1440 Handle<StackTraceFrame> st_frame = factory()->NewStackTraceFrame();
1438 abstract_code = AbstractCode::cast(iframe->GetBytecodeArray()); 1441
1439 code_offset = iframe->GetBytecodeOffset(); 1442 st_frame->set_receiver(frame->receiver());
1440 } else { 1443 st_frame->set_function(frame->function());
1441 DCHECK(frame->is_java_script() || frame->is_wasm()); 1444 st_frame->set_abstract_code(abstract_code);
1442 Code* code = frame->LookupCode(); 1445 st_frame->set_offset(code_offset);
1443 abstract_code = AbstractCode::cast(code); 1446
1444 code_offset = static_cast<int>(frame->pc() - code->instruction_start());
1445 }
1446 int pos = abstract_code->SourcePosition(code_offset);
1447 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
1448 Handle<Object> pos_obj(Smi::FromInt(pos), this);
1449 // Fetch function and receiver.
1450 Handle<JSFunction> fun(js_frame->function(), this);
1451 Handle<Object> recv(js_frame->receiver(), this);
1452 // Advance to the next JavaScript frame and determine if the
1453 // current frame is the top-level frame.
1454 it.Advance();
1455 Handle<Object> is_top_level = factory()->ToBoolean(it.done());
1456 // Generate and print stack trace line. 1447 // Generate and print stack trace line.
1457 Handle<String> line = 1448 Handle<String> line = st_frame->ToString();
1458 Execution::GetStackTraceLine(recv, fun, pos_obj, is_top_level);
1459 if (line->length() > 0) { 1449 if (line->length() > 0) {
1460 line->PrintOn(out); 1450 line->PrintOn(out);
1461 PrintF(out, "\n"); 1451 PrintF(out, "\n");
1462 } 1452 }
1463 } 1453 }
1464 } 1454 }
1465 1455
1466 bool Isolate::ComputeLocation(MessageLocation* target) { 1456 bool Isolate::ComputeLocation(MessageLocation* target) {
1467 StackTraceFrameIterator it(this); 1457 StackTraceFrameIterator it(this);
1468 if (it.done()) return false; 1458 if (it.done()) return false;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1506 Handle<Name> script_symbol = factory()->error_script_symbol(); 1496 Handle<Name> script_symbol = factory()->error_script_symbol();
1507 Handle<Object> script = JSReceiver::GetDataProperty( 1497 Handle<Object> script = JSReceiver::GetDataProperty(
1508 Handle<JSObject>::cast(exception), script_symbol); 1498 Handle<JSObject>::cast(exception), script_symbol);
1509 if (!script->IsScript()) return false; 1499 if (!script->IsScript()) return false;
1510 1500
1511 Handle<Script> cast_script(Script::cast(*script)); 1501 Handle<Script> cast_script(Script::cast(*script));
1512 *target = MessageLocation(cast_script, start_pos_value, end_pos_value); 1502 *target = MessageLocation(cast_script, start_pos_value, end_pos_value);
1513 return true; 1503 return true;
1514 } 1504 }
1515 1505
1506 namespace {
1507
1508 int PositionFromStackTrace(Handle<FixedArray> elements, int index) {
1509 DisallowHeapAllocation no_gc;
1510 using ESTF = EncodedStackTraceFrame;
1511 Object* maybe_code = elements->get(index + ESTF::kCodeOffset);
1512 if (maybe_code->IsSmi()) {
1513 return Smi::cast(maybe_code)->value();
1514 } else {
1515 AbstractCode* abstract_code = AbstractCode::cast(maybe_code);
1516 int code_offset =
1517 Smi::cast(elements->get(index + ESTF::kOffsetOffset))->value();
1518 return abstract_code->SourcePosition(code_offset);
1519 }
1520 }
1521
1522 } // namespace
1516 1523
1517 bool Isolate::ComputeLocationFromStackTrace(MessageLocation* target, 1524 bool Isolate::ComputeLocationFromStackTrace(MessageLocation* target,
1518 Handle<Object> exception) { 1525 Handle<Object> exception) {
1519 if (!exception->IsJSObject()) return false; 1526 if (!exception->IsJSObject()) return false;
1520 Handle<Name> key = factory()->stack_trace_symbol(); 1527 Handle<Name> key = factory()->stack_trace_symbol();
1521 Handle<Object> property = 1528 Handle<Object> property =
1522 JSReceiver::GetDataProperty(Handle<JSObject>::cast(exception), key); 1529 JSReceiver::GetDataProperty(Handle<JSObject>::cast(exception), key);
1523 if (!property->IsJSArray()) return false; 1530 if (!property->IsJSArray()) return false;
1524 Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property); 1531 Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property);
1525 1532
1526 Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements())); 1533 Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements()));
1527 int elements_limit = Smi::cast(simple_stack_trace->length())->value(); 1534 int elements_limit = Smi::cast(simple_stack_trace->length())->value();
1528 1535
1529 for (int i = 1; i < elements_limit; i += 4) { 1536 using ESTF = EncodedStackTraceFrame;
1530 Handle<Object> fun_obj = handle(elements->get(i + 1), this); 1537 for (int i = 0; i < elements_limit; i += ESTF::kElementsPerFrame) {
1538 Handle<Object> fun_obj =
1539 handle(elements->get(i + ESTF::kFunctionOffset), this);
1531 if (fun_obj->IsSmi()) { 1540 if (fun_obj->IsSmi()) {
1532 // TODO(clemensh): handle wasm frames 1541 // TODO(clemensh): handle wasm frames
1533 return false; 1542 return false;
1534 } 1543 }
1535 Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj); 1544 Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj);
1536 if (!fun->shared()->IsSubjectToDebugging()) continue; 1545 if (!fun->shared()->IsSubjectToDebugging()) continue;
1537 1546
1538 Object* script = fun->shared()->script(); 1547 Object* script = fun->shared()->script();
1539 if (script->IsScript() && 1548 if (script->IsScript() &&
1540 !(Script::cast(script)->source()->IsUndefined(this))) { 1549 !(Script::cast(script)->source()->IsUndefined(this))) {
(...skipping 1662 matching lines...) Expand 10 before | Expand all | Expand 10 after
3203 // Then check whether this scope intercepts. 3212 // Then check whether this scope intercepts.
3204 if ((flag & intercept_mask_)) { 3213 if ((flag & intercept_mask_)) {
3205 intercepted_flags_ |= flag; 3214 intercepted_flags_ |= flag;
3206 return true; 3215 return true;
3207 } 3216 }
3208 return false; 3217 return false;
3209 } 3218 }
3210 3219
3211 } // namespace internal 3220 } // namespace internal
3212 } // namespace v8 3221 } // namespace v8
OLDNEW
« no previous file with comments | « src/isolate.h ('k') | src/messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698