Reland "Reland "[compiler] Don't collect source positions for the top frame""
This is a reland of f2e652264dd05c4d834191686f48a1afb0747131
Nothing has changed but
https://chromium-review.googlesource.com/c/v8/v8/+/1585269 has been rolled
back due to v8:9234.
Original change's description:
> Reland "[compiler] Don't collect source positions for the top frame"
>
> Fixed crashes by adding missing call to EnsureSourcePositionsAvailable,
> which requires clearing and restoring the pending exception.
>
> > While most source positions were not collected even throwing exceptions,
> > the top frame still was always collected as it was used to initialize
> > the JSMessageObject. This skips even that frame, by storing the
> > SharedFunctionInfo and bytecode offset in the JSMessageObject allowing
> > it to lazily evaluate the actual source position.
> >
> > Also adds tests to test-api.cc that test each of the source position
> > functions in isolation to ensure that they don't rely on previous
> > invocations to call the source collection function.
> >
> > Since no source positions are now collected at the point when an
> > exception is thrown, the mjsunit/stack-traces-overflow now passes again
> > with the flag enabled. (cctest/test-cpu-profiler/Inlining2 is now the
> > only failure).
>
> Bug: v8:8510
> Change-Id: Ifa5fe31d3db34a6c6d6a9cef3d646ad620dabd81
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1601270
> Commit-Queue: Dan Elphick <delphick@chromium.org>
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#61372}
TBR=ulan@chromium.org
Bug: v8:8510
Change-Id: Iaa9e376f90d10c0f25d1bcc352808363e4ea8b4d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1605946
Reviewed-by: Dan Elphick <delphick@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61418}
diff --git a/src/api.cc b/src/api.cc
index 17839f6..fac25e9 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -2857,20 +2857,28 @@
i::Isolate* isolate = self->GetIsolate();
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
- auto msg = i::Handle<i::JSMessageObject>::cast(self);
- return Just(msg->GetLineNumber());
+ i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
+ return Just(self->GetLineNumber());
}
int Message::GetStartPosition() const {
auto self = Utils::OpenHandle(this);
- return self->start_position();
+ i::Isolate* isolate = self->GetIsolate();
+ ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
+ EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
+ i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
+ return self->GetStartPosition();
}
int Message::GetEndPosition() const {
auto self = Utils::OpenHandle(this);
- return self->end_position();
+ i::Isolate* isolate = self->GetIsolate();
+ ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
+ EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
+ i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
+ return self->GetEndPosition();
}
int Message::ErrorLevel() const {
@@ -2883,8 +2891,8 @@
i::Isolate* isolate = self->GetIsolate();
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
- auto msg = i::Handle<i::JSMessageObject>::cast(self);
- return msg->GetColumnNumber();
+ i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
+ return self->GetColumnNumber();
}
Maybe<int> Message::GetStartColumn(Local<Context> context) const {
@@ -2896,11 +2904,11 @@
i::Isolate* isolate = self->GetIsolate();
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
- auto msg = i::Handle<i::JSMessageObject>::cast(self);
- const int column_number = msg->GetColumnNumber();
+ i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
+ const int column_number = self->GetColumnNumber();
if (column_number == -1) return -1;
- const int start = self->start_position();
- const int end = self->end_position();
+ const int start = self->GetStartPosition();
+ const int end = self->GetEndPosition();
return column_number + (end - start);
}
@@ -2930,8 +2938,8 @@
i::Isolate* isolate = self->GetIsolate();
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
- auto msg = i::Handle<i::JSMessageObject>::cast(self);
- RETURN_ESCAPED(Utils::ToLocal(msg->GetSourceLine()));
+ i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
+ RETURN_ESCAPED(Utils::ToLocal(self->GetSourceLine()));
}
diff --git a/src/builtins/base.tq b/src/builtins/base.tq
index 8ae6979..77b9a36 100644
--- a/src/builtins/base.tq
+++ b/src/builtins/base.tq
@@ -321,8 +321,11 @@
arguments: Object;
script: Script;
stack_frames: Object;
+ shared_info: SharedFunctionInfo | Undefined;
+
// Raw data fields.
// TODO(ishell): store as int32 instead of Smi.
+ bytecode_offset: Smi;
start_position: Smi;
end_position: Smi;
error_level: Smi;
diff --git a/src/frames.cc b/src/frames.cc
index ed585d7..b1117d3 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -1338,11 +1338,23 @@
}
}
+bool FrameSummary::AreSourcePositionsAvailable() const {
+ if (IsJavaScript()) {
+ return java_script_summary_.AreSourcePositionsAvailable();
+ }
+ return true;
+}
+
void FrameSummary::JavaScriptFrameSummary::EnsureSourcePositionsAvailable() {
Handle<SharedFunctionInfo> shared(function()->shared(), isolate());
SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate(), shared);
}
+bool FrameSummary::JavaScriptFrameSummary::AreSourcePositionsAvailable() const {
+ return !FLAG_enable_lazy_source_positions ||
+ function()->shared()->GetBytecodeArray()->HasSourcePositionTable();
+}
+
bool FrameSummary::JavaScriptFrameSummary::is_subject_to_debugging() const {
return function()->shared()->IsSubjectToDebugging();
}
diff --git a/src/frames.h b/src/frames.h
index 5a2e71f..d3c22e4 100644
--- a/src/frames.h
+++ b/src/frames.h
@@ -483,6 +483,7 @@
FixedArray parameters);
void EnsureSourcePositionsAvailable();
+ bool AreSourcePositionsAvailable() const;
Handle<Object> receiver() const { return receiver_; }
Handle<JSFunction> function() const { return function_; }
@@ -572,6 +573,7 @@
static FrameSummary Get(const StandardFrame* frame, int index);
void EnsureSourcePositionsAvailable();
+ bool AreSourcePositionsAvailable() const;
// Dispatched accessors.
Handle<Object> receiver() const;
diff --git a/src/heap/factory.cc b/src/heap/factory.cc
index 094ab75..9fb066e 100644
--- a/src/heap/factory.cc
+++ b/src/heap/factory.cc
@@ -3468,7 +3468,8 @@
Handle<JSMessageObject> Factory::NewJSMessageObject(
MessageTemplate message, Handle<Object> argument, int start_position,
- int end_position, Handle<Script> script, Handle<Object> stack_frames) {
+ int end_position, Handle<SharedFunctionInfo> shared_info,
+ int bytecode_offset, Handle<Script> script, Handle<Object> stack_frames) {
Handle<Map> map = message_object_map();
Handle<JSMessageObject> message_obj(
JSMessageObject::cast(New(map, AllocationType::kYoung)), isolate());
@@ -3481,6 +3482,23 @@
message_obj->set_start_position(start_position);
message_obj->set_end_position(end_position);
message_obj->set_script(*script);
+ if (start_position >= 0) {
+ // If there's a start_position, then there's no need to store the
+ // SharedFunctionInfo as it will never be necessary to regenerate the
+ // position.
+ message_obj->set_shared_info(*undefined_value());
+ message_obj->set_bytecode_offset(Smi::FromInt(0));
+ } else {
+ message_obj->set_bytecode_offset(Smi::FromInt(bytecode_offset));
+ if (shared_info.is_null()) {
+ message_obj->set_shared_info(*undefined_value());
+ DCHECK_EQ(bytecode_offset, -1);
+ } else {
+ message_obj->set_shared_info(*shared_info);
+ DCHECK_GE(bytecode_offset, 0);
+ }
+ }
+
message_obj->set_stack_frames(*stack_frames);
message_obj->set_error_level(v8::Isolate::kMessageError);
return message_obj;
diff --git a/src/heap/factory.h b/src/heap/factory.h
index c485f1a..d587b70 100644
--- a/src/heap/factory.h
+++ b/src/heap/factory.h
@@ -885,7 +885,8 @@
// Allocates a new JSMessageObject object.
Handle<JSMessageObject> NewJSMessageObject(
MessageTemplate message, Handle<Object> argument, int start_position,
- int end_position, Handle<Script> script, Handle<Object> stack_frames);
+ int end_position, Handle<SharedFunctionInfo> shared_info,
+ int bytecode_offset, Handle<Script> script, Handle<Object> stack_frames);
Handle<ClassPositions> NewClassPositions(int start, int end);
Handle<DebugInfo> NewDebugInfo(Handle<SharedFunctionInfo> shared);
diff --git a/src/isolate.cc b/src/isolate.cc
index 2d649c7..56efd34 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -2069,8 +2069,6 @@
wasm::WasmCodeRefScope code_ref_scope;
frame->Summarize(&frames);
FrameSummary& summary = frames.back();
- summary.EnsureSourcePositionsAvailable();
- int pos = summary.SourcePosition();
Handle<SharedFunctionInfo> shared;
Handle<Object> script = summary.script();
if (!script->IsScript() ||
@@ -2081,7 +2079,14 @@
if (summary.IsJavaScript()) {
shared = handle(summary.AsJavaScript().function()->shared(), this);
}
- *target = MessageLocation(Handle<Script>::cast(script), pos, pos + 1, shared);
+ if (summary.AreSourcePositionsAvailable()) {
+ int pos = summary.SourcePosition();
+ *target =
+ MessageLocation(Handle<Script>::cast(script), pos, pos + 1, shared);
+ } else {
+ *target = MessageLocation(Handle<Script>::cast(script), shared,
+ summary.code_offset());
+ }
return true;
}
@@ -2156,13 +2161,18 @@
if (script->IsScript() &&
!(Script::cast(script)->source()->IsUndefined(this))) {
Handle<SharedFunctionInfo> shared = handle(fun->shared(), this);
- SharedFunctionInfo::EnsureSourcePositionsAvailable(this, shared);
+
AbstractCode abstract_code = elements->Code(i);
const int code_offset = elements->Offset(i)->value();
- const int pos = abstract_code->SourcePosition(code_offset);
-
Handle<Script> casted_script(Script::cast(script), this);
- *target = MessageLocation(casted_script, pos, pos + 1);
+ if (shared->HasBytecodeArray() &&
+ shared->GetBytecodeArray()->HasSourcePositionTable()) {
+ int pos = abstract_code->SourcePosition(code_offset);
+ *target = MessageLocation(casted_script, pos, pos + 1, shared);
+ } else {
+ *target = MessageLocation(casted_script, shared, code_offset);
+ }
+
return true;
}
}
@@ -2278,8 +2288,13 @@
HandleScope scope(this);
Handle<JSMessageObject> message(JSMessageObject::cast(message_obj), this);
Handle<Script> script(message->script(), this);
- int start_pos = message->start_position();
- int end_pos = message->end_position();
+ // Clear the exception and restore it afterwards, otherwise
+ // CollectSourcePositions will abort.
+ clear_pending_exception();
+ JSMessageObject::EnsureSourcePositionsAvailable(this, message);
+ set_pending_exception(exception);
+ int start_pos = message->GetStartPosition();
+ int end_pos = message->GetEndPosition();
MessageLocation location(script, start_pos, end_pos);
MessageHandler::ReportMessage(this, &location, message);
}
diff --git a/src/messages.cc b/src/messages.cc
index cf63346..b7ee1d2 100644
--- a/src/messages.cc
+++ b/src/messages.cc
@@ -24,14 +24,30 @@
MessageLocation::MessageLocation(Handle<Script> script, int start_pos,
int end_pos)
- : script_(script), start_pos_(start_pos), end_pos_(end_pos) {}
+ : script_(script),
+ start_pos_(start_pos),
+ end_pos_(end_pos),
+ bytecode_offset_(-1) {}
+
MessageLocation::MessageLocation(Handle<Script> script, int start_pos,
int end_pos, Handle<SharedFunctionInfo> shared)
: script_(script),
start_pos_(start_pos),
end_pos_(end_pos),
+ bytecode_offset_(-1),
shared_(shared) {}
-MessageLocation::MessageLocation() : start_pos_(-1), end_pos_(-1) {}
+
+MessageLocation::MessageLocation(Handle<Script> script,
+ Handle<SharedFunctionInfo> shared,
+ int bytecode_offset)
+ : script_(script),
+ start_pos_(-1),
+ end_pos_(-1),
+ bytecode_offset_(bytecode_offset),
+ shared_(shared) {}
+
+MessageLocation::MessageLocation()
+ : start_pos_(-1), end_pos_(-1), bytecode_offset_(-1) {}
// If no message listeners have been registered this one is called
// by default.
@@ -59,11 +75,15 @@
int start = -1;
int end = -1;
+ int bytecode_offset = -1;
Handle<Script> script_handle = isolate->factory()->empty_script();
+ Handle<SharedFunctionInfo> shared_info;
if (location != nullptr) {
start = location->start_pos();
end = location->end_pos();
script_handle = location->script();
+ bytecode_offset = location->bytecode_offset();
+ shared_info = location->shared();
}
Handle<Object> stack_frames_handle = stack_frames.is_null()
@@ -71,7 +91,8 @@
: Handle<Object>::cast(stack_frames);
Handle<JSMessageObject> message_obj = factory->NewJSMessageObject(
- message, argument, start, end, script_handle, stack_frames_handle);
+ message, argument, start, end, shared_info, bytecode_offset,
+ script_handle, stack_frames_handle);
return message_obj;
}
diff --git a/src/messages.h b/src/messages.h
index af45b16..386104f 100644
--- a/src/messages.h
+++ b/src/messages.h
@@ -33,20 +33,29 @@
class V8_EXPORT_PRIVATE MessageLocation {
public:
+ // Constructors for when source positions are already known.
+ // TODO(delphick): Collapse to a single constructor with a default parameter
+ // when we stop using the GCC that requires this separation.
MessageLocation(Handle<Script> script, int start_pos, int end_pos);
MessageLocation(Handle<Script> script, int start_pos, int end_pos,
Handle<SharedFunctionInfo> shared);
+ // Constructor for when source positions were not collected but which can be
+ // reconstructed from the SharedFuncitonInfo and bytecode offset.
+ MessageLocation(Handle<Script> script, Handle<SharedFunctionInfo> shared,
+ int bytecode_offset);
MessageLocation();
Handle<Script> script() const { return script_; }
int start_pos() const { return start_pos_; }
int end_pos() const { return end_pos_; }
+ int bytecode_offset() const { return bytecode_offset_; }
Handle<SharedFunctionInfo> shared() const { return shared_; }
private:
Handle<Script> script_;
int start_pos_;
int end_pos_;
+ int bytecode_offset_;
Handle<SharedFunctionInfo> shared_;
};
diff --git a/src/objects.cc b/src/objects.cc
index b3c7fbf..634f8e2 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -21,6 +21,7 @@
#include "src/ast/ast.h"
#include "src/ast/scopes.h"
#include "src/base/bits.h"
+#include "src/base/debug/stack_trace.h"
#include "src/base/overflowing-math.h"
#include "src/base/utils/random-number-generator.h"
#include "src/bootstrapper.h"
@@ -5571,6 +5572,13 @@
}
}
+bool SharedFunctionInfo::AreSourcePositionsAvailable() const {
+ if (FLAG_enable_lazy_source_positions) {
+ return !HasBytecodeArray() || GetBytecodeArray()->HasSourcePositionTable();
+ }
+ return true;
+}
+
// static
void SharedFunctionInfo::EnsureSourcePositionsAvailable(
Isolate* isolate, Handle<SharedFunctionInfo> shared_info) {
diff --git a/src/objects/js-objects-inl.h b/src/objects/js-objects-inl.h
index 096a84c..1018565 100644
--- a/src/objects/js-objects-inl.h
+++ b/src/objects/js-objects-inl.h
@@ -717,16 +717,34 @@
ACCESSORS(JSDate, min, Object, kMinOffset)
ACCESSORS(JSDate, sec, Object, kSecOffset)
+bool JSMessageObject::DidEnsureSourcePositionsAvailable() const {
+ return shared_info()->IsUndefined();
+}
+
+int JSMessageObject::GetStartPosition() const {
+ DCHECK(DidEnsureSourcePositionsAvailable());
+ return start_position();
+}
+
+int JSMessageObject::GetEndPosition() const {
+ DCHECK(DidEnsureSourcePositionsAvailable());
+ return end_position();
+}
+
MessageTemplate JSMessageObject::type() const {
Object value = READ_FIELD(*this, kMessageTypeOffset);
return MessageTemplateFromInt(Smi::ToInt(value));
}
+
void JSMessageObject::set_type(MessageTemplate value) {
WRITE_FIELD(*this, kMessageTypeOffset, Smi::FromInt(static_cast<int>(value)));
}
+
ACCESSORS(JSMessageObject, argument, Object, kArgumentsOffset)
ACCESSORS(JSMessageObject, script, Script, kScriptOffset)
ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
+ACCESSORS(JSMessageObject, shared_info, HeapObject, kSharedInfoOffset)
+ACCESSORS(JSMessageObject, bytecode_offset, Smi, kBytecodeOffsetOffset)
SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
SMI_ACCESSORS(JSMessageObject, error_level, kErrorLevelOffset)
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
index cae2d82..b54ba92 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -5786,7 +5786,27 @@
set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
}
+// static
+void JSMessageObject::EnsureSourcePositionsAvailable(
+ Isolate* isolate, Handle<JSMessageObject> message) {
+ if (!message->DidEnsureSourcePositionsAvailable()) {
+ DCHECK_EQ(message->start_position(), -1);
+ DCHECK_GE(message->bytecode_offset()->value(), 0);
+ Handle<SharedFunctionInfo> shared_info(
+ SharedFunctionInfo::cast(message->shared_info()), isolate);
+ SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate, shared_info);
+ DCHECK(shared_info->HasBytecodeArray());
+ int position = shared_info->abstract_code()->SourcePosition(
+ message->bytecode_offset()->value());
+ DCHECK_GE(position, 0);
+ message->set_start_position(position);
+ message->set_end_position(position + 1);
+ message->set_shared_info(ReadOnlyRoots(isolate).undefined_value());
+ }
+}
+
int JSMessageObject::GetLineNumber() const {
+ DCHECK(DidEnsureSourcePositionsAvailable());
if (start_position() == -1) return Message::kNoLineNumberInfo;
Handle<Script> the_script(script(), GetIsolate());
@@ -5802,6 +5822,7 @@
}
int JSMessageObject::GetColumnNumber() const {
+ DCHECK(DidEnsureSourcePositionsAvailable());
if (start_position() == -1) return -1;
Handle<Script> the_script(script(), GetIsolate());
@@ -5826,6 +5847,7 @@
Script::PositionInfo info;
const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
+ DCHECK(DidEnsureSourcePositionsAvailable());
if (!Script::GetPositionInfo(the_script, start_position(), &info,
offset_flag)) {
return isolate->factory()->empty_string();
diff --git a/src/objects/js-objects.h b/src/objects/js-objects.h
index ece2991..d3d7c0e 100644
--- a/src/objects/js-objects.h
+++ b/src/objects/js-objects.h
@@ -1342,23 +1342,30 @@
// [stack_frames]: an array of stack frames for this error object.
DECL_ACCESSORS(stack_frames, Object)
- // [start_position]: the start position in the script for the error message.
- inline int start_position() const;
- inline void set_start_position(int value);
+ // Initializes the source positions in the object if possible. Does nothing if
+ // called more than once. If called when stack space is exhausted, then the
+ // source positions will be not be set and calling it again when there is more
+ // stack space will not have any effect.
+ static void EnsureSourcePositionsAvailable(Isolate* isolate,
+ Handle<JSMessageObject> message);
- // [end_position]: the end position in the script for the error message.
- inline int end_position() const;
- inline void set_end_position(int value);
+ // Gets the start and end positions for the message.
+ // EnsureSourcePositionsAvailable must have been called before calling these.
+ inline int GetStartPosition() const;
+ inline int GetEndPosition() const;
// Returns the line number for the error message (1-based), or
// Message::kNoLineNumberInfo if the line cannot be determined.
+ // EnsureSourcePositionsAvailable must have been called before calling this.
V8_EXPORT_PRIVATE int GetLineNumber() const;
// Returns the offset of the given position within the containing line.
+ // EnsureSourcePositionsAvailable must have been called before calling this.
V8_EXPORT_PRIVATE int GetColumnNumber() const;
// Returns the source code line containing the given source
// position, or the empty string if the position is invalid.
+ // EnsureSourcePositionsAvailable must have been called before calling this.
Handle<String> GetSourceLine() const;
inline int error_level() const;
@@ -1379,6 +1386,27 @@
kPointerFieldsEndOffset, kSize>;
OBJECT_CONSTRUCTORS(JSMessageObject, JSObject);
+
+ private:
+ friend class Factory;
+
+ inline bool DidEnsureSourcePositionsAvailable() const;
+
+ // [shared]: optional SharedFunctionInfo that can be used to reconstruct the
+ // source position if not available when the message was generated.
+ DECL_ACCESSORS(shared_info, HeapObject)
+
+ // [bytecode_offset]: optional offset using along with |shared| to generation
+ // source positions.
+ DECL_ACCESSORS(bytecode_offset, Smi)
+
+ // [start_position]: the start position in the script for the error message.
+ inline int start_position() const;
+ inline void set_start_position(int value);
+
+ // [end_position]: the end position in the script for the error message.
+ inline int end_position() const;
+ inline void set_end_position(int value);
};
// The [Async-from-Sync Iterator] object
diff --git a/src/objects/shared-function-info.h b/src/objects/shared-function-info.h
index 5d7363d..947bbc7 100644
--- a/src/objects/shared-function-info.h
+++ b/src/objects/shared-function-info.h
@@ -590,6 +590,8 @@
static void EnsureSourcePositionsAvailable(
Isolate* isolate, Handle<SharedFunctionInfo> shared_info);
+ bool AreSourcePositionsAvailable() const;
+
// Hash based on function literal id and script id.
V8_EXPORT_PRIVATE uint32_t Hash();
diff --git a/test/cctest/interpreter/test-interpreter.cc b/test/cctest/interpreter/test-interpreter.cc
index ba247dd..83ca163 100644
--- a/test/cctest/interpreter/test-interpreter.cc
+++ b/test/cctest/interpreter/test-interpreter.cc
@@ -5131,9 +5131,7 @@
CHECK_GT(source_position_table->length(), 0);
}
-// TODO(v8:8510): When an exception is thrown, the top frame still has its
-// source positions collected. Re-enable this test when that is fixed.
-DISABLED_TEST(InterpreterCollectSourcePositions_ThrowFrom1stFrame) {
+TEST(InterpreterCollectSourcePositions_ThrowFrom1stFrame) {
FLAG_enable_lazy_source_positions = true;
HandleAndZoneScope handles;
Isolate* isolate = handles.main_isolate();
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 8f8ffab..fbf0677 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -5048,6 +5048,81 @@
isolate->RemoveMessageListeners(check_message_5b);
}
+namespace {
+
+// Verifies that after throwing an exception the message object is set up in
+// some particular way by calling the supplied |tester| function. The tests that
+// use this purposely test only a single getter as the getter updates the cached
+// state of the object which could affect the results of other functions.
+void CheckMessageAttributes(std::function<void(v8::Local<v8::Context> context,
+ v8::Local<v8::Message> message)>
+ tester) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+
+ TryCatch try_catch(context->GetIsolate());
+ CompileRun(
+ R"javascript(
+ (function() {
+ throw new Error();
+ })();
+ )javascript");
+ CHECK(try_catch.HasCaught());
+
+ v8::Local<v8::Value> error = try_catch.Exception();
+ v8::Local<v8::Message> message =
+ v8::Exception::CreateMessage(context->GetIsolate(), error);
+ CHECK(!message.IsEmpty());
+
+ tester(context.local(), message);
+}
+
+} // namespace
+
+TEST(MessageGetLineNumber) {
+ CheckMessageAttributes(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Message> message) {
+ CHECK_EQ(3, message->GetLineNumber(context).FromJust());
+ });
+}
+
+TEST(MessageGetStartColumn) {
+ CheckMessageAttributes(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Message> message) {
+ CHECK_EQ(14, message->GetStartColumn(context).FromJust());
+ });
+}
+
+TEST(MessageGetEndColumn) {
+ CheckMessageAttributes(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Message> message) {
+ CHECK_EQ(15, message->GetEndColumn(context).FromJust());
+ });
+}
+
+TEST(MessageGetStartPosition) {
+ CheckMessageAttributes(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Message> message) {
+ CHECK_EQ(35, message->GetStartPosition());
+ });
+}
+
+TEST(MessageGetEndPosition) {
+ CheckMessageAttributes(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Message> message) {
+ CHECK_EQ(36, message->GetEndPosition());
+ });
+}
+
+TEST(MessageGetSourceLine) {
+ CheckMessageAttributes(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Message> message) {
+ std::string result(*v8::String::Utf8Value(
+ context->GetIsolate(),
+ message->GetSourceLine(context).ToLocalChecked()));
+ CHECK_EQ(" throw new Error();", result);
+ });
+}
THREADED_TEST(GetSetProperty) {
LocalContext context;
diff --git a/test/cctest/wasm/test-wasm-stack.cc b/test/cctest/wasm/test-wasm-stack.cc
index 303fb75..68c2d8e 100644
--- a/test/cctest/wasm/test-wasm-stack.cc
+++ b/test/cctest/wasm/test-wasm-stack.cc
@@ -86,10 +86,10 @@
printf("loc start: %d, end: %d\n", loc.start_pos(), loc.end_pos());
Handle<JSMessageObject> message = i_isolate->CreateMessage(exc, nullptr);
printf("msg start: %d, end: %d, line: %d, col: %d\n",
- message->start_position(), message->end_position(),
+ message->GetStartPosition(), message->GetEndPosition(),
message->GetLineNumber(), message->GetColumnNumber());
- CHECK_EQ(loc.start_pos(), message->start_position());
- CHECK_EQ(loc.end_pos(), message->end_position());
+ CHECK_EQ(loc.start_pos(), message->GetStartPosition());
+ CHECK_EQ(loc.end_pos(), message->GetEndPosition());
// In the message, the line is 1-based, but the column is 0-based.
CHECK_EQ(topLocation.line_nr, message->GetLineNumber());
CHECK_LE(1, topLocation.column);
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index dd26605..29a8133 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -401,12 +401,6 @@
}], # 'lite_mode or variant == jitless'
##############################################################################
-['lite_mode', {
- # TODO(v8:8510): Tests that currently fail with lazy source positions.
- 'stack-traces-overflow': [SKIP],
-}], # lite_mode
-
-##############################################################################
['is_full_debug', {
# Tests too slow in non-optimized debug mode.
'compiler/regress-9017': [SKIP],