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

Side by Side Diff: src/isolate.cc

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