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

Side by Side Diff: src/isolate.cc

Issue 2270783002: Add new FrameArray type (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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') | src/messages.cc » ('J')
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 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 uint8_t buffer[kMaxStackTraceSize]; 308 uint8_t buffer[kMaxStackTraceSize];
309 int length = Min(kMaxStackTraceSize - 1, trace->length()); 309 int length = Min(kMaxStackTraceSize - 1, trace->length());
310 String::WriteToFlat(*trace, buffer, 0, length); 310 String::WriteToFlat(*trace, buffer, 0, length);
311 buffer[length] = '\0'; 311 buffer[length] = '\0';
312 // TODO(dcarney): convert buffer to utf8? 312 // TODO(dcarney): convert buffer to utf8?
313 base::OS::PrintError("Stacktrace (%x-%x) %p %p: %s\n", magic, magic2, ptr1, 313 base::OS::PrintError("Stacktrace (%x-%x) %p %p: %s\n", magic, magic2, ptr1,
314 ptr2, reinterpret_cast<char*>(buffer)); 314 ptr2, reinterpret_cast<char*>(buffer));
315 base::OS::Abort(); 315 base::OS::Abort();
316 } 316 }
317 317
318 static Handle<FixedArray> MaybeGrow(Isolate* isolate, 318 namespace {
319 Handle<FixedArray> elements,
320 int cur_position, int new_size) {
321 if (new_size > elements->length()) {
322 int new_capacity = JSObject::NewElementsCapacity(elements->length());
323 Handle<FixedArray> new_elements =
324 isolate->factory()->NewFixedArrayWithHoles(new_capacity);
325 for (int i = 0; i < cur_position; i++) {
326 new_elements->set(i, elements->get(i));
327 }
328 elements = new_elements;
329 }
330 DCHECK(new_size <= elements->length());
331 return elements;
332 }
333 319
334 class StackTraceHelper { 320 class StackTraceHelper {
335 public: 321 public:
336 StackTraceHelper(Isolate* isolate, FrameSkipMode mode, Handle<Object> caller) 322 StackTraceHelper(Isolate* isolate, FrameSkipMode mode, Handle<Object> caller)
337 : isolate_(isolate), 323 : isolate_(isolate),
338 mode_(mode), 324 mode_(mode),
339 caller_(caller), 325 caller_(caller),
340 skip_next_frame_(true) { 326 skip_next_frame_(true) {
341 // The caller parameter can be used to skip a specific set of frames in the 327 // The caller parameter can be used to skip a specific set of frames in the
342 // stack trace. It can be: 328 // stack trace. It can be:
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 Isolate* isolate_; 414 Isolate* isolate_;
429 415
430 const FrameSkipMode mode_; 416 const FrameSkipMode mode_;
431 const Handle<Object> caller_; 417 const Handle<Object> caller_;
432 bool skip_next_frame_; 418 bool skip_next_frame_;
433 419
434 int sloppy_frames_; 420 int sloppy_frames_;
435 bool encountered_strict_function_; 421 bool encountered_strict_function_;
436 }; 422 };
437 423
438 namespace {
439
440 // TODO(jgruber): Fix all cases in which frames give us a hole value (e.g. the 424 // TODO(jgruber): Fix all cases in which frames give us a hole value (e.g. the
441 // receiver in RegExp constructor frames. 425 // receiver in RegExp constructor frames.
442 Handle<Object> TheHoleToUndefined(Isolate* isolate, Handle<Object> in) { 426 Handle<Object> TheHoleToUndefined(Isolate* isolate, Handle<Object> in) {
443 return (in->IsTheHole(isolate)) 427 return (in->IsTheHole(isolate))
444 ? Handle<Object>::cast(isolate->factory()->undefined_value()) 428 ? Handle<Object>::cast(isolate->factory()->undefined_value())
445 : in; 429 : in;
446 } 430 }
447 } 431
432 } // namespace
448 433
449 Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object, 434 Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object,
450 FrameSkipMode mode, 435 FrameSkipMode mode,
451 Handle<Object> caller) { 436 Handle<Object> caller) {
452 DisallowJavascriptExecution no_js(this); 437 DisallowJavascriptExecution no_js(this);
453 438
454 // Get stack trace limit. 439 // Get stack trace limit.
455 Handle<JSObject> error = error_function(); 440 Handle<JSObject> error = error_function();
456 Handle<String> stackTraceLimit = 441 Handle<String> stackTraceLimit =
457 factory()->InternalizeUtf8String("stackTraceLimit"); 442 factory()->InternalizeUtf8String("stackTraceLimit");
458 DCHECK(!stackTraceLimit.is_null()); 443 DCHECK(!stackTraceLimit.is_null());
459 Handle<Object> stack_trace_limit = 444 Handle<Object> stack_trace_limit =
460 JSReceiver::GetDataProperty(error, stackTraceLimit); 445 JSReceiver::GetDataProperty(error, stackTraceLimit);
461 if (!stack_trace_limit->IsNumber()) return factory()->undefined_value(); 446 if (!stack_trace_limit->IsNumber()) return factory()->undefined_value();
462 int limit = FastD2IChecked(stack_trace_limit->Number()); 447 int limit = FastD2IChecked(stack_trace_limit->Number());
463 limit = Max(limit, 0); // Ensure that limit is not negative. 448 limit = Max(limit, 0); // Ensure that limit is not negative.
464 449
465 int initial_size = Min(limit, 10); 450 int initial_size = Min(limit, 10);
466 Handle<FixedArray> elements = 451 Handle<FrameArray> elements = FrameArray::Allocate(this, initial_size);
467 factory()->NewFixedArrayWithHoles(initial_size * 4 + 1);
468 452
469 StackTraceHelper helper(this, mode, caller); 453 StackTraceHelper helper(this, mode, caller);
470 454
471 // First element is reserved to store the number of sloppy frames.
472 int cursor = 1;
473 int frames_seen = 0; 455 int frames_seen = 0;
Toon Verwaest 2016/08/23 13:14:08 Perhaps we should just encapsulate frames_seen as
jgruber 2016/08/23 15:32:13 Done.
474 for (StackFrameIterator iter(this); !iter.done() && frames_seen < limit; 456 for (StackFrameIterator iter(this); !iter.done() && frames_seen < limit;
475 iter.Advance()) { 457 iter.Advance()) {
476 StackFrame* frame = iter.frame(); 458 StackFrame* frame = iter.frame();
477 459
478 switch (frame->type()) { 460 switch (frame->type()) {
479 case StackFrame::JAVA_SCRIPT: 461 case StackFrame::JAVA_SCRIPT:
480 case StackFrame::OPTIMIZED: 462 case StackFrame::OPTIMIZED:
481 case StackFrame::INTERPRETED: 463 case StackFrame::INTERPRETED:
482 case StackFrame::BUILTIN: { 464 case StackFrame::BUILTIN: {
483 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame); 465 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
(...skipping 11 matching lines...) Expand all
495 Handle<Object> recv = frames[i].receiver(); 477 Handle<Object> recv = frames[i].receiver();
496 Handle<AbstractCode> abstract_code = frames[i].abstract_code(); 478 Handle<AbstractCode> abstract_code = frames[i].abstract_code();
497 if (frame->type() == StackFrame::BUILTIN) { 479 if (frame->type() == StackFrame::BUILTIN) {
498 // Help CallSite::IsConstructor correctly detect hand-written 480 // Help CallSite::IsConstructor correctly detect hand-written
499 // construct stubs. 481 // construct stubs.
500 Code* code = Code::cast(*abstract_code); 482 Code* code = Code::cast(*abstract_code);
501 if (code->is_construct_stub()) { 483 if (code->is_construct_stub()) {
502 recv = handle(heap()->call_site_constructor_symbol(), this); 484 recv = handle(heap()->call_site_constructor_symbol(), this);
503 } 485 }
504 } 486 }
505 Handle<Smi> offset(Smi::FromInt(frames[i].code_offset()), this); 487 const int offset = frames[i].code_offset();
506 488
507 elements = MaybeGrow(this, elements, cursor, cursor + 4); 489 elements = FrameArray::AppendJSFrame(elements, frames_seen,
508 elements->set(cursor++, *TheHoleToUndefined(this, recv)); 490 TheHoleToUndefined(this, recv),
509 elements->set(cursor++, *fun); 491 fun, abstract_code, offset);
510 elements->set(cursor++, *abstract_code);
511 elements->set(cursor++, *offset);
512 frames_seen++; 492 frames_seen++;
513 } 493 }
514 } break; 494 } break;
515 495
516 case StackFrame::BUILTIN_EXIT: { 496 case StackFrame::BUILTIN_EXIT: {
517 BuiltinExitFrame* exit_frame = BuiltinExitFrame::cast(frame); 497 BuiltinExitFrame* exit_frame = BuiltinExitFrame::cast(frame);
518 Handle<JSFunction> fun = handle(exit_frame->function(), this); 498 Handle<JSFunction> fun = handle(exit_frame->function(), this);
519 499
520 // Filter out internal frames that we do not want to show. 500 // Filter out internal frames that we do not want to show.
521 if (!helper.IsVisibleInStackTrace(*fun)) continue; 501 if (!helper.IsVisibleInStackTrace(*fun)) continue;
522 helper.CountSloppyFrames(*fun); 502 helper.CountSloppyFrames(*fun);
523 503
524 Handle<Code> code = handle(exit_frame->LookupCode(), this); 504 Handle<Code> code = handle(exit_frame->LookupCode(), this);
525 int offset = 505 int offset =
526 static_cast<int>(exit_frame->pc() - code->instruction_start()); 506 static_cast<int>(exit_frame->pc() - code->instruction_start());
527 507
528 // In order to help CallSite::IsConstructor detect builtin constructors, 508 // In order to help CallSite::IsConstructor detect builtin constructors,
529 // we reuse the receiver field to pass along a special symbol. 509 // we reuse the receiver field to pass along a special symbol.
530 Handle<Object> recv; 510 Handle<Object> recv;
531 if (exit_frame->IsConstructor()) { 511 if (exit_frame->IsConstructor()) {
532 recv = factory()->call_site_constructor_symbol(); 512 recv = factory()->call_site_constructor_symbol();
533 } else { 513 } else {
534 recv = handle(exit_frame->receiver(), this); 514 recv = handle(exit_frame->receiver(), this);
535 } 515 }
536 516
537 elements = MaybeGrow(this, elements, cursor, cursor + 4); 517 elements =
538 elements->set(cursor++, *recv); 518 FrameArray::AppendJSFrame(elements, frames_seen, recv, fun,
539 elements->set(cursor++, *fun); 519 Handle<AbstractCode>::cast(code), offset);
540 elements->set(cursor++, *code);
541 elements->set(cursor++, Smi::FromInt(offset));
542 frames_seen++; 520 frames_seen++;
543 } break; 521 } break;
544 522
545 case StackFrame::WASM: { 523 case StackFrame::WASM: {
546 WasmFrame* wasm_frame = WasmFrame::cast(frame); 524 WasmFrame* wasm_frame = WasmFrame::cast(frame);
525 Handle<Object> wasm_object = handle(wasm_frame->wasm_obj(), this);
526 const int wasm_function_index = wasm_frame->function_index();
547 Code* code = wasm_frame->unchecked_code(); 527 Code* code = wasm_frame->unchecked_code();
548 Handle<AbstractCode> abstract_code = 528 Handle<AbstractCode> abstract_code =
549 Handle<AbstractCode>(AbstractCode::cast(code), this); 529 Handle<AbstractCode>(AbstractCode::cast(code), this);
550 int offset = 530 const int offset =
551 static_cast<int>(wasm_frame->pc() - code->instruction_start()); 531 static_cast<int>(wasm_frame->pc() - code->instruction_start());
552 elements = MaybeGrow(this, elements, cursor, cursor + 4); 532
553 elements->set(cursor++, wasm_frame->wasm_obj()); 533 // TODO(wasm): The wasm object returned by the WasmFrame should always
554 elements->set(cursor++, Smi::FromInt(wasm_frame->function_index())); 534 // be a wasm object.
555 elements->set(cursor++, *abstract_code); 535 DCHECK(wasm::IsWasmObject(*wasm_object) ||
556 elements->set(cursor++, Smi::FromInt(offset)); 536 wasm_object->IsUndefined(this));
537
538 elements = FrameArray::AppendWasmFrame(elements, frames_seen,
539 wasm_object, wasm_function_index,
540 abstract_code, offset);
557 frames_seen++; 541 frames_seen++;
558 } break; 542 } break;
559 543
560 default: 544 default:
561 break; 545 break;
562 } 546 }
563 } 547 }
564 elements->set(0, Smi::FromInt(helper.sloppy_frames())); 548 elements->set(0, Smi::FromInt(helper.sloppy_frames()));
565 elements->Shrink(cursor); 549
550 const int elements_length = FrameArray::LengthFor(frames_seen);
Toon Verwaest 2016/08/23 13:14:08 What about elements->Shrink(frames_seen) to avoid
jgruber 2016/08/23 15:32:13 Done.
551 elements->Shrink(elements_length);
552
566 Handle<JSArray> result = factory()->NewJSArrayWithElements(elements); 553 Handle<JSArray> result = factory()->NewJSArrayWithElements(elements);
567 result->set_length(Smi::FromInt(cursor)); 554 result->set_length(Smi::FromInt(elements_length));
555
568 // TODO(yangguo): Queue this structured stack trace for preprocessing on GC. 556 // TODO(yangguo): Queue this structured stack trace for preprocessing on GC.
569 return result; 557 return result;
570 } 558 }
571 559
572 MaybeHandle<JSReceiver> Isolate::CaptureAndSetDetailedStackTrace( 560 MaybeHandle<JSReceiver> Isolate::CaptureAndSetDetailedStackTrace(
573 Handle<JSReceiver> error_object) { 561 Handle<JSReceiver> error_object) {
574 if (capture_stack_trace_for_uncaught_exceptions_) { 562 if (capture_stack_trace_for_uncaught_exceptions_) {
575 // Capture stack trace for a detailed exception message. 563 // Capture stack trace for a detailed exception message.
576 Handle<Name> key = factory()->detailed_stack_trace_symbol(); 564 Handle<Name> key = factory()->detailed_stack_trace_symbol();
577 Handle<JSArray> stack_trace = CaptureCurrentStackTrace( 565 Handle<JSArray> stack_trace = CaptureCurrentStackTrace(
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 Handle<String> column_key_; 754 Handle<String> column_key_;
767 Handle<String> line_key_; 755 Handle<String> line_key_;
768 Handle<String> script_id_key_; 756 Handle<String> script_id_key_;
769 Handle<String> script_name_key_; 757 Handle<String> script_name_key_;
770 Handle<String> script_name_or_source_url_key_; 758 Handle<String> script_name_or_source_url_key_;
771 Handle<String> function_key_; 759 Handle<String> function_key_;
772 Handle<String> eval_key_; 760 Handle<String> eval_key_;
773 Handle<String> constructor_key_; 761 Handle<String> constructor_key_;
774 }; 762 };
775 763
776
777 int PositionFromStackTrace(Handle<FixedArray> elements, int index) {
778 DisallowHeapAllocation no_gc;
779 Object* maybe_code = elements->get(index + 2);
780 if (maybe_code->IsSmi()) {
781 return Smi::cast(maybe_code)->value();
782 } else {
783 AbstractCode* abstract_code = AbstractCode::cast(maybe_code);
784 int code_offset = Smi::cast(elements->get(index + 3))->value();
785 return abstract_code->SourcePosition(code_offset);
786 }
787 }
788
789 Handle<JSArray> Isolate::CaptureCurrentStackTrace( 764 Handle<JSArray> Isolate::CaptureCurrentStackTrace(
790 int frame_limit, StackTrace::StackTraceOptions options) { 765 int frame_limit, StackTrace::StackTraceOptions options) {
791 DisallowJavascriptExecution no_js(this); 766 DisallowJavascriptExecution no_js(this);
792 CaptureStackTraceHelper helper(this, options); 767 CaptureStackTraceHelper helper(this, options);
793 768
794 // Ensure no negative values. 769 // Ensure no negative values.
795 int limit = Max(frame_limit, 0); 770 int limit = Max(frame_limit, 0);
796 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); 771 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit);
797 Handle<FixedArray> stack_trace_elems( 772 Handle<FixedArray> stack_trace_elems(
798 FixedArray::cast(stack_trace->elements()), this); 773 FixedArray::cast(stack_trace->elements()), this);
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
1524 1499
1525 bool Isolate::ComputeLocationFromStackTrace(MessageLocation* target, 1500 bool Isolate::ComputeLocationFromStackTrace(MessageLocation* target,
1526 Handle<Object> exception) { 1501 Handle<Object> exception) {
1527 if (!exception->IsJSObject()) return false; 1502 if (!exception->IsJSObject()) return false;
1528 Handle<Name> key = factory()->stack_trace_symbol(); 1503 Handle<Name> key = factory()->stack_trace_symbol();
1529 Handle<Object> property = 1504 Handle<Object> property =
1530 JSReceiver::GetDataProperty(Handle<JSObject>::cast(exception), key); 1505 JSReceiver::GetDataProperty(Handle<JSObject>::cast(exception), key);
1531 if (!property->IsJSArray()) return false; 1506 if (!property->IsJSArray()) return false;
1532 Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property); 1507 Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property);
1533 1508
1534 Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements())); 1509 Handle<FrameArray> elements(FrameArray::cast(simple_stack_trace->elements()));
1535 int elements_limit = Smi::cast(simple_stack_trace->length())->value();
1536 1510
1537 for (int i = 1; i < elements_limit; i += 4) { 1511 const int frame_count = elements->FrameCount();
1538 Handle<Object> fun_obj = handle(elements->get(i + 1), this); 1512 for (int i = 0; i < frame_count; i++) {
1539 if (fun_obj->IsSmi()) { 1513 if (elements->IsWasmFrame(i)) {
1540 // TODO(clemensh): handle wasm frames 1514 // TODO(clemensh): handle wasm frames
1541 return false; 1515 return false;
1542 } 1516 }
1543 Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj); 1517
1518 Handle<JSFunction> fun = handle(elements->Function(i), this);
1544 if (!fun->shared()->IsSubjectToDebugging()) continue; 1519 if (!fun->shared()->IsSubjectToDebugging()) continue;
1545 1520
1546 Object* script = fun->shared()->script(); 1521 Object* script = fun->shared()->script();
1547 if (script->IsScript() && 1522 if (script->IsScript() &&
1548 !(Script::cast(script)->source()->IsUndefined(this))) { 1523 !(Script::cast(script)->source()->IsUndefined(this))) {
1549 int pos = PositionFromStackTrace(elements, i); 1524 AbstractCode* abstract_code = elements->Code(i);
1525 const int code_offset = elements->Offset(i)->value();
1526 const int pos = abstract_code->SourcePosition(code_offset);
1527
1550 Handle<Script> casted_script(Script::cast(script)); 1528 Handle<Script> casted_script(Script::cast(script));
1551 *target = MessageLocation(casted_script, pos, pos + 1); 1529 *target = MessageLocation(casted_script, pos, pos + 1);
1552 return true; 1530 return true;
1553 } 1531 }
1554 } 1532 }
1555 return false; 1533 return false;
1556 } 1534 }
1557 1535
1558 1536
1559 Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception, 1537 Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception,
(...skipping 1651 matching lines...) Expand 10 before | Expand all | Expand 10 after
3211 // Then check whether this scope intercepts. 3189 // Then check whether this scope intercepts.
3212 if ((flag & intercept_mask_)) { 3190 if ((flag & intercept_mask_)) {
3213 intercepted_flags_ |= flag; 3191 intercepted_flags_ |= flag;
3214 return true; 3192 return true;
3215 } 3193 }
3216 return false; 3194 return false;
3217 } 3195 }
3218 3196
3219 } // namespace internal 3197 } // namespace internal
3220 } // namespace v8 3198 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/messages.cc » ('j') | src/messages.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698