diff options
Diffstat (limited to 'Source/JavaScriptCore/runtime/ButterflyInlines.h')
-rw-r--r-- | Source/JavaScriptCore/runtime/ButterflyInlines.h | 125 |
1 files changed, 70 insertions, 55 deletions
diff --git a/Source/JavaScriptCore/runtime/ButterflyInlines.h b/Source/JavaScriptCore/runtime/ButterflyInlines.h index f5439bb02..88c6f8a67 100644 --- a/Source/JavaScriptCore/runtime/ButterflyInlines.h +++ b/Source/JavaScriptCore/runtime/ButterflyInlines.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2012-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,34 +23,68 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ButterflyInlines_h -#define ButterflyInlines_h +#pragma once #include "ArrayStorage.h" #include "Butterfly.h" -#include "CopiedSpaceInlines.h" -#include "CopyVisitor.h" #include "VM.h" #include "Structure.h" namespace JSC { -inline Butterfly* Butterfly::createUninitialized(VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes) +ALWAYS_INLINE unsigned Butterfly::availableContiguousVectorLength(size_t propertyCapacity, unsigned vectorLength) +{ + size_t cellSize = totalSize(0, propertyCapacity, true, sizeof(EncodedJSValue) * vectorLength); + cellSize = MarkedSpace::optimalSizeFor(cellSize); + vectorLength = (cellSize - totalSize(0, propertyCapacity, true, 0)) / sizeof(EncodedJSValue); + return vectorLength; +} + +ALWAYS_INLINE unsigned Butterfly::availableContiguousVectorLength(Structure* structure, unsigned vectorLength) +{ + return availableContiguousVectorLength(structure ? structure->outOfLineCapacity() : 0, vectorLength); +} + +ALWAYS_INLINE unsigned Butterfly::optimalContiguousVectorLength(size_t propertyCapacity, unsigned vectorLength) +{ + if (!vectorLength) + vectorLength = BASE_CONTIGUOUS_VECTOR_LEN_EMPTY; + else + vectorLength = std::max(BASE_CONTIGUOUS_VECTOR_LEN, vectorLength); + return availableContiguousVectorLength(propertyCapacity, vectorLength); +} + +ALWAYS_INLINE unsigned Butterfly::optimalContiguousVectorLength(Structure* structure, unsigned vectorLength) +{ + return optimalContiguousVectorLength(structure ? structure->outOfLineCapacity() : 0, vectorLength); +} + +inline Butterfly* Butterfly::createUninitialized(VM& vm, JSCell*, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes) { - void* temp; size_t size = totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); - RELEASE_ASSERT(vm.heap.tryAllocateStorage(intendedOwner, size, &temp)); - Butterfly* result = fromBase(temp, preCapacity, propertyCapacity); + void* base = vm.auxiliarySpace.allocate(size); + Butterfly* result = fromBase(base, preCapacity, propertyCapacity); return result; } -inline Butterfly* Butterfly::create(VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes) +inline Butterfly* Butterfly::tryCreate(VM& vm, JSCell*, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes) { - Butterfly* result = createUninitialized( - vm, intendedOwner, preCapacity, propertyCapacity, hasIndexingHeader, - indexingPayloadSizeInBytes); + size_t size = totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); + void* base = vm.auxiliarySpace.tryAllocate(size); + if (!base) + return nullptr; + Butterfly* result = fromBase(base, preCapacity, propertyCapacity); if (hasIndexingHeader) *result->indexingHeader() = indexingHeader; + memset(result->propertyStorage() - propertyCapacity, 0, propertyCapacity * sizeof(EncodedJSValue)); + return result; +} + +inline Butterfly* Butterfly::create(VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes) +{ + Butterfly* result = tryCreate(vm, intendedOwner, preCapacity, propertyCapacity, hasIndexingHeader, indexingHeader, indexingPayloadSizeInBytes); + + RELEASE_ASSERT(result); return result; } @@ -61,53 +95,34 @@ inline Butterfly* Butterfly::create(VM& vm, JSCell* intendedOwner, Structure* st structure->hasIndexingHeader(intendedOwner), IndexingHeader(), 0); } -inline Butterfly* Butterfly::createUninitializedDuringCollection(CopyVisitor& visitor, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes) -{ - size_t size = totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); - Butterfly* result = fromBase( - visitor.allocateNewSpace(size), - preCapacity, propertyCapacity); - return result; -} - inline void* Butterfly::base(Structure* structure) { return base(indexingHeader()->preCapacity(structure), structure->outOfLineCapacity()); } -inline Butterfly* Butterfly::growPropertyStorage( - VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t oldPropertyCapacity, - bool hasIndexingHeader, size_t indexingPayloadSizeInBytes, size_t newPropertyCapacity) +inline Butterfly* Butterfly::createOrGrowPropertyStorage( + Butterfly* oldButterfly, VM& vm, JSCell* intendedOwner, Structure* structure, size_t oldPropertyCapacity, size_t newPropertyCapacity) { RELEASE_ASSERT(newPropertyCapacity > oldPropertyCapacity); + if (!oldButterfly) + return create(vm, intendedOwner, 0, newPropertyCapacity, false, IndexingHeader(), 0); + + size_t preCapacity = oldButterfly->indexingHeader()->preCapacity(structure); + size_t indexingPayloadSizeInBytes = oldButterfly->indexingHeader()->indexingPayloadSizeInBytes(structure); + bool hasIndexingHeader = structure->hasIndexingHeader(intendedOwner); Butterfly* result = createUninitialized( - vm, intendedOwner, preCapacity, newPropertyCapacity, hasIndexingHeader, - indexingPayloadSizeInBytes); + vm, intendedOwner, preCapacity, newPropertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); memcpy( result->propertyStorage() - oldPropertyCapacity, - propertyStorage() - oldPropertyCapacity, + oldButterfly->propertyStorage() - oldPropertyCapacity, totalSize(0, oldPropertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes)); + memset( + result->propertyStorage() - newPropertyCapacity, + 0, + (newPropertyCapacity - oldPropertyCapacity) * sizeof(EncodedJSValue)); return result; } -inline Butterfly* Butterfly::growPropertyStorage( - VM& vm, JSCell* intendedOwner, Structure* structure, size_t oldPropertyCapacity, - size_t newPropertyCapacity) -{ - return growPropertyStorage( - vm, intendedOwner, indexingHeader()->preCapacity(structure), oldPropertyCapacity, - structure->hasIndexingHeader(intendedOwner), - indexingHeader()->indexingPayloadSizeInBytes(structure), newPropertyCapacity); -} - -inline Butterfly* Butterfly::growPropertyStorage( - VM& vm, JSCell* intendedOwner, Structure* oldStructure, size_t newPropertyCapacity) -{ - return growPropertyStorage( - vm, intendedOwner, oldStructure, oldStructure->outOfLineCapacity(), - newPropertyCapacity); -} - inline Butterfly* Butterfly::createOrGrowArrayRight( Butterfly* oldButterfly, VM& vm, JSCell* intendedOwner, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, @@ -129,13 +144,16 @@ inline Butterfly* Butterfly::growArrayRight( size_t newIndexingPayloadSizeInBytes) { ASSERT_UNUSED(oldStructure, !indexingHeader()->preCapacity(oldStructure)); - ASSERT_UNUSED(oldStructure, hadIndexingHeader == oldStructure->hasIndexingHeader(intendedOwner)); + ASSERT_UNUSED(intendedOwner, hadIndexingHeader == oldStructure->hasIndexingHeader(intendedOwner)); void* theBase = base(0, propertyCapacity); size_t oldSize = totalSize(0, propertyCapacity, hadIndexingHeader, oldIndexingPayloadSizeInBytes); size_t newSize = totalSize(0, propertyCapacity, true, newIndexingPayloadSizeInBytes); - if (!vm.heap.tryReallocateStorage(intendedOwner, &theBase, oldSize, newSize)) - return 0; - return fromBase(theBase, 0, propertyCapacity); + void* newBase = vm.auxiliarySpace.tryAllocate(newSize); + if (!newBase) + return nullptr; + // FIXME: This probably shouldn't be a memcpy. + memcpy(newBase, theBase, oldSize); + return fromBase(newBase, 0, propertyCapacity); } inline Butterfly* Butterfly::growArrayRight( @@ -181,7 +199,7 @@ inline Butterfly* Butterfly::resizeArray( inline Butterfly* Butterfly::unshift(Structure* structure, size_t numberOfSlots) { - ASSERT(hasArrayStorage(structure->indexingType())); + ASSERT(hasAnyArrayStorage(structure->indexingType())); ASSERT(numberOfSlots <= indexingHeader()->preCapacity(structure)); unsigned propertyCapacity = structure->outOfLineCapacity(); // FIXME: It would probably be wise to rewrite this as a loop since (1) we know in which @@ -200,7 +218,7 @@ inline Butterfly* Butterfly::unshift(Structure* structure, size_t numberOfSlots) inline Butterfly* Butterfly::shift(Structure* structure, size_t numberOfSlots) { - ASSERT(hasArrayStorage(structure->indexingType())); + ASSERT(hasAnyArrayStorage(structure->indexingType())); unsigned propertyCapacity = structure->outOfLineCapacity(); // FIXME: See comment in unshift(), above. memmove( @@ -211,6 +229,3 @@ inline Butterfly* Butterfly::shift(Structure* structure, size_t numberOfSlots) } } // namespace JSC - -#endif // ButterflyInlines_h - |