Commit 54e81c35 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Add source position recording for variable loads

This provides more precise source to generated code mapping as variable loads can be handled using IC calls.

R=kmillikin@chromium.org

BUG=v8:1527
TEST=test/message/regress/regress-1527

Review URL: http://codereview.chromium.org//7327038

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8610 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 58d7fb82
......@@ -776,7 +776,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
// IDs for bailouts from optimized code.
ASSERT(prop->obj()->AsVariableProxy() != NULL);
{ AccumulatorValueContext for_object(this);
EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
EmitVariableLoad(prop->obj()->AsVariableProxy());
}
__ push(r0);
......@@ -1113,7 +1113,7 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
Comment cmnt(masm_, "[ VariableProxy");
EmitVariableLoad(expr->var());
EmitVariableLoad(expr);
}
......@@ -1262,7 +1262,11 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
}
void FullCodeGenerator::EmitVariableLoad(Variable* var) {
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
// Record position before possible IC call.
SetSourcePosition(proxy->position());
Variable* var = proxy->var();
// Three cases: non-this global variables, lookup slots, and all other
// types of slots.
Slot* slot = var->AsSlot();
......@@ -1593,7 +1597,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
{ AccumulatorValueContext context(this);
switch (assign_type) {
case VARIABLE:
EmitVariableLoad(expr->target()->AsVariableProxy()->var());
EmitVariableLoad(expr->target()->AsVariableProxy());
PrepareForBailout(expr->target(), TOS_REG);
break;
case NAMED_PROPERTY:
......@@ -3816,7 +3820,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
if (assign_type == VARIABLE) {
ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
AccumulatorValueContext context(this);
EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
EmitVariableLoad(expr->expression()->AsVariableProxy());
} else {
// Reserve space for result of postfix operation.
if (expr->is_postfix() && !context()->IsEffect()) {
......
......@@ -444,7 +444,7 @@ class FullCodeGenerator: public AstVisitor {
TypeofState typeof_state,
Label* slow,
Label* done);
void EmitVariableLoad(Variable* expr);
void EmitVariableLoad(VariableProxy* proxy);
enum ResolveEvalFlag {
SKIP_CONTEXT_LOOKUP,
......
......@@ -744,7 +744,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
// IDs for bailouts from optimized code.
ASSERT(prop->obj()->AsVariableProxy() != NULL);
{ AccumulatorValueContext for_object(this);
EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
EmitVariableLoad(prop->obj()->AsVariableProxy());
}
__ push(eax);
......@@ -1064,7 +1064,7 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
Comment cmnt(masm_, "[ VariableProxy");
EmitVariableLoad(expr->var());
EmitVariableLoad(expr);
}
......@@ -1214,7 +1214,11 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
}
void FullCodeGenerator::EmitVariableLoad(Variable* var) {
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
// Record position before possible IC call.
SetSourcePosition(proxy->position());
Variable* var = proxy->var();
// Three cases: non-this global variables, lookup slots, and all other
// types of slots.
Slot* slot = var->AsSlot();
......@@ -1540,7 +1544,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
{ AccumulatorValueContext context(this);
switch (assign_type) {
case VARIABLE:
EmitVariableLoad(expr->target()->AsVariableProxy()->var());
EmitVariableLoad(expr->target()->AsVariableProxy());
PrepareForBailout(expr->target(), TOS_REG);
break;
case NAMED_PROPERTY:
......@@ -1769,7 +1773,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
ASSERT(prop->obj()->AsVariableProxy() != NULL);
ASSERT(prop->key()->AsLiteral() != NULL);
{ AccumulatorValueContext for_object(this);
EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
EmitVariableLoad(prop->obj()->AsVariableProxy());
}
__ mov(edx, eax);
__ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle()));
......@@ -3768,7 +3772,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
if (assign_type == VARIABLE) {
ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
AccumulatorValueContext context(this);
EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
EmitVariableLoad(expr->expression()->AsVariableProxy());
} else {
// Reserve space for result of postfix operation.
if (expr->is_postfix() && !context()->IsEffect()) {
......
......@@ -783,7 +783,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
// IDs for bailouts from optimized code.
ASSERT(prop->obj()->AsVariableProxy() != NULL);
{ AccumulatorValueContext for_object(this);
EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
EmitVariableLoad(prop->obj()->AsVariableProxy());
}
__ push(result_register());
......@@ -1117,7 +1117,7 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
Comment cmnt(masm_, "[ VariableProxy");
EmitVariableLoad(expr->var());
EmitVariableLoad(expr);
}
......@@ -1262,7 +1262,11 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
}
void FullCodeGenerator::EmitVariableLoad(Variable* var) {
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
// Record position before possible IC call.
SetSourcePosition(proxy->position());
Variable* var = proxy->var();
// Three cases: non-this global variables, lookup slots, and all other
// types of slots.
Slot* slot = var->AsSlot();
......@@ -1598,7 +1602,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
{ AccumulatorValueContext context(this);
switch (assign_type) {
case VARIABLE:
EmitVariableLoad(expr->target()->AsVariableProxy()->var());
EmitVariableLoad(expr->target()->AsVariableProxy());
PrepareForBailout(expr->target(), TOS_REG);
break;
case NAMED_PROPERTY:
......@@ -3839,7 +3843,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
if (assign_type == VARIABLE) {
ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
AccumulatorValueContext context(this);
EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
EmitVariableLoad(expr->expression()->AsVariableProxy());
} else {
// Reserve space for result of postfix operation.
if (expr->is_postfix() && !context()->IsEffect()) {
......
......@@ -741,7 +741,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
// IDs for bailouts from optimized code.
ASSERT(prop->obj()->AsVariableProxy() != NULL);
{ AccumulatorValueContext for_object(this);
EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
EmitVariableLoad(prop->obj()->AsVariableProxy());
}
__ push(rax);
VisitForAccumulatorValue(function);
......@@ -1071,7 +1071,7 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
Comment cmnt(masm_, "[ VariableProxy");
EmitVariableLoad(expr->var());
EmitVariableLoad(expr);
}
......@@ -1222,7 +1222,11 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
}
void FullCodeGenerator::EmitVariableLoad(Variable* var) {
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
// Record position before possible IC call.
SetSourcePosition(proxy->position());
Variable* var = proxy->var();
// Three cases: non-this global variables, lookup slots, and all other
// types of slots.
Slot* slot = var->AsSlot();
......@@ -1548,7 +1552,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
{ AccumulatorValueContext context(this);
switch (assign_type) {
case VARIABLE:
EmitVariableLoad(expr->target()->AsVariableProxy()->var());
EmitVariableLoad(expr->target()->AsVariableProxy());
PrepareForBailout(expr->target(), TOS_REG);
break;
case NAMED_PROPERTY:
......@@ -3746,7 +3750,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
if (assign_type == VARIABLE) {
ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
AccumulatorValueContext context(this);
EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
EmitVariableLoad(expr->expression()->AsVariableProxy());
} else {
// Reserve space for result of postfix operation.
if (expr->is_postfix() && !context()->IsEffect()) {
......
......@@ -12633,9 +12633,10 @@ v8::Handle<Value> AnalyzeStackInNativeCode(const v8::Arguments& args) {
stackTrace->GetFrame(0));
checkStackFrame(origin, "foo", 6, 3, false, false,
stackTrace->GetFrame(1));
checkStackFrame(NULL, "", 1, 1, false, false,
// This is the source string inside the eval which has the call to foo.
checkStackFrame(NULL, "", 1, 5, false, false,
stackTrace->GetFrame(2));
// The last frame is an anonymous function that has the initial call.
// The last frame is an anonymous function which has the initial eval call.
checkStackFrame(origin, "", 8, 7, false, false,
stackTrace->GetFrame(3));
......@@ -12654,9 +12655,10 @@ v8::Handle<Value> AnalyzeStackInNativeCode(const v8::Arguments& args) {
bool is_eval = false;
#endif // ENABLE_DEBUGGER_SUPPORT
checkStackFrame(NULL, "", 1, 1, is_eval, false,
// This is the source string inside the eval which has the call to baz.
checkStackFrame(NULL, "", 1, 5, is_eval, false,
stackTrace->GetFrame(2));
// The last frame is an anonymous function that has the initial call to foo.
// The last frame is an anonymous function which has the initial eval call.
checkStackFrame(origin, "", 10, 1, false, false,
stackTrace->GetFrame(3));
......
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
var o1 = {foo: 'bar'};
var o2 = {
1: 'blah',
2: o1.foo,
3: foo
}
# Copyright 2011 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*%(basename)s:32: ReferenceError: foo is not defined
3: foo
^
ReferenceError: foo is not defined
at *%(basename)s:32:6
......@@ -195,7 +195,7 @@ function listener(event, exec_state, event_data, data) {
assertEquals("m", response.lookup(frame.func.ref).inferredName);
assertFalse(frame.constructCall);
assertEquals(35, frame.line);
assertEquals(2, frame.column);
assertEquals(6, frame.column);
assertEquals(0, frame.arguments.length);
json = '{"seq":0,"type":"request","command":"frame","arguments":{"number":3}}'
......@@ -269,4 +269,3 @@ g();
// Make sure that the debug event listener vas invoked.
assertFalse(exception, "exception in listener");
assertTrue(listenerCalled);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment