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

Side by Side Diff: src/isolate.cc

Issue 2169563003: Revert of Remove stack overflow boilerplate (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 5 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/js/messages.js » ('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 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 for (int i = 0; i < cur_position; i++) { 322 for (int i = 0; i < cur_position; i++) {
323 new_elements->set(i, elements->get(i)); 323 new_elements->set(i, elements->get(i));
324 } 324 }
325 elements = new_elements; 325 elements = new_elements;
326 } 326 }
327 DCHECK(new_size <= elements->length()); 327 DCHECK(new_size <= elements->length());
328 return elements; 328 return elements;
329 } 329 }
330 330
331 class StackTraceHelper { 331 class StackTraceHelper {
332 private:
333 enum FrameSkipMode {
334 SKIP_FIRST,
335 SKIP_UNTIL_SEEN,
336 SKIP_NONE,
337 };
338
332 public: 339 public:
333 StackTraceHelper(Isolate* isolate, FrameSkipMode mode, Handle<Object> caller) 340 StackTraceHelper(Isolate* isolate, Handle<Object> caller)
334 : isolate_(isolate), mode_(mode), caller_(caller) { 341 : isolate_(isolate), caller_(caller) {
335 // The caller parameter can be used to skip a specific set of frames in the 342 // The caller parameter can be used to skip a specific set of frames in the
336 // stack trace. It can be: 343 // stack trace. It can be:
337 // * null, when called from a standard error constructor. We unconditionally 344 // * null, when called from a standard error constructor. We unconditionally
338 // skip the top frame, which is always a builtin-exit frame for the error 345 // skip the top frame, which is always a builtin-exit frame for the error
339 // constructor builtin. 346 // constructor builtin.
340 // * a JSFunction, when called by the user from Error.captureStackTrace(). 347 // * a JSFunction, when called by the user from Error.captureStackTrace().
341 // We skip each frame until encountering the caller function. 348 // We skip each frame until encountering the caller function.
342 // * For any other value, all frames are included in the trace. 349 // * For any other value, all frames are included in the trace.
343 switch (mode_) { 350 if (caller_.is_null()) {
344 case SKIP_FIRST: 351 mode_ = SKIP_FIRST;
345 DCHECK(caller_.is_null()); 352 skip_next_frame_ = true;
346 skip_next_frame_ = true; 353 } else if (caller_->IsJSFunction()) {
347 break; 354 mode_ = SKIP_UNTIL_SEEN;
348 case SKIP_UNTIL_SEEN: 355 skip_next_frame_ = true;
349 DCHECK(caller_->IsJSFunction()); 356 } else {
350 skip_next_frame_ = true; 357 mode_ = SKIP_NONE;
351 break; 358 skip_next_frame_ = false;
352 case SKIP_NONE:
353 skip_next_frame_ = false;
354 break;
355 } 359 }
356 encountered_strict_function_ = false; 360 encountered_strict_function_ = false;
357 sloppy_frames_ = 0; 361 sloppy_frames_ = 0;
358 } 362 }
359 363
360 // The stack trace API should not expose receivers and function 364 // The stack trace API should not expose receivers and function
361 // objects on frames deeper than the top-most one with a strict mode 365 // objects on frames deeper than the top-most one with a strict mode
362 // function. The number of sloppy frames is stored as first element in 366 // function. The number of sloppy frames is stored as first element in
363 // the result array. 367 // the result array.
364 void CountSloppyFrames(JSFunction* fun) { 368 void CountSloppyFrames(JSFunction* fun) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 } 418 }
415 return true; 419 return true;
416 } 420 }
417 421
418 bool IsInSameSecurityContext(JSFunction* fun) { 422 bool IsInSameSecurityContext(JSFunction* fun) {
419 return isolate_->context()->HasSameSecurityTokenAs(fun->context()); 423 return isolate_->context()->HasSameSecurityTokenAs(fun->context());
420 } 424 }
421 425
422 Isolate* isolate_; 426 Isolate* isolate_;
423 427
424 const FrameSkipMode mode_; 428 FrameSkipMode mode_;
425 const Handle<Object> caller_; 429 Handle<Object> caller_;
426 bool skip_next_frame_; 430 bool skip_next_frame_;
427 431
428 int sloppy_frames_; 432 int sloppy_frames_;
429 bool encountered_strict_function_; 433 bool encountered_strict_function_;
430 }; 434 };
431 435
432 Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object, 436 Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object,
433 FrameSkipMode mode,
434 Handle<Object> caller) { 437 Handle<Object> caller) {
435 DisallowJavascriptExecution no_js(this); 438 DisallowJavascriptExecution no_js(this);
436 439
437 // Get stack trace limit. 440 // Get stack trace limit.
438 Handle<JSObject> error = error_function(); 441 Handle<JSObject> error = error_function();
439 Handle<String> stackTraceLimit = 442 Handle<String> stackTraceLimit =
440 factory()->InternalizeUtf8String("stackTraceLimit"); 443 factory()->InternalizeUtf8String("stackTraceLimit");
441 DCHECK(!stackTraceLimit.is_null()); 444 DCHECK(!stackTraceLimit.is_null());
442 Handle<Object> stack_trace_limit = 445 Handle<Object> stack_trace_limit =
443 JSReceiver::GetDataProperty(error, stackTraceLimit); 446 JSReceiver::GetDataProperty(error, stackTraceLimit);
444 if (!stack_trace_limit->IsNumber()) return factory()->undefined_value(); 447 if (!stack_trace_limit->IsNumber()) return factory()->undefined_value();
445 int limit = FastD2IChecked(stack_trace_limit->Number()); 448 int limit = FastD2IChecked(stack_trace_limit->Number());
446 limit = Max(limit, 0); // Ensure that limit is not negative. 449 limit = Max(limit, 0); // Ensure that limit is not negative.
447 450
448 int initial_size = Min(limit, 10); 451 int initial_size = Min(limit, 10);
449 Handle<FixedArray> elements = 452 Handle<FixedArray> elements =
450 factory()->NewFixedArrayWithHoles(initial_size * 4 + 1); 453 factory()->NewFixedArrayWithHoles(initial_size * 4 + 1);
451 454
452 StackTraceHelper helper(this, mode, caller); 455 StackTraceHelper helper(this, caller);
453 456
454 // First element is reserved to store the number of sloppy frames. 457 // First element is reserved to store the number of sloppy frames.
455 int cursor = 1; 458 int cursor = 1;
456 int frames_seen = 0; 459 int frames_seen = 0;
457 for (StackFrameIterator iter(this); !iter.done() && frames_seen < limit; 460 for (StackFrameIterator iter(this); !iter.done() && frames_seen < limit;
458 iter.Advance()) { 461 iter.Advance()) {
459 StackFrame* frame = iter.frame(); 462 StackFrame* frame = iter.frame();
460 463
461 switch (frame->type()) { 464 switch (frame->type()) {
462 case StackFrame::JAVA_SCRIPT: 465 case StackFrame::JAVA_SCRIPT:
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 stack_trace_for_uncaught_exceptions_options_); 565 stack_trace_for_uncaught_exceptions_options_);
563 // TODO(jgruber): Set back to STRICT once we have eagerly formatted traces. 566 // TODO(jgruber): Set back to STRICT once we have eagerly formatted traces.
564 RETURN_ON_EXCEPTION( 567 RETURN_ON_EXCEPTION(
565 this, JSReceiver::SetProperty(error_object, key, stack_trace, SLOPPY), 568 this, JSReceiver::SetProperty(error_object, key, stack_trace, SLOPPY),
566 JSReceiver); 569 JSReceiver);
567 } 570 }
568 return error_object; 571 return error_object;
569 } 572 }
570 573
571 MaybeHandle<JSReceiver> Isolate::CaptureAndSetSimpleStackTrace( 574 MaybeHandle<JSReceiver> Isolate::CaptureAndSetSimpleStackTrace(
572 Handle<JSReceiver> error_object, FrameSkipMode mode, 575 Handle<JSReceiver> error_object, Handle<Object> caller) {
573 Handle<Object> caller) {
574 // Capture stack trace for simple stack trace string formatting. 576 // Capture stack trace for simple stack trace string formatting.
575 Handle<Name> key = factory()->stack_trace_symbol(); 577 Handle<Name> key = factory()->stack_trace_symbol();
576 Handle<Object> stack_trace = 578 Handle<Object> stack_trace = CaptureSimpleStackTrace(error_object, caller);
577 CaptureSimpleStackTrace(error_object, mode, caller);
578 // TODO(jgruber): Set back to STRICT once we have eagerly formatted traces. 579 // TODO(jgruber): Set back to STRICT once we have eagerly formatted traces.
579 RETURN_ON_EXCEPTION( 580 RETURN_ON_EXCEPTION(
580 this, JSReceiver::SetProperty(error_object, key, stack_trace, SLOPPY), 581 this, JSReceiver::SetProperty(error_object, key, stack_trace, SLOPPY),
581 JSReceiver); 582 JSReceiver);
582 return error_object; 583 return error_object;
583 } 584 }
584 585
585 586
586 Handle<JSArray> Isolate::GetDetailedStackTrace(Handle<JSObject> error_object) { 587 Handle<JSArray> Isolate::GetDetailedStackTrace(Handle<JSObject> error_object) {
587 Handle<Name> key_detailed = factory()->detailed_stack_trace_symbol(); 588 Handle<Name> key_detailed = factory()->detailed_stack_trace_symbol();
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 VMState<EXTERNAL> state(this); 953 VMState<EXTERNAL> state(this);
953 return callback(v8::Utils::ToLocal(accessing_context), 954 return callback(v8::Utils::ToLocal(accessing_context),
954 v8::Utils::ToLocal(receiver), v8::Utils::ToLocal(data)); 955 v8::Utils::ToLocal(receiver), v8::Utils::ToLocal(data));
955 } 956 }
956 } 957 }
957 958
958 959
959 Object* Isolate::StackOverflow() { 960 Object* Isolate::StackOverflow() {
960 DisallowJavascriptExecution no_js(this); 961 DisallowJavascriptExecution no_js(this);
961 HandleScope scope(this); 962 HandleScope scope(this);
962 963 // At this point we cannot create an Error object using its javascript
963 Handle<JSFunction> fun = range_error_function(); 964 // constructor. Instead, we copy the pre-constructed boilerplate and
964 Handle<Object> msg = factory()->NewStringFromAsciiChecked( 965 // attach the stack trace as a hidden property.
965 MessageTemplate::TemplateString(MessageTemplate::kStackOverflow));
966 Handle<Object> exception; 966 Handle<Object> exception;
967 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 967 if (bootstrapper()->IsActive()) {
968 this, exception, ConstructError(this, fun, fun, msg, SKIP_NONE, true)); 968 // There is no boilerplate to use during bootstrapping.
969 969 exception = factory()->NewStringFromAsciiChecked(
970 MessageTemplate::TemplateString(MessageTemplate::kStackOverflow));
971 } else {
972 Handle<JSObject> boilerplate = stack_overflow_boilerplate();
973 Handle<JSObject> copy = factory()->CopyJSObject(boilerplate);
974 CaptureAndSetSimpleStackTrace(copy, factory()->undefined_value());
975 exception = copy;
976 }
970 Throw(*exception, nullptr); 977 Throw(*exception, nullptr);
971 978
972 #ifdef VERIFY_HEAP 979 #ifdef VERIFY_HEAP
973 if (FLAG_verify_heap && FLAG_stress_compaction) { 980 if (FLAG_verify_heap && FLAG_stress_compaction) {
974 heap()->CollectAllGarbage(Heap::kNoGCFlags, "trigger compaction"); 981 heap()->CollectAllGarbage(Heap::kNoGCFlags, "trigger compaction");
975 } 982 }
976 #endif // VERIFY_HEAP 983 #endif // VERIFY_HEAP
977 984
978 return heap()->exception(); 985 return heap()->exception();
979 } 986 }
(...skipping 2139 matching lines...) Expand 10 before | Expand all | Expand 10 after
3119 // Then check whether this scope intercepts. 3126 // Then check whether this scope intercepts.
3120 if ((flag & intercept_mask_)) { 3127 if ((flag & intercept_mask_)) {
3121 intercepted_flags_ |= flag; 3128 intercepted_flags_ |= flag;
3122 return true; 3129 return true;
3123 } 3130 }
3124 return false; 3131 return false;
3125 } 3132 }
3126 3133
3127 } // namespace internal 3134 } // namespace internal
3128 } // namespace v8 3135 } // namespace v8
OLDNEW
« no previous file with comments | « src/isolate.h ('k') | src/js/messages.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698