diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog index 54e88de61f00..f8452c0b0e38 100644 --- a/Source/JavaScriptCore/ChangeLog +++ b/Source/JavaScriptCore/ChangeLog @@ -1,3 +1,21 @@ +2017-08-09 Caio Lima + + [JSC] Create JSSet constructor that accepts it's size as parameter + https://bugs.webkit.org/show_bug.cgi?id=173297 + + Reviewed by Saam Barati. + + This patch is adding a new constructor to JSSet that gives its + expected initial size. It is important to avoid re-hashing and mutiple + allocations when we know the final size of JSSet, such as in + CodeBlock::setConstantIdentifierSetRegisters. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::setConstantIdentifierSetRegisters): + * runtime/HashMapImpl.h: + (JSC::HashMapImpl::HashMapImpl): + * runtime/JSSet.h: + 2017-08-09 Caitlin Potter Early error on ANY operator before new.target diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp index 28ee727d6c8c..e123ff8f09f8 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp @@ -877,12 +877,13 @@ void CodeBlock::setConstantIdentifierSetRegisters(VM& vm, const VectorglobalExec(); for (const auto& entry : constants) { + const IdentifierSet& set = entry.first; + Structure* setStructure = globalObject->setStructure(); RETURN_IF_EXCEPTION(scope, void()); - JSSet* jsSet = JSSet::create(exec, vm, setStructure); + JSSet* jsSet = JSSet::create(exec, vm, setStructure, set.size()); RETURN_IF_EXCEPTION(scope, void()); - const IdentifierSet& set = entry.first; for (auto setEntry : set) { JSString* jsString = jsOwnedString(&vm, setEntry.get()); jsSet->add(exec, jsString); diff --git a/Source/JavaScriptCore/runtime/HashMapImpl.h b/Source/JavaScriptCore/runtime/HashMapImpl.h index d18717671335..2908a10bc81a 100644 --- a/Source/JavaScriptCore/runtime/HashMapImpl.h +++ b/Source/JavaScriptCore/runtime/HashMapImpl.h @@ -300,6 +300,16 @@ class HashMapImpl : public JSNonFinalObject { { } + HashMapImpl(VM& vm, Structure* structure, uint32_t sizeHint) + : Base(vm, structure) + , m_keyCount(0) + , m_deleteCount(0) + { + uint32_t capacity = ((Checked(sizeHint) * 2) + 1).unsafeGet(); + capacity = std::max(WTF::roundUpToPowerOfTwo(capacity), 4U); + m_capacity = capacity; + } + ALWAYS_INLINE HashMapBucketType** buffer() const { return m_buffer->buffer(); diff --git a/Source/JavaScriptCore/runtime/JSSet.h b/Source/JavaScriptCore/runtime/JSSet.h index e6764079e28f..4283293ea529 100644 --- a/Source/JavaScriptCore/runtime/JSSet.h +++ b/Source/JavaScriptCore/runtime/JSSet.h @@ -47,7 +47,12 @@ class JSSet final : public HashMapImpl> { static JSSet* create(ExecState* exec, VM& vm, Structure* structure) { - JSSet* instance = new (NotNull, allocateCell(vm.heap)) JSSet(vm, structure); + return create(exec, vm, structure, 0); + } + + static JSSet* create(ExecState* exec, VM& vm, Structure* structure, uint32_t size) + { + JSSet* instance = new (NotNull, allocateCell(vm.heap)) JSSet(vm, structure, size); instance->finishCreation(exec, vm); return instance; } @@ -62,6 +67,11 @@ class JSSet final : public HashMapImpl> { { } + JSSet(VM& vm, Structure* structure, uint32_t sizeHint) + : Base(vm, structure, sizeHint) + { + } + static String toStringName(const JSObject*, ExecState*); };