Commit 40f7cbf3 authored by fpizlo@apple.com's avatar fpizlo@apple.com

put_to_scope[5] should not point to the structure if it's a variable access,...

put_to_scope[5] should not point to the structure if it's a variable access, but it should point to the WatchpointSet
https://bugs.webkit.org/show_bug.cgi?id=124539

Reviewed by Mark Hahnenberg.
        
This is in preparation for getting put_to_scope to directly invalidate the watchpoint set
on stores, which will allow us to run constant inference on all globals.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):
* bytecode/Instruction.h:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* runtime/JSScope.cpp:
(JSC::abstractAccess):
(JSC::JSScope::abstractResolve):
* runtime/JSScope.h:
(JSC::ResolveOp::ResolveOp):
* runtime/SymbolTable.h:
(JSC::SymbolTableEntry::watchpointSet):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159462 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent a7b7e50d
2013-11-18 Filip Pizlo <fpizlo@apple.com>
put_to_scope[5] should not point to the structure if it's a variable access, but it should point to the WatchpointSet
https://bugs.webkit.org/show_bug.cgi?id=124539
Reviewed by Mark Hahnenberg.
This is in preparation for getting put_to_scope to directly invalidate the watchpoint set
on stores, which will allow us to run constant inference on all globals.
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):
* bytecode/Instruction.h:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* runtime/JSScope.cpp:
(JSC::abstractAccess):
(JSC::JSScope::abstractResolve):
* runtime/JSScope.h:
(JSC::ResolveOp::ResolveOp):
* runtime/SymbolTable.h:
(JSC::SymbolTableEntry::watchpointSet):
2013-11-18 Mark Hahnenberg <mhahnenberg@apple.com>
APIEntryShims need some love
......
......@@ -1882,7 +1882,10 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), scope, ident, Put, modeAndType.type());
instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand();
if (op.structure)
if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks) {
ASSERT(!op.structure);
instructions[i + 5].u.watchpointSet = op.watchpointSet;
} else if (op.structure)
instructions[i + 5].u.structure.set(*vm(), ownerExecutable, op.structure);
instructions[i + 6].u.pointer = reinterpret_cast<void*>(op.operand);
break;
......@@ -2274,6 +2277,10 @@ void CodeBlock::finalizeUnconditionally()
break;
case op_get_from_scope:
case op_put_to_scope: {
ResolveModeAndType modeAndType =
ResolveModeAndType(curInstruction[4].u.operand);
if (modeAndType.type() == GlobalVar || modeAndType.type() == GlobalVarWithVarInjectionChecks)
continue;
WriteBarrierBase<Structure>& structure = curInstruction[5].u.structure;
if (!structure || Heap::isMarked(structure.get()))
break;
......
......@@ -115,6 +115,7 @@ struct Instruction {
ArrayProfile* arrayProfile;
ArrayAllocationProfile* arrayAllocationProfile;
ObjectAllocationProfile* objectAllocationProfile;
WatchpointSet* watchpointSet;
void* pointer;
bool* predicatePointer;
} u;
......
......@@ -3127,7 +3127,10 @@ bool ByteCodeParser::parseBlock(unsigned limit)
uintptr_t operand;
{
ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
structure = currentInstruction[5].u.structure.get();
if (resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks)
structure = 0;
else
structure = currentInstruction[5].u.structure.get();
operand = reinterpret_cast<uintptr_t>(currentInstruction[6].u.pointer);
}
......
......@@ -53,19 +53,19 @@ static inline bool abstractAccess(ExecState* exec, JSScope* scope, const Identif
if (JSActivation* activation = jsDynamicCast<JSActivation*>(scope)) {
if (ident == exec->propertyNames().arguments) {
// We know the property will be at this activation scope, but we don't know how to cache it.
op = ResolveOp(Dynamic, 0, 0, 0);
op = ResolveOp(Dynamic, 0, 0, 0, 0);
return true;
}
SymbolTableEntry entry = activation->symbolTable()->get(ident.impl());
if (entry.isReadOnly() && getOrPut == Put) {
// We know the property will be at this activation scope, but we don't know how to cache it.
op = ResolveOp(Dynamic, 0, 0, 0);
op = ResolveOp(Dynamic, 0, 0, 0, 0);
return true;
}
if (!entry.isNull()) {
op = ResolveOp(makeType(ClosureVar, needsVarInjectionChecks), depth, activation->structure(), entry.getIndex());
op = ResolveOp(makeType(ClosureVar, needsVarInjectionChecks), depth, activation->structure(), 0, entry.getIndex());
return true;
}
......@@ -80,7 +80,7 @@ static inline bool abstractAccess(ExecState* exec, JSScope* scope, const Identif
if (getOrPut == Put) {
if (entry.isReadOnly()) {
// We know the property will be at global scope, but we don't know how to cache it.
op = ResolveOp(Dynamic, 0, 0, 0);
op = ResolveOp(Dynamic, 0, 0, 0, 0);
return true;
}
......@@ -88,7 +88,8 @@ static inline bool abstractAccess(ExecState* exec, JSScope* scope, const Identif
entry.notifyWrite();
}
op = ResolveOp(makeType(GlobalVar, needsVarInjectionChecks), depth, globalObject->structure(),
op = ResolveOp(
makeType(GlobalVar, needsVarInjectionChecks), depth, 0, entry.watchpointSet(),
reinterpret_cast<uintptr_t>(globalObject->registerAt(entry.getIndex()).slot()));
return true;
}
......@@ -100,15 +101,15 @@ static inline bool abstractAccess(ExecState* exec, JSScope* scope, const Identif
|| (globalObject->structure()->hasReadOnlyOrGetterSetterPropertiesExcludingProto() && getOrPut == Put)) {
// We know the property will be at global scope, but we don't know how to cache it.
ASSERT(!scope->next());
op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, 0, 0);
op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, 0, 0, 0);
return true;
}
op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, globalObject->structure(), slot.cachedOffset());
op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, globalObject->structure(), 0, slot.cachedOffset());
return true;
}
op = ResolveOp(Dynamic, 0, 0, 0);
op = ResolveOp(Dynamic, 0, 0, 0, 0);
return true;
}
......@@ -146,7 +147,7 @@ JSValue JSScope::resolve(ExecState* exec, JSScope* scope, const Identifier& iden
ResolveOp JSScope::abstractResolve(ExecState* exec, JSScope* scope, const Identifier& ident, GetOrPut getOrPut, ResolveType unlinkedType)
{
ResolveOp op(Dynamic, 0, 0, 0);
ResolveOp op(Dynamic, 0, 0, 0, 0);
if (unlinkedType == Dynamic)
return op;
......
......@@ -31,6 +31,7 @@
namespace JSC {
class ScopeChainIterator;
class WatchpointSet;
enum ResolveMode {
ThrowIfNotFound,
......@@ -95,10 +96,11 @@ inline bool needsVarInjectionChecks(ResolveType type)
}
struct ResolveOp {
ResolveOp(ResolveType type, size_t depth, Structure* structure, uintptr_t operand)
ResolveOp(ResolveType type, size_t depth, Structure* structure, WatchpointSet* watchpointSet, uintptr_t operand)
: type(type)
, depth(depth)
, structure(structure)
, watchpointSet(watchpointSet)
, operand(operand)
{
}
......@@ -106,6 +108,7 @@ struct ResolveOp {
ResolveType type;
size_t depth;
Structure* structure;
WatchpointSet* watchpointSet;
uintptr_t operand;
};
......
......@@ -234,6 +234,8 @@ struct SymbolTableEntry {
WatchpointSet* watchpointSet()
{
if (!isFat())
return 0;
return fatEntry()->m_watchpoints.get();
}
......
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