/*
- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include "JSScope.h"
#include "PropertyDescriptor.h"
#include "SymbolTable.h"
-#include "VariableWatchpointSetInlines.h"
+#include "VariableWriteFireDetail.h"
namespace JSC {
+class JSSymbolTableObject;
+
class JSSymbolTableObject : public JSScope {
public:
typedef JSScope Base;
+ static const unsigned StructureFlags = Base::StructureFlags | IsEnvironmentRecord | OverridesGetPropertyNames;
SymbolTable* symbolTable() const { return m_symbolTable.get(); }
JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+ static ptrdiff_t offsetOfSymbolTable() { return OBJECT_OFFSETOF(JSSymbolTableObject, m_symbolTable); }
+
protected:
- static const unsigned StructureFlags = IsEnvironmentRecord | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
+ JSSymbolTableObject(VM& vm, Structure* structure, JSScope* scope)
+ : Base(vm, structure, scope)
+ {
+ }
- JSSymbolTableObject(VM& vm, Structure* structure, JSScope* scope, SymbolTable* symbolTable = 0)
+ JSSymbolTableObject(VM& vm, Structure* structure, JSScope* scope, SymbolTable* symbolTable)
: Base(vm, structure, scope)
{
- if (symbolTable)
- m_symbolTable.set(vm, this, symbolTable);
+ ASSERT(symbolTable);
+ setSymbolTable(vm, symbolTable);
}
-
- void finishCreation(VM& vm)
+
+ void setSymbolTable(VM& vm, SymbolTable* symbolTable)
{
- Base::finishCreation(vm);
- if (!m_symbolTable)
- m_symbolTable.set(vm, this, SymbolTable::create(vm));
+ ASSERT(!m_symbolTable);
+ symbolTable->singletonScope()->notifyWrite(vm, this, "Allocated a scope");
+ m_symbolTable.set(vm, this, symbolTable);
}
-
+
static void visitChildren(JSCell*, SlotVisitor&);
-
+
+private:
WriteBarrier<SymbolTable> m_symbolTable;
};
return false;
SymbolTableEntry::Fast entry = iter->value;
ASSERT(!entry.isNull());
- slot.setValue(object, entry.getAttributes() | DontDelete, object->registerAt(entry.getIndex()).get());
+ slot.setValue(object, entry.getAttributes() | DontDelete, object->variableAt(entry.scopeOffset()).get());
return true;
}
SymbolTableEntry::Fast entry = iter->value;
ASSERT(!entry.isNull());
descriptor.setDescriptor(
- object->registerAt(entry.getIndex()).get(), entry.getAttributes() | DontDelete);
+ object->variableAt(entry.scopeOffset()).get(), entry.getAttributes() | DontDelete);
return true;
}
return false;
SymbolTableEntry::Fast entry = iter->value;
ASSERT(!entry.isNull());
- slot.setValue(object, entry.getAttributes() | DontDelete, object->registerAt(entry.getIndex()).get());
+ slot.setValue(object, entry.getAttributes() | DontDelete, object->variableAt(entry.scopeOffset()).get());
slotIsWriteable = !entry.isReadOnly();
return true;
}
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
WriteBarrierBase<Unknown>* reg;
+ WatchpointSet* set;
{
SymbolTable& symbolTable = *object->symbolTable();
// FIXME: This is very suspicious. We shouldn't need a GC-safe lock here.
throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return true;
}
- if (VariableWatchpointSet* set = iter->value.watchpointSet()) {
- // FIXME: It's strange that we're doing this while holding the symbol table's lock.
- // https://bugs.webkit.org/show_bug.cgi?id=134601
- set->notifyWrite(vm, value);
- }
- reg = &object->registerAt(fastEntry.getIndex());
+ set = iter->value.watchpointSet();
+ reg = &object->variableAt(fastEntry.scopeOffset());
}
// I'd prefer we not hold lock while executing barriers, since I prefer to reserve
// the right for barriers to be able to trigger GC. And I don't want to hold VM
// locks while GC'ing.
reg->set(vm, object, value);
+ if (set)
+ VariableWriteFireDetail::touch(set, object, propertyName);
return true;
}
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
WriteBarrierBase<Unknown>* reg;
+ WatchpointSet* set;
{
SymbolTable& symbolTable = *object->symbolTable();
ConcurrentJITLocker locker(symbolTable.m_lock);
return false;
SymbolTableEntry& entry = iter->value;
ASSERT(!entry.isNull());
- if (VariableWatchpointSet* set = entry.watchpointSet())
- set->notifyWrite(vm, value);
+ set = entry.watchpointSet();
entry.setAttributes(attributes);
- reg = &object->registerAt(entry.getIndex());
+ reg = &object->variableAt(entry.scopeOffset());
}
reg->set(vm, object, value);
+ if (set)
+ VariableWriteFireDetail::touch(set, object, propertyName);
return true;
}