Reviewers: Yang, rossberg, ulan,
Description:
Introduce Runtime_GetAllScopesDetails to get all scopes at once for a frame.
This will reduce heavy ScopeIterator instantiations.
Once incorporated into chromium, will give 30% speed boost.
BUG=chromium:340285
R=Yang, ulan, rossberg
Please review this at https://codereview.chromium.org/181063008/
SVN Base: git://github.com/v8/v8.git@master
Affected files (+73, -5 lines):
M src/mirror-debugger.js
M src/runtime.h
M src/runtime.cc
M test/mjsunit/debug-scopes.js
Index: src/mirror-debugger.js
diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js
index
212bb0b9cac370b734011add6baa5a95fef593b5..6182d9de15b764d7e8a73c88685ca8f50d847cd2
100644
--- a/src/mirror-debugger.js
+++ b/src/mirror-debugger.js
@@ -1675,6 +1675,18 @@ FrameMirror.prototype.scope = function(index) {
};
+FrameMirror.prototype.allScopes = function() {
+ var scopeDetails = %GetAllScopesDetails(this.break_id_,
+ this.details_.frameId(),
+
this.details_.inlinedFrameIndex());
+ var result = [];
+ for (var i = 0; i < scopeDetails.length; ++i) {
+ result.push(new ScopeMirror(this, UNDEFINED, i, scopeDetails[i]));
+ }
+ return result;
+};
+
+
FrameMirror.prototype.stepInPositions = function() {
var script = this.func().script();
var funcOffset = this.func().sourcePosition_();
@@ -1865,17 +1877,18 @@ FrameMirror.prototype.toText = function(opt_locals)
{
var kScopeDetailsTypeIndex = 0;
var kScopeDetailsObjectIndex = 1;
-function ScopeDetails(frame, fun, index) {
+function ScopeDetails(frame, fun, index, opt_details) {
if (frame) {
this.break_id_ = frame.break_id_;
- this.details_ = %GetScopeDetails(frame.break_id_,
+ this.details_ = opt_details ||
+ %GetScopeDetails(frame.break_id_,
frame.details_.frameId(),
frame.details_.inlinedFrameIndex(),
index);
this.frame_id_ = frame.details_.frameId();
this.inlined_frame_id_ = frame.details_.inlinedFrameIndex();
} else {
- this.details_ = %GetFunctionScopeDetails(fun.value(), index);
+ this.details_ = opt_details || %GetFunctionScopeDetails(fun.value(),
index);
this.fun_value_ = fun.value();
this.break_id_ = undefined;
}
@@ -1921,10 +1934,11 @@ ScopeDetails.prototype.setVariableValueImpl =
function(name, new_value) {
* @param {FrameMirror} frame The frame this scope is a part of
* @param {FunctionMirror} function The function this scope is a part of
* @param {number} index The scope index in the frame
+ * @param {Array=} opt_details Raw scope details data
* @constructor
* @extends Mirror
*/
-function ScopeMirror(frame, function, index) {
+function ScopeMirror(frame, function, index, opt_details) {
%_CallFunction(this, SCOPE_TYPE, Mirror);
if (frame) {
this.frame_index_ = frame.index_;
@@ -1932,7 +1946,7 @@ function ScopeMirror(frame, function, index) {
this.frame_index_ = undefined;
}
this.scope_index_ = index;
- this.details_ = new ScopeDetails(frame, function, index);
+ this.details_ = new ScopeDetails(frame, function, index, opt_details);
}
inherits(ScopeMirror, Mirror);
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index
0caaa47bd57f79ba52b8b46959a590c9fe918041..d8448d80322be527bdfa12c8ab058ceb5e6fdabb
100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -12298,6 +12298,48 @@ RUNTIME_FUNCTION(MaybeObject*,
Runtime_GetScopeDetails) {
}
+// Return an array of scope details
+// args[0]: number: break id
+// args[1]: number: frame index
+// args[2]: number: inlined frame index
+//
+// The array returned contains arrays with the following information:
+// 0: Scope type
+// 1: Scope object
+RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAllScopesDetails) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 3);
+
+ // Check arguments.
+ Object* check;
+ { MaybeObject* maybe_check = Runtime_CheckExecutionState(
+ RUNTIME_ARGUMENTS(isolate, args));
+ if (!maybe_check->ToObject(&check)) return maybe_check;
+ }
+ CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
+ CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
+
+ // Get the frame where the debugging is performed.
+ StackFrame::Id id = UnwrapFrameId(wrapped_id);
+ JavaScriptFrameIterator frame_it(isolate, id);
+ JavaScriptFrame* frame = frame_it.frame();
+
+ List<Handle<Object> > result(4);
+ ScopeIterator it(isolate, frame, inlined_jsframe_index);
+ for (; !it.Done(); it.Next()) {
+ MaybeObject* maybe_object = MaterializeScopeDetails(isolate, &it);
+ if (maybe_object->IsFailure()) return maybe_object;
+ result.Add(handle(maybe_object->ToObjectUnchecked(), isolate));
+ }
+
+ Handle<FixedArray> array =
isolate->factory()->NewFixedArray(result.length());
+ for (int i = 0; i < result.length(); ++i) {
+ array->set(i, *result[i]);
+ }
+ return *isolate->factory()->NewJSArrayWithElements(array);
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeCount) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
Index: src/runtime.h
diff --git a/src/runtime.h b/src/runtime.h
index
823285fd37661bad76a15483a06cc104b680512b..7360097e41089cbf4c904b3ea071d9446e48346e
100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -505,6 +505,7 @@ namespace internal {
F(GetScopeCount, 2, 1) \
F(GetStepInPositions, 2, 1) \
F(GetScopeDetails, 4, 1) \
+ F(GetAllScopesDetails, 3, 1) \
F(GetFunctionScopeCount, 1, 1) \
F(GetFunctionScopeDetails, 2, 1) \
F(SetScopeVariableValue, 6, 1) \
Index: test/mjsunit/debug-scopes.js
diff --git a/test/mjsunit/debug-scopes.js b/test/mjsunit/debug-scopes.js
index
942bd2bb073804571bf39b01db88b07d25f44479..57adf236ffbafb3adaf463cfafd5ae7a167aa121
100644
--- a/test/mjsunit/debug-scopes.js
+++ b/test/mjsunit/debug-scopes.js
@@ -76,13 +76,24 @@ function EndTest() {
}
+// Check that two scope are the same.
+function CheckScopeMirrors(scope1, scope2) {
+ assertEquals(scope1.scopeType(), scope2.scopeType());
+ assertEquals(scope1.frameIndex(), scope2.frameIndex());
+ assertEquals(scope1.scopeIndex(), scope2.scopeIndex());
+}
+
+
// Check that the scope chain contains the expected types of scopes.
function CheckScopeChain(scopes, exec_state) {
+ var all_scopes = exec_state.frame().allScopes();
assertEquals(scopes.length, exec_state.frame().scopeCount());
+ assertEquals(scopes.length, all_scopes.length, "FrameMirror.allScopes
length");
for (var i = 0; i < scopes.length; i++) {
var scope = exec_state.frame().scope(i);
assertTrue(scope.isScope());
assertEquals(scopes[i], scope.scopeType());
+ CheckScopeMirrors(all_scopes[i], scope);
// Check the global object when hitting the global scope.
if (scopes[i] == debug.ScopeType.Global) {
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.