Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (145400 => 145401)
--- trunk/Source/_javascript_Core/ChangeLog 2013-03-11 21:01:53 UTC (rev 145400)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-03-11 21:02:39 UTC (rev 145401)
@@ -1,3 +1,36 @@
+2013-03-11 Oliver Hunt <oli...@apple.com>
+
+ Make SegmentedVector Noncopyable
+ https://bugs.webkit.org/show_bug.cgi?id=112059
+
+ Reviewed by Geoffrey Garen.
+
+ Copying a SegmentedVector is very expensive, and really shouldn't
+ be necessary. So I've taken the one place where we currently copy
+ and replaced it with a regular Vector, and replaced the address
+ dependent logic with a indexing ref instead.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::newLabelScope):
+ (JSC::BytecodeGenerator::emitComplexJumpScopes):
+ * bytecompiler/BytecodeGenerator.h:
+ (BytecodeGenerator):
+ * bytecompiler/LabelScope.h:
+ (JSC):
+ (JSC::LabelScopePtr::LabelScopePtr):
+ (LabelScopePtr):
+ (JSC::LabelScopePtr::operator=):
+ (JSC::LabelScopePtr::~LabelScopePtr):
+ (JSC::LabelScopePtr::operator*):
+ (JSC::LabelScopePtr::operator->):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::DoWhileNode::emitBytecode):
+ (JSC::WhileNode::emitBytecode):
+ (JSC::ForNode::emitBytecode):
+ (JSC::ForInNode::emitBytecode):
+ (JSC::SwitchNode::emitBytecode):
+ (JSC::LabelNode::emitBytecode):
+
2013-03-10 Andreas Kling <akl...@apple.com>
SpeculativeJIT should use OwnPtr<SlowPathGenerator>.
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (145400 => 145401)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2013-03-11 21:01:53 UTC (rev 145400)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2013-03-11 21:02:39 UTC (rev 145401)
@@ -639,7 +639,7 @@
return result;
}
-PassRefPtr<LabelScope> BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
+LabelScopePtr BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
{
// Reclaim free label scopes.
while (m_labelScopes.size() && !m_labelScopes.last().refCount())
@@ -648,7 +648,7 @@
// Allocate new label scope.
LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>()); // Only loops have continue targets.
m_labelScopes.append(scope);
- return &m_labelScopes.last();
+ return LabelScopePtr(&m_labelScopes, m_labelScopes.size() - 1);
}
PassRefPtr<Label> BytecodeGenerator::newLabel()
@@ -2281,7 +2281,7 @@
Vector<SwitchInfo> savedSwitchContextStack;
Vector<ForInContext> savedForInContextStack;
Vector<TryContext> poppedTryContexts;
- SegmentedVector<LabelScope, 8> savedLabelScopes;
+ LabelScopeStore savedLabelScopes;
while (topScope > bottomScope && topScope->isFinallyBlock) {
RefPtr<Label> beforeFinally = emitLabel(newLabel().get());
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (145400 => 145401)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2013-03-11 21:01:53 UTC (rev 145400)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2013-03-11 21:02:39 UTC (rev 145401)
@@ -331,7 +331,7 @@
return dst == ignoredResult() ? 0 : (dst && dst != src) ? emitMove(dst, src) : src;
}
- PassRefPtr<LabelScope> newLabelScope(LabelScope::Type, const Identifier* = 0);
+ LabelScopePtr newLabelScope(LabelScope::Type, const Identifier* = 0);
PassRefPtr<Label> newLabel();
// The emitNode functions are just syntactic sugar for calling
@@ -701,7 +701,7 @@
SegmentedVector<RegisterID, 32> m_calleeRegisters;
SegmentedVector<RegisterID, 32> m_parameters;
SegmentedVector<Label, 32> m_labels;
- SegmentedVector<LabelScope, 8> m_labelScopes;
+ LabelScopeStore m_labelScopes;
RefPtr<RegisterID> m_lastVar;
int m_finallyDepth;
int m_dynamicScopeDepth;
Modified: trunk/Source/_javascript_Core/bytecompiler/LabelScope.h (145400 => 145401)
--- trunk/Source/_javascript_Core/bytecompiler/LabelScope.h 2013-03-11 21:01:53 UTC (rev 145400)
+++ trunk/Source/_javascript_Core/bytecompiler/LabelScope.h 2013-03-11 21:02:39 UTC (rev 145401)
@@ -49,13 +49,6 @@
, m_continueTarget(continueTarget)
{
}
-
- void ref() { ++m_refCount; }
- void deref()
- {
- --m_refCount;
- ASSERT(m_refCount >= 0);
- }
int refCount() const { return m_refCount; }
Label* breakTarget() const { return m_breakTarget.get(); }
@@ -66,6 +59,15 @@
int scopeDepth() const { return m_scopeDepth; }
private:
+ friend class LabelScopePtr;
+
+ void ref() { ++m_refCount; }
+ void deref()
+ {
+ --m_refCount;
+ ASSERT(m_refCount >= 0);
+ }
+
int m_refCount;
Type m_type;
const Identifier* m_name;
@@ -74,6 +76,57 @@
RefPtr<Label> m_continueTarget;
};
+ typedef Vector<LabelScope, 8> LabelScopeStore;
+
+ class LabelScopePtr {
+ public:
+ LabelScopePtr()
+ : m_owner(0)
+ , m_index(0)
+ {
+ }
+ LabelScopePtr(LabelScopeStore* owner, size_t index)
+ : m_owner(owner)
+ , m_index(index)
+ {
+ m_owner->at(index).ref();
+ }
+
+ LabelScopePtr(const LabelScopePtr& other)
+ : m_owner(other.m_owner)
+ , m_index(other.m_index)
+ {
+ if (m_owner)
+ m_owner->at(m_index).ref();
+ }
+
+ const LabelScopePtr& operator=(const LabelScopePtr& other)
+ {
+ if (other.m_owner)
+ other.m_owner->at(other.m_index).ref();
+ if (m_owner)
+ m_owner->at(m_index).deref();
+ m_owner = other.m_owner;
+ m_index = other.m_index;
+ return *this;
+ }
+
+ ~LabelScopePtr()
+ {
+ if (m_owner)
+ m_owner->at(m_index).deref();
+ }
+
+ LabelScope& operator*() { ASSERT(m_owner); return m_owner->at(m_index); }
+ LabelScope* operator->() { ASSERT(m_owner); return &m_owner->at(m_index); }
+ const LabelScope& operator*() const { ASSERT(m_owner); return m_owner->at(m_index); }
+ const LabelScope* operator->() const { ASSERT(m_owner); return &m_owner->at(m_index); }
+
+ private:
+ LabelScopeStore* m_owner;
+ size_t m_index;
+ };
+
} // namespace JSC
#endif // LabelScope_h
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (145400 => 145401)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2013-03-11 21:01:53 UTC (rev 145400)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2013-03-11 21:02:39 UTC (rev 145401)
@@ -1594,7 +1594,7 @@
RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+ LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
RefPtr<Label> topOfLoop = generator.newLabel();
generator.emitLabel(topOfLoop.get());
@@ -1620,7 +1620,7 @@
RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+ LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
RefPtr<Label> topOfLoop = generator.newLabel();
generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo(), m_expr->columnNo());
@@ -1656,7 +1656,7 @@
RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+ LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
@@ -1701,7 +1701,7 @@
RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+ LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
if (!m_lexpr->isLocation())
return emitThrowReferenceError(generator, "Left side of for-in statement is not a reference.");
@@ -2010,7 +2010,7 @@
{
generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
+ LabelScopePtr scope = generator.newLabelScope(LabelScope::Switch);
RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
@@ -2027,7 +2027,7 @@
ASSERT(!generator.breakTarget(m_name));
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
+ LabelScopePtr scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
RegisterID* r0 = generator.emitNode(dst, m_statement);
generator.emitLabel(scope->breakTarget());
Modified: trunk/Source/WTF/ChangeLog (145400 => 145401)
--- trunk/Source/WTF/ChangeLog 2013-03-11 21:01:53 UTC (rev 145400)
+++ trunk/Source/WTF/ChangeLog 2013-03-11 21:02:39 UTC (rev 145401)
@@ -1,3 +1,17 @@
+2013-03-11 Oliver Hunt <oli...@apple.com>
+
+ Make SegmentedVector Noncopyable
+ https://bugs.webkit.org/show_bug.cgi?id=112059
+
+ Reviewed by Geoffrey Garen.
+
+ Copying a SegmentedVector can be extraordinarily expensive, so we beat
+ it with the Noncopyable stick - that way we can ensure that if anyone
+ wants an actual copy they know what they're doing.
+
+ * wtf/SegmentedVector.h:
+ (SegmentedVector):
+
2013-03-08 Benjamin Poulain <benja...@webkit.org>
[Mac] Add a feature flag for 'view-mode' Media Feature, disable it on Mac
Modified: trunk/Source/WTF/wtf/SegmentedVector.h (145400 => 145401)
--- trunk/Source/WTF/wtf/SegmentedVector.h 2013-03-11 21:01:53 UTC (rev 145400)
+++ trunk/Source/WTF/wtf/SegmentedVector.h 2013-03-11 21:02:39 UTC (rev 145401)
@@ -29,6 +29,7 @@
#ifndef SegmentedVector_h
#define SegmentedVector_h
+#include <wtf/Noncopyable.h>
#include <wtf/Vector.h>
namespace WTF {
@@ -104,6 +105,8 @@
template <typename T, size_t SegmentSize, size_t InlineCapacity>
class SegmentedVector {
friend class SegmentedVectorIterator<T, SegmentSize, InlineCapacity>;
+ WTF_MAKE_NONCOPYABLE(SegmentedVector);
+
public:
typedef SegmentedVectorIterator<T, SegmentSize, InlineCapacity> Iterator;