X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/1df5f87f1309a8daa30dabdee855f48ae40d14ab..6fe7ccc865dc7d7541b93c5bcaf6368d2c98a174:/bytecode/PolymorphicPutByIdList.cpp diff --git a/bytecode/PolymorphicPutByIdList.cpp b/bytecode/PolymorphicPutByIdList.cpp new file mode 100644 index 0000000..170615b --- /dev/null +++ b/bytecode/PolymorphicPutByIdList.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PolymorphicPutByIdList.h" + +#if ENABLE(JIT) + +#include "StructureStubInfo.h" + +namespace JSC { + +PutByIdAccess PutByIdAccess::fromStructureStubInfo( + StructureStubInfo& stubInfo, + MacroAssemblerCodePtr initialSlowPath) +{ + PutByIdAccess result; + + switch (stubInfo.accessType) { + case access_put_by_id_replace: + result.m_type = Replace; + result.m_oldStructure.copyFrom(stubInfo.u.putByIdReplace.baseObjectStructure); + result.m_stubRoutine = MacroAssemblerCodeRef::createSelfManagedCodeRef(initialSlowPath); + break; + + case access_put_by_id_transition_direct: + case access_put_by_id_transition_normal: + result.m_type = Transition; + result.m_oldStructure.copyFrom(stubInfo.u.putByIdTransition.previousStructure); + result.m_newStructure.copyFrom(stubInfo.u.putByIdTransition.structure); + result.m_chain.copyFrom(stubInfo.u.putByIdTransition.chain); + result.m_stubRoutine = stubInfo.stubRoutine; + break; + + default: + ASSERT_NOT_REACHED(); + } + + return result; +} + +bool PutByIdAccess::visitWeak() const +{ + switch (m_type) { + case Replace: + if (!Heap::isMarked(m_oldStructure.get())) + return false; + break; + case Transition: + if (!Heap::isMarked(m_oldStructure.get())) + return false; + if (!Heap::isMarked(m_newStructure.get())) + return false; + if (!Heap::isMarked(m_chain.get())) + return false; + break; + default: + ASSERT_NOT_REACHED(); + return false; + } + return true; +} + +PolymorphicPutByIdList::PolymorphicPutByIdList( + PutKind putKind, + StructureStubInfo& stubInfo, + MacroAssemblerCodePtr initialSlowPath) + : m_kind(putKind) +{ + m_list.append(PutByIdAccess::fromStructureStubInfo(stubInfo, initialSlowPath)); +} + +PolymorphicPutByIdList* PolymorphicPutByIdList::from( + PutKind putKind, + StructureStubInfo& stubInfo, + MacroAssemblerCodePtr initialSlowPath) +{ + if (stubInfo.accessType == access_put_by_id_list) + return stubInfo.u.putByIdList.list; + + ASSERT(stubInfo.accessType == access_put_by_id_replace + || stubInfo.accessType == access_put_by_id_transition_normal + || stubInfo.accessType == access_put_by_id_transition_direct); + + PolymorphicPutByIdList* result = + new PolymorphicPutByIdList(putKind, stubInfo, initialSlowPath); + + stubInfo.initPutByIdList(result); + + return result; +} + +PolymorphicPutByIdList::~PolymorphicPutByIdList() { } + +bool PolymorphicPutByIdList::isFull() const +{ + ASSERT(size() <= POLYMORPHIC_LIST_CACHE_SIZE); + return size() == POLYMORPHIC_LIST_CACHE_SIZE; +} + +bool PolymorphicPutByIdList::isAlmostFull() const +{ + ASSERT(size() <= POLYMORPHIC_LIST_CACHE_SIZE); + return size() >= POLYMORPHIC_LIST_CACHE_SIZE - 1; +} + +void PolymorphicPutByIdList::addAccess(const PutByIdAccess& putByIdAccess) +{ + ASSERT(!isFull()); + // Make sure that the resizing optimizes for space, not time. + m_list.resize(m_list.size() + 1); + m_list.last() = putByIdAccess; +} + +bool PolymorphicPutByIdList::visitWeak() const +{ + for (unsigned i = 0; i < size(); ++i) { + if (!at(i).visitWeak()) + return false; + } + return true; +} + +} // namespace JSC + +#endif // ENABLE(JIT)