Diff
Modified: trunk/LayoutTests/ChangeLog (176478 => 176479)
--- trunk/LayoutTests/ChangeLog 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/LayoutTests/ChangeLog 2014-11-21 23:41:26 UTC (rev 176479)
@@ -1,3 +1,20 @@
+2014-11-21 Michael Saboff <msab...@apple.com>
+
+ Allocate local ScopeChain register
+ https://bugs.webkit.org/show_bug.cgi?id=138793
+
+ Reviewed by Geoffrey Garen.
+
+ New test that sets a breakpoint in a callee of a DFG caller. While stopped in the
+ breakpoint, it modifies a global via the scope chain of the DFG caller as well as
+ a local of the DFG caller.
+
+ * inspector-protocol/debugger/resources/breakpoint.js:
+ (notInlineable3):
+ (dfgWithoutInline3):
+ * inspector-protocol/debugger/setBreakpoint-dfg-callee-and-examine-dfg-local-expected.txt: Added.
+ * inspector-protocol/debugger/setBreakpoint-dfg-callee-and-examine-dfg-local.html: Added.
+
2014-11-21 Glenn Adams <gl...@skynav.com> and Myles C. Maxfield <mmaxfi...@apple.com>
CSS3: line-break property support
Modified: trunk/LayoutTests/inspector-protocol/debugger/resources/breakpoint.js (176478 => 176479)
--- trunk/LayoutTests/inspector-protocol/debugger/resources/breakpoint.js 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/LayoutTests/inspector-protocol/debugger/resources/breakpoint.js 2014-11-21 23:41:26 UTC (rev 176479)
@@ -91,3 +91,25 @@
return x + 3;
}
+function notInlineable3(x)
+{
+ var func = new Function("return x + 100;");
+ if (x == 1999)
+ breakpointBasic();
+ return x + 3;
+}
+
+var globalVal3 = 0;
+
+function dfgWithoutInline3()
+{
+ globalVal3 = 0;
+ var i;
+ var result = 0;
+ var localVal3 = 0;
+ for (i = 0; i < 2000; i++)
+ result += notInlineable3(i);
+ if (globalVal3)
+ result = globalVal3 + localVal3;
+ log("result: " + result);
+}
Added: trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-dfg-callee-and-examine-dfg-local-expected.txt (0 => 176479)
--- trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-dfg-callee-and-examine-dfg-local-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-dfg-callee-and-examine-dfg-local-expected.txt 2014-11-21 23:41:26 UTC (rev 176479)
@@ -0,0 +1,20 @@
+Debugger.evaluateOnCallFrame in a DFG compiled function from a breakpoint in a non-DFG callee.
+
+Found breakpoint.js
+inside breakpointBasic
+result: 2005000
+dfg function warmed up
+
+Breakpoint set in breakpointBasic()
+Hit Breakpoint!
+Evaluating in DFG frame at frame[2]: 'globalVal3 = 30;'
+Response value is 30
+Evaluating in DFG frame at frame[2]: 'localVal3 = 12;'
+Response value is 12
+Evaluating in DFG frame at frame[2]: 'localVal3'
+Response value is 12
+Resumed from breakpoint
+inside breakpointBasic
+result: 42
+Test complete
+
Added: trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-dfg-callee-and-examine-dfg-local.html (0 => 176479)
--- trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-dfg-callee-and-examine-dfg-local.html (rev 0)
+++ trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-dfg-callee-and-examine-dfg-local.html 2014-11-21 23:41:26 UTC (rev 176479)
@@ -0,0 +1,113 @@
+<html>
+<head>
+<script src=""
+<script src=""
+
+<script>
+// Put this here instead of on <body onload> to prevent an extra Debugger.scriptParsed event.
+window._onload_ = runTest;
+
+function test()
+{
+ // This test setting a breakpoints in DFG compiled functions callee and then modify
+ // and examine a global and local via the DFG frame.
+
+ InspectorTest.sendCommand("Debugger.enable", {});
+
+ var breakpointId = null;
+ var scriptId = 0;
+ var startLine = 0;
+
+ InspectorTest.eventHandler["Debugger.scriptParsed"] = function(messageObject)
+ {
+ if (/resources\/breakpoint\.js$/.test(messageObject.params.url)) {
+ InspectorTest.log("Found breakpoint.js");
+ scriptId = messageObject.params.scriptId;
+ startLine = messageObject.params.startLine;
+
+ InspectorTest.sendCommand("Runtime.evaluate", {
+ _expression_: "dfgWithoutInline3();"
+ }, function(responseObject) {
+ InspectorTest.log("dfg function warmed up\n");
+
+ var location1 = {scriptId: scriptId, lineNumber: 2, columnNumber: 0};
+
+ InspectorTest.sendCommand("Debugger.setBreakpoint", {location: location1}, function(responseObject) {
+ InspectorTest.checkForError(responseObject);
+ InspectorTest.log("Breakpoint set in breakpointBasic()");
+
+ breakpointId = responseObject.result.breakpointId;
+ InspectorTest.sendCommand("Runtime.evaluate", {
+ _expression_: "dfgWithoutInline3();"
+ }, function(responseObject) {
+ InspectorTest.log("Test complete");
+ InspectorTest.completeTest();
+ });
+ });
+ });
+ }
+ }
+
+ InspectorTest.eventHandler["Debugger.paused"] = function(messageObject)
+ {
+ function dumpResponse(response)
+ {
+ try {
+ if (response.result.wasThrown) {
+ InspectorTest.log("Exception thrown processing request");
+ return false;
+ }
+ InspectorTest.log("Response value is " + response.result.result.value);
+ return true;
+ } catch (e) {
+ return false;
+ }
+ }
+
+ function resumeFromBreakpoint()
+ {
+ InspectorTest.sendCommand("Debugger.resume", {}, function(responseObject) {
+ InspectorTest.log("Resumed from breakpoint");
+ });
+ }
+
+ InspectorTest.log("Hit Breakpoint!");
+ var callFrames = messageObject.params.callFrames;
+ if (callFrames.length < 3) {
+ InspectorTest.log("FAIL: too few frames in stack trace");
+ resumeFromBreakpoint();
+ return;
+ }
+ var callFrameId = callFrames[2].callFrameId;
+ InspectorTest.log("Evaluating in DFG frame at frame[2]: 'globalVal3 = 30;'");
+ InspectorTest.sendCommand("Debugger.evaluateOnCallFrame", { callFrameId: callFrameId, _expression_: "globalVal3 = 30;" }, function(responseObject) {
+ if (!dumpResponse(responseObject)) {
+ resumeFromBreakpoint();
+ return;
+ }
+ InspectorTest.log("Evaluating in DFG frame at frame[2]: 'localVal3 = 12;'");
+ InspectorTest.sendCommand("Debugger.evaluateOnCallFrame", { callFrameId: callFrameId, _expression_: "localVal3 = 12;" }, function(responseObject) {
+ if (!dumpResponse(responseObject)) {
+ resumeFromBreakpoint();
+ return;
+ }
+ InspectorTest.log("Evaluating in DFG frame at frame[2]: 'localVal3'");
+ InspectorTest.sendCommand("Debugger.evaluateOnCallFrame", { callFrameId: callFrameId, _expression_: "localVal3" }, function(responseObject) {
+ if (!dumpResponse(responseObject)) {
+ resumeFromBreakpoint();
+ return;
+ }
+ InspectorTest.sendCommand("Debugger.resume", {}, function(responseObject) {
+ InspectorTest.log("Resumed from breakpoint");
+ });
+ });
+ });
+ });
+ }
+}
+</script>
+</head>
+<body>
+<p>Debugger.evaluateOnCallFrame in a DFG compiled function from a breakpoint in a non-DFG callee.</p>
+</body>
+</html>
Modified: trunk/Source/_javascript_Core/ChangeLog (176478 => 176479)
--- trunk/Source/_javascript_Core/ChangeLog 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/ChangeLog 2014-11-21 23:41:26 UTC (rev 176479)
@@ -1,3 +1,104 @@
+2014-11-21 Michael Saboff <msab...@apple.com>
+
+ Allocate local ScopeChain register
+ https://bugs.webkit.org/show_bug.cgi?id=138793
+
+ Reviewed by Geoffrey Garen.
+
+ Now we allocate the scope register as a local. The allocated register is stored in the
+ CodeBlock for use by other components. Update the DFG to work with a local scope register.
+ Changed usage of JSStack::ScopeChain access to the CallFrame header to use the allocated
+ local register.
+
+ * bytecode/BytecodeUseDef.h:
+ (JSC::computeUsesForBytecodeOffset):
+ (JSC::computeDefsForBytecodeOffset):
+ Updated to properly represent the operand inputs and bytecode result.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::setScopeRegister):
+ (JSC::CodeBlock::scopeRegister):
+ * bytecode/UnlinkedCodeBlock.h:
+ (JSC::UnlinkedCodeBlock::setScopeRegister):
+ (JSC::UnlinkedCodeBlock::scopeRegister):
+ Added scope register member and accessors.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::allocateAndEmitScope):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::scopeRegister):
+ Change m_scopeRegister to an allocated register. Added allocateAndEmitScope helper to
+ allocate the scope register, set the CodeBlock with its value and emit op_get_scope.
+
+ * debugger/DebuggerCallFrame.cpp:
+ (JSC::DebuggerCallFrame::scope): Changed to access the scope using the new convention.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::get):
+ (JSC::DFG::ByteCodeParser::flush):
+ (JSC::DFG::ByteCodeParser::inlineCall):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ Changed op_create_lexical_environment to set the scope VirtualRegister operand.
+ Filled out op_get_scope processing to emit a GetScope node putting the result in
+ the scope VirtualRegister result operand.
+ Added Phantoms where appropriate to keep the Scope register alive in places where
+ it use is optimized away, but where the baseline JIT would need to use its value.
+ Eliminated uses of JSStack::ScopeChain.
+
+ * dfg/DFGStackLayoutPhase.cpp:
+ (JSC::DFG::StackLayoutPhase::run):
+ Make sure that the scope register stack location is allocated using the same place
+ that the codeBlock expects.
+
+ * dfg/DFGStrengthReductionPhase.cpp:
+ (JSC::DFG::StrengthReductionPhase::handleNode):
+ Allow strength reduction of Flush to skip of GetScope nodes looking for a prior
+ corresponding SetLocal.
+
+ * interpreter/CallFrame.h:
+ (JSC::ExecState::scope):
+ (JSC::ExecState::setScope):
+ Added new scope() and setScope() helpers that take a VirtualRegister offset.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::eval):
+ Changed eval() to get the scope from the caller's scope register instead of from the
+ temporary frame created for eval.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::unwind):
+ Changed unwind() to manipulate the scope n the allocated register instead of from the
+ call frame slot.
+
+ * interpreter/StackVisitor.cpp:
+ (JSC::StackVisitor::readNonInlinedFrame):
+ (JSC::StackVisitor::readInlinedFrame):
+ * interpreter/StackVisitor.h:
+ (JSC::StackVisitor::Frame::callee):
+ (JSC::StackVisitor::Frame::scope): Deleted.
+ Eliminated the scope member as it needed to change and no StackVisitor users use it.
+
+ * jit/JITOperations.cpp:
+ (JSC::operationPushNameScope):
+ (JSC::operationPushWithScope):
+ * runtime/JSNameScope.h:
+ (JSC::JSNameScope::create):
+ * runtime/JSWithScope.h:
+ (JSC::JSWithScope::create): Deleted.
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ Deleted JSNameScope::create() and JSWithScope::create() flavors tht used the ScopeChain slot
+ in the CallFrame header. Changed the only user of these function, op_push_name_scope and
+ op_push_with_scope helpers, to use the remaining create variants that require explicit scope.
+ Those operations get the scope from the register pointed to by their scope operands.
+
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ Changed resolveScope to use the allocated register.
+
2014-11-21 Csaba Osztrogonác <o...@webkit.org>
[JSC] Disable verifyHeap
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h (176478 => 176479)
--- trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h 2014-11-21 23:41:26 UTC (rev 176479)
@@ -44,10 +44,7 @@
case op_new_array_buffer:
case op_throw_static_error:
case op_debug:
- case op_resolve_scope:
- case op_pop_scope:
case op_jneq_ptr:
- case op_new_func_exp:
case op_loop_hint:
case op_jmp:
case op_new_object:
@@ -57,16 +54,15 @@
case op_catch:
case op_touch_entry:
return;
- case op_new_func:
- case op_create_lexical_environment:
+ case op_create_lexical_environment:
case op_get_scope:
case op_create_arguments:
case op_to_this:
+ case op_pop_scope:
case op_profile_will_call:
case op_profile_did_call:
case op_profile_type:
case op_throw:
- case op_push_with_scope:
case op_end:
case op_ret:
case op_jtrue:
@@ -78,6 +74,7 @@
functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
return;
}
+ case op_new_func:
case op_ret_object_or_this:
case op_jlesseq:
case op_jgreater:
@@ -117,10 +114,13 @@
return;
}
case op_get_enumerable_length:
+ case op_new_func_exp:
case op_to_index_string:
case op_init_global_const_nop:
case op_init_global_const:
case op_push_name_scope:
+ case op_push_with_scope:
+ case op_resolve_scope:
case op_get_from_scope:
case op_to_primitive:
case op_get_by_id:
@@ -244,10 +244,7 @@
// These don't define anything.
case op_init_global_const:
case op_init_global_const_nop:
- case op_push_name_scope:
- case op_push_with_scope:
case op_put_to_scope:
- case op_pop_scope:
case op_end:
case op_profile_will_call:
case op_profile_did_call:
@@ -301,6 +298,9 @@
case op_get_direct_pname:
case op_get_structure_property_enumerator:
case op_next_enumerator_pname:
+ case op_pop_scope:
+ case op_push_name_scope:
+ case op_push_with_scope:
case op_resolve_scope:
case op_strcat:
case op_to_primitive:
@@ -365,7 +365,6 @@
case op_to_this:
case op_get_callee:
case op_init_lazy_reg:
- case op_create_lexical_environment:
case op_get_scope:
case op_create_arguments:
case op_del_by_id:
@@ -374,6 +373,11 @@
functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
return;
}
+ case op_create_lexical_environment: {
+ functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
+ functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
+ return;
+ }
case op_enter: {
for (unsigned i = codeBlock->m_numVars; i--;)
functor(codeBlock, instruction, opcodeID, virtualRegisterForLocal(i).offset());
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (176478 => 176479)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2014-11-21 23:41:26 UTC (rev 176479)
@@ -1630,6 +1630,7 @@
, m_vm(other.m_vm)
, m_instructions(other.m_instructions)
, m_thisRegister(other.m_thisRegister)
+ , m_scopeRegister(other.m_scopeRegister)
, m_argumentsRegister(other.m_argumentsRegister)
, m_lexicalEnvironmentRegister(other.m_lexicalEnvironmentRegister)
, m_isStrictMode(other.m_isStrictMode)
@@ -1689,6 +1690,7 @@
, m_ownerExecutable(m_globalObject->vm(), ownerExecutable, ownerExecutable)
, m_vm(unlinkedCodeBlock->vm())
, m_thisRegister(unlinkedCodeBlock->thisRegister())
+ , m_scopeRegister(unlinkedCodeBlock->scopeRegister())
, m_argumentsRegister(unlinkedCodeBlock->argumentsRegister())
, m_lexicalEnvironmentRegister(unlinkedCodeBlock->activationRegister())
, m_isStrictMode(unlinkedCodeBlock->isStrictMode())
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (176478 => 176479)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2014-11-21 23:41:26 UTC (rev 176479)
@@ -323,6 +323,17 @@
bool usesEval() const { return m_unlinkedCode->usesEval(); }
+ void setScopeRegister(VirtualRegister scopeRegister)
+ {
+ m_scopeRegister = scopeRegister;
+ }
+
+ VirtualRegister scopeRegister() const
+ {
+ ASSERT(m_scopeRegister.isValid());
+ return m_scopeRegister;
+ }
+
void setArgumentsRegister(VirtualRegister argumentsRegister)
{
ASSERT(argumentsRegister.isValid());
@@ -340,6 +351,7 @@
return VirtualRegister();
return argumentsRegister();
}
+
void setActivationRegister(VirtualRegister activationRegister)
{
m_lexicalEnvironmentRegister = activationRegister;
@@ -1032,6 +1044,7 @@
RefCountedArray<Instruction> m_instructions;
WriteBarrier<SymbolTable> m_symbolTable;
VirtualRegister m_thisRegister;
+ VirtualRegister m_scopeRegister;
VirtualRegister m_argumentsRegister;
VirtualRegister m_lexicalEnvironmentRegister;
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (176478 => 176479)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2014-11-21 23:41:26 UTC (rev 176479)
@@ -282,6 +282,7 @@
// Special registers
void setThisRegister(VirtualRegister thisRegister) { m_thisRegister = thisRegister; }
+ void setScopeRegister(VirtualRegister scopeRegister) { m_scopeRegister = scopeRegister; }
void setActivationRegister(VirtualRegister activationRegister) { m_lexicalEnvironmentRegister = activationRegister; }
void setArgumentsRegister(VirtualRegister argumentsRegister) { m_argumentsRegister = argumentsRegister; }
@@ -429,6 +430,7 @@
CodeType codeType() const { return m_codeType; }
VirtualRegister thisRegister() const { return m_thisRegister; }
+ VirtualRegister scopeRegister() const { return m_scopeRegister; }
VirtualRegister activationRegister() const { return m_lexicalEnvironmentRegister; }
bool hasActivationRegister() const { return m_lexicalEnvironmentRegister.isValid(); }
@@ -520,6 +522,7 @@
VirtualRegister m_thisRegister;
VirtualRegister m_argumentsRegister;
+ VirtualRegister m_scopeRegister;
VirtualRegister m_lexicalEnvironmentRegister;
VirtualRegister m_globalObjectRegister;
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (176478 => 176479)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2014-11-21 23:41:26 UTC (rev 176479)
@@ -164,7 +164,7 @@
, m_scopeNode(programNode)
, m_codeBlock(vm, codeBlock)
, m_thisRegister(CallFrame::thisArgumentOffset())
- , m_scopeRegister(JSStack::ScopeChain)
+ , m_scopeRegister(0)
, m_lexicalEnvironmentRegister(0)
, m_emptyValueRegister(0)
, m_globalObjectRegister(0)
@@ -190,7 +190,7 @@
emitOpcode(op_enter);
- emitGetScope();
+ allocateAndEmitScope();
const VarStack& varStack = programNode->varStack();
const FunctionStack& functionStack = programNode->functionStack();
@@ -212,7 +212,7 @@
, m_symbolTable(codeBlock->symbolTable())
, m_scopeNode(functionBody)
, m_codeBlock(vm, codeBlock)
- , m_scopeRegister(JSStack::ScopeChain)
+ , m_scopeRegister(0)
, m_lexicalEnvironmentRegister(0)
, m_emptyValueRegister(0)
, m_globalObjectRegister(0)
@@ -251,7 +251,7 @@
emitOpcode(op_enter);
- emitGetScope();
+ allocateAndEmitScope();
if (m_codeBlock->needsFullScopeChain() || m_shouldEmitDebugHooks) {
m_lexicalEnvironmentRegister = addVar();
@@ -452,7 +452,7 @@
, m_scopeNode(evalNode)
, m_codeBlock(vm, codeBlock)
, m_thisRegister(CallFrame::thisArgumentOffset())
- , m_scopeRegister(JSStack::ScopeChain)
+ , m_scopeRegister(0)
, m_lexicalEnvironmentRegister(0)
, m_emptyValueRegister(0)
, m_globalObjectRegister(0)
@@ -479,7 +479,7 @@
emitOpcode(op_enter);
- emitGetScope();
+ allocateAndEmitScope();
const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
for (size_t i = 0; i < functionStack.size(); ++i)
@@ -2218,6 +2218,14 @@
return LabelScopePtr::null();
}
+void BytecodeGenerator::allocateAndEmitScope()
+{
+ m_scopeRegister = addVar();
+ m_scopeRegister->ref();
+ m_codeBlock->setScopeRegister(scopeRegister()->virtualRegister());
+ emitGetScope();
+}
+
void BytecodeGenerator::emitComplexPopScopes(RegisterID* scope, ControlFlowContext* topScope, ControlFlowContext* bottomScope)
{
while (topScope > bottomScope) {
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (176478 => 176479)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2014-11-21 23:41:26 UTC (rev 176479)
@@ -290,7 +290,7 @@
// Returns the register storing "this"
RegisterID* thisRegister() { return &m_thisRegister; }
- RegisterID* scopeRegister() { return &m_scopeRegister; }
+ RegisterID* scopeRegister() { return m_scopeRegister; }
// Returns the next available temporary register. Registers returned by
// newTemporary require a modified form of reference counting: any
@@ -594,6 +594,7 @@
ALWAYS_INLINE void rewindBinaryOp();
ALWAYS_INLINE void rewindUnaryOp();
+ void allocateAndEmitScope();
void emitComplexPopScopes(RegisterID*, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
typedef HashMap<double, JSValue> NumberMap;
@@ -754,7 +755,7 @@
RegisterID m_ignoredResultRegister;
RegisterID m_thisRegister;
RegisterID m_calleeRegister;
- RegisterID m_scopeRegister;
+ RegisterID* m_scopeRegister;
RegisterID* m_lexicalEnvironmentRegister;
RegisterID* m_emptyValueRegister;
RegisterID* m_globalObjectRegister;
Modified: trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp (176478 => 176479)
--- trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp 2014-11-21 23:41:26 UTC (rev 176479)
@@ -143,15 +143,14 @@
if (!m_scope) {
VM& vm = m_callFrame->vm();
+ JSScope* scope;
CodeBlock* codeBlock = m_callFrame->codeBlock();
- if (codeBlock && codeBlock->needsActivation() && !m_callFrame->hasActivation()) {
- ASSERT(!m_callFrame->scope()->isWithScope());
- JSLexicalEnvironment* lexicalEnvironment = JSLexicalEnvironment::create(vm, m_callFrame, codeBlock);
- m_callFrame->setActivation(lexicalEnvironment);
- m_callFrame->setScope(lexicalEnvironment);
- }
+ if (codeBlock && codeBlock->scopeRegister().isValid())
+ scope = m_callFrame->scope(codeBlock->scopeRegister().offset());
+ else
+ scope = jsCast<JSCallee*>(m_callFrame->callee())->scope();
- m_scope.set(vm, DebuggerScope::create(vm, m_callFrame->scope()));
+ m_scope.set(vm, DebuggerScope::create(vm, scope));
}
return m_scope.get();
}
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (176478 => 176479)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2014-11-21 23:41:26 UTC (rev 176479)
@@ -262,13 +262,11 @@
JSFunction* callee = inlineCallFrame()->calleeConstant();
if (operand.offset() == JSStack::Callee)
return weakJSConstant(callee);
- if (operand.offset() == JSStack::ScopeChain)
+ if (operand == m_inlineStackTop->m_codeBlock->scopeRegister())
return weakJSConstant(callee->scope());
}
} else if (operand.offset() == JSStack::Callee)
return addToGraph(GetCallee);
- else if (operand.offset() == JSStack::ScopeChain)
- return addToGraph(GetMyScope);
return getDirect(m_inlineStackTop->remapOperand(operand));
}
@@ -526,10 +524,8 @@
int numArguments;
if (InlineCallFrame* inlineCallFrame = inlineStackEntry->m_inlineCallFrame) {
numArguments = inlineCallFrame->arguments.size();
- if (inlineCallFrame->isClosureCall) {
+ if (inlineCallFrame->isClosureCall)
flushDirect(inlineStackEntry->remapOperand(VirtualRegister(JSStack::Callee)));
- flushDirect(inlineStackEntry->remapOperand(VirtualRegister(JSStack::ScopeChain)));
- }
} else
numArguments = inlineStackEntry->m_codeBlock->numParameters();
for (unsigned argument = numArguments; argument-- > 1;)
@@ -1262,11 +1258,8 @@
if (callee.isClosureCall()) {
VariableAccessData* calleeVariable =
set(VirtualRegister(JSStack::Callee), callTargetNode, ImmediateNakedSet)->variableAccessData();
- VariableAccessData* scopeVariable =
- set(VirtualRegister(JSStack::ScopeChain), addToGraph(GetScope, callTargetNode), ImmediateNakedSet)->variableAccessData();
calleeVariable->mergeShouldNeverUnbox(true);
- scopeVariable->mergeShouldNeverUnbox(true);
inlineVariableData.calleeVariable = calleeVariable;
}
@@ -3195,10 +3188,13 @@
if (lexicalEnvironment
&& lexicalEnvironment->symbolTable()->m_functionEnteredOnce.isStillValid()) {
addToGraph(FunctionReentryWatchpoint, OpInfo(lexicalEnvironment->symbolTable()));
+ addToGraph(Phantom, getDirect(m_inlineStackTop->remapOperand(VirtualRegister(currentInstruction[2].u.operand))));
set(VirtualRegister(dst), weakJSConstant(lexicalEnvironment));
break;
}
set(VirtualRegister(dst), getScope(VirtualRegister(currentInstruction[2].u.operand), depth));
+ if (inlineCallFrame())
+ addToGraph(Phantom, getDirect(m_inlineStackTop->remapOperand(VirtualRegister(currentInstruction[2].u.operand))));
break;
}
case Dynamic:
@@ -3395,11 +3391,14 @@
}
case op_create_lexical_environment: {
- set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CreateActivation, get(VirtualRegister(currentInstruction[1].u.operand))));
+ Node* lexicalEnvironment = addToGraph(CreateActivation, get(VirtualRegister(currentInstruction[1].u.operand)));
+ set(VirtualRegister(currentInstruction[1].u.operand), lexicalEnvironment);
+ set(VirtualRegister(currentInstruction[2].u.operand), lexicalEnvironment);
NEXT_OPCODE(op_create_lexical_environment);
}
case op_get_scope: {
+ set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetScope, get(VirtualRegister(JSStack::Callee))));
NEXT_OPCODE(op_get_scope);
}
Modified: trunk/Source/_javascript_Core/dfg/DFGStackLayoutPhase.cpp (176478 => 176479)
--- trunk/Source/_javascript_Core/dfg/DFGStackLayoutPhase.cpp 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/dfg/DFGStackLayoutPhase.cpp 2014-11-21 23:41:26 UTC (rev 176479)
@@ -168,6 +168,11 @@
virtualRegisterForLocal(allocation[codeBlock()->activationRegister().toLocal()]));
}
+ if (codeBlock()->scopeRegister().isValid()) {
+ codeBlock()->setScopeRegister(
+ virtualRegisterForLocal(allocation[codeBlock()->scopeRegister().toLocal()]));
+ }
+
for (unsigned i = m_graph.m_inlineVariableData.size(); i--;) {
InlineVariableData data = ""
InlineCallFrame* inlineCallFrame = data.inlineCallFrame;
Modified: trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp (176478 => 176479)
--- trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp 2014-11-21 23:41:26 UTC (rev 176479)
@@ -255,6 +255,7 @@
case JSConstant:
case DoubleConstant:
case Int52Constant:
+ case GetScope:
break;
default:
Modified: trunk/Source/_javascript_Core/interpreter/CallFrame.h (176478 => 176479)
--- trunk/Source/_javascript_Core/interpreter/CallFrame.h 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/interpreter/CallFrame.h 2014-11-21 23:41:26 UTC (rev 176479)
@@ -51,6 +51,12 @@
return this[JSStack::ScopeChain].Register::scope();
}
+ JSScope* scope(int scopeRegisterOffset) const
+ {
+ ASSERT(this[scopeRegisterOffset].Register::scope());
+ return this[scopeRegisterOffset].Register::scope();
+ }
+
bool hasActivation() const;
JSLexicalEnvironment* lexicalEnvironment() const;
JSValue uncheckedActivation() const;
@@ -186,6 +192,7 @@
void setCallerFrame(CallFrame* frame) { callerFrameAndPC().callerFrame = frame; }
void setScope(JSScope* scope) { static_cast<Register*>(this)[JSStack::ScopeChain] = scope; }
+ void setScope(int scopeRegisterOffset, JSScope* scope) { static_cast<Register*>(this)[scopeRegisterOffset] = scope; }
void setActivation(JSLexicalEnvironment*);
ALWAYS_INLINE void init(CodeBlock* codeBlock, Instruction* vPC, JSScope* scope,
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (176478 => 176479)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2014-11-21 23:41:26 UTC (rev 176479)
@@ -105,7 +105,7 @@
CallFrame* callerFrame = callFrame->callerFrame();
CodeBlock* callerCodeBlock = callerFrame->codeBlock();
- JSScope* callerScopeChain = callerFrame->scope();
+ JSScope* callerScopeChain = callerFrame->uncheckedR(callerCodeBlock->scopeRegister().offset()).Register::scope();
EvalExecutable* eval = callerCodeBlock->evalCodeCache().tryGet(callerCodeBlock->isStrictMode(), programSource, callerScopeChain);
if (!eval) {
@@ -726,14 +726,16 @@
if (codeBlock->needsActivation() && callFrame->hasActivation())
++targetScopeDepth;
- JSScope* scope = callFrame->scope();
+ int scopeRegisterOffset = codeBlock->scopeRegister().offset();
+ JSScope* scope = callFrame->scope(scopeRegisterOffset);
int scopeDelta = scope->depth() - targetScopeDepth;
RELEASE_ASSERT(scopeDelta >= 0);
while (scopeDelta--)
scope = scope->next();
- callFrame->setScope(scope);
+ callFrame->setScope(scopeRegisterOffset, scope);
+
return handler;
}
Modified: trunk/Source/_javascript_Core/interpreter/StackVisitor.cpp (176478 => 176479)
--- trunk/Source/_javascript_Core/interpreter/StackVisitor.cpp 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/interpreter/StackVisitor.cpp 2014-11-21 23:41:26 UTC (rev 176479)
@@ -121,7 +121,6 @@
m_frame.m_callerFrame = callFrame->callerFrame(m_frame.m_CallerVMEntryFrame);
m_frame.m_callerIsVMEntryFrame = m_frame.m_CallerVMEntryFrame != m_frame.m_VMEntryFrame;
m_frame.m_callee = callFrame->callee();
- m_frame.m_scope = callFrame->scope();
m_frame.m_codeBlock = callFrame->codeBlock();
m_frame.m_bytecodeOffset = !m_frame.codeBlock() ? 0
: codeOrigin ? codeOrigin->bytecodeIndex
@@ -155,9 +154,7 @@
m_frame.m_bytecodeOffset = codeOrigin->bytecodeIndex;
JSFunction* callee = inlineCallFrame->calleeForCallFrame(callFrame);
- m_frame.m_scope = callee->scope();
m_frame.m_callee = callee;
- ASSERT(m_frame.scope());
ASSERT(m_frame.callee());
// The callerFrame just needs to be non-null to indicate that we
Modified: trunk/Source/_javascript_Core/interpreter/StackVisitor.h (176478 => 176479)
--- trunk/Source/_javascript_Core/interpreter/StackVisitor.h 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/interpreter/StackVisitor.h 2014-11-21 23:41:26 UTC (rev 176479)
@@ -60,7 +60,6 @@
bool callerIsVMEntryFrame() const { return m_callerIsVMEntryFrame; }
CallFrame* callerFrame() const { return m_callerFrame; }
JSObject* callee() const { return m_callee; }
- JSScope* scope() const { return m_scope; }
CodeBlock* codeBlock() const { return m_codeBlock; }
unsigned bytecodeOffset() const { return m_bytecodeOffset; }
#if ENABLE(DFG_JIT)
@@ -101,7 +100,6 @@
VMEntryFrame* m_CallerVMEntryFrame;
CallFrame* m_callerFrame;
JSObject* m_callee;
- JSScope* m_scope;
CodeBlock* m_codeBlock;
unsigned m_bytecodeOffset;
bool m_callerIsVMEntryFrame;
Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (176478 => 176479)
--- trunk/Source/_javascript_Core/jit/JITOperations.cpp 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp 2014-11-21 23:41:26 UTC (rev 176479)
@@ -1313,9 +1313,14 @@
VM& vm = exec->vm();
NativeCallFrameTracer tracer(&vm, exec);
+ // FIXME: This won't work if this operation is called from the DFG or FTL.
+ // This should be changed to pass in the new scope.
+ JSScope* currentScope = exec->uncheckedR(dst).Register::scope();
JSNameScope::Type scopeType = static_cast<JSNameScope::Type>(type);
- JSNameScope* scope = JSNameScope::create(exec, *identifier, JSValue::decode(encodedValue), attibutes, scopeType);
+ JSNameScope* scope = JSNameScope::create(exec, currentScope, *identifier, JSValue::decode(encodedValue), attibutes, scopeType);
+ // FIXME: This won't work if this operation is called from the DFG or FTL.
+ // This should be changed to return the new scope.
exec->uncheckedR(dst) = scope;
}
@@ -1340,7 +1345,10 @@
if (vm.exception())
return;
- exec->uncheckedR(dst) = JSWithScope::create(exec, o);
+ // FIXME: This won't work if this operation is called from the DFG or FTL.
+ // This should be changed to pass in the old scope and return the new scope.
+ JSScope* currentScope = exec->uncheckedR(dst).Register::scope();
+ exec->uncheckedR(dst) = JSWithScope::create(exec, o, currentScope);
}
void JIT_OPERATION operationPopScope(ExecState* exec, int32_t scopeReg)
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (176478 => 176479)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2014-11-21 23:41:26 UTC (rev 176479)
@@ -1235,7 +1235,8 @@
execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
execCallee->setCallerFrame(exec);
execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
- execCallee->setScope(exec->scope());
+ JSScope* callerScope = exec->uncheckedR(exec->codeBlock()->scopeRegister().offset()).Register::scope();
+ execCallee->setScope(callerScope);
execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
execCallee->setCodeBlock(0);
exec->setCurrentVPC(pc);
@@ -1275,7 +1276,9 @@
JSObject* o = v.toObject(exec);
LLINT_CHECK_EXCEPTION();
- exec->uncheckedR(pc[1].u.operand) = JSWithScope::create(exec, o);
+ int scopeReg = pc[1].u.operand;
+ JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
+ exec->uncheckedR(scopeReg) = JSWithScope::create(exec, o, currentScope);
LLINT_END();
}
@@ -1293,9 +1296,11 @@
{
LLINT_BEGIN();
CodeBlock* codeBlock = exec->codeBlock();
+ int scopeReg = pc[1].u.operand;
+ JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
JSNameScope::Type type = static_cast<JSNameScope::Type>(pc[5].u.operand);
- JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[2].u.operand), LLINT_OP(3).jsValue(), pc[4].u.operand, type);
- exec->uncheckedR(pc[1].u.operand) = scope;
+ JSNameScope* scope = JSNameScope::create(exec, currentScope, codeBlock->identifier(pc[2].u.operand), LLINT_OP(3).jsValue(), pc[4].u.operand, type);
+ exec->uncheckedR(scopeReg) = scope;
LLINT_END();
}
Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm (176478 => 176479)
--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm 2014-11-21 23:41:26 UTC (rev 176479)
@@ -2171,7 +2171,8 @@
loadp CodeBlock[cfr], t0
loadisFromInstruction(5, t2)
- loadp ScopeChain + PayloadOffset[cfr], t0
+ loadisFromInstruction(2, t0)
+ loadp PayloadOffset[cfr, t0, 8], t0
btiz t2, .resolveScopeLoopEnd
.resolveScopeLoop:
Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (176478 => 176479)
--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2014-11-21 23:41:26 UTC (rev 176479)
@@ -2000,9 +2000,9 @@
end
macro resolveScope()
- loadp CodeBlock[cfr], t0
loadisFromInstruction(5, t2)
- loadp ScopeChain[cfr], t0
+ loadisFromInstruction(2, t0)
+ loadp [cfr, t0, 8], t0
btiz t2, .resolveScopeLoopEnd
.resolveScopeLoop:
Modified: trunk/Source/_javascript_Core/runtime/JSNameScope.h (176478 => 176479)
--- trunk/Source/_javascript_Core/runtime/JSNameScope.h 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/runtime/JSNameScope.h 2014-11-21 23:41:26 UTC (rev 176479)
@@ -41,10 +41,10 @@
FunctionNameScope
};
- static JSNameScope* create(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes, Type type)
+ static JSNameScope* create(ExecState* exec, JSScope* currentScope, const Identifier& identifier, JSValue value, unsigned attributes, Type type)
{
VM& vm = exec->vm();
- JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(vm.heap)) JSNameScope(vm, exec->lexicalGlobalObject(), exec->scope(), type);
+ JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(vm.heap)) JSNameScope(vm, exec->lexicalGlobalObject(), currentScope, type);
scopeObject->finishCreation(vm, identifier, value, attributes);
return scopeObject;
}
Modified: trunk/Source/_javascript_Core/runtime/JSWithScope.h (176478 => 176479)
--- trunk/Source/_javascript_Core/runtime/JSWithScope.h 2014-11-21 23:39:16 UTC (rev 176478)
+++ trunk/Source/_javascript_Core/runtime/JSWithScope.h 2014-11-21 23:41:26 UTC (rev 176479)
@@ -34,13 +34,6 @@
public:
typedef JSScope Base;
- static JSWithScope* create(ExecState* exec, JSObject* object)
- {
- JSWithScope* withScope = new (NotNull, allocateCell<JSWithScope>(*exec->heap())) JSWithScope(exec, object);
- withScope->finishCreation(exec->vm());
- return withScope;
- }
-
static JSWithScope* create(ExecState* exec, JSObject* object, JSScope* next)
{
JSWithScope* withScope = new (NotNull, allocateCell<JSWithScope>(*exec->heap())) JSWithScope(exec, object, next);