fourthTier: It should be possible to record heap operations (both FastMalloc and JSC GC)
https://bugs.webkit.org/show_bug.cgi?id=116848
Source/JavaScriptCore:
Reviewed by Mark Hahnenberg.
Record GC heap operations if ENABLE(ALLOCATION_LOGGING).
* API/JSManagedValue.mm:
* dfg/DFGOperations.cpp:
* heap/Heap.cpp:
(JSC::Heap::collect):
* heap/Heap.h:
(Heap):
(JSC::Heap::allocateWithNormalDestructor):
(JSC::Heap::allocateWithImmortalStructureDestructor):
(JSC::Heap::allocateWithoutDestructor):
(JSC::Heap::tryAllocateStorage):
(JSC::Heap::tryReallocateStorage):
(JSC):
(JSC::Heap::ascribeOwner):
* heap/SlotVisitor.cpp:
(JSC::SlotVisitor::append):
(JSC::SlotVisitor::internalAppend):
* heap/SlotVisitor.h:
(SlotVisitor):
* heap/SlotVisitorInlines.h:
(JSC::SlotVisitor::append):
(JSC::SlotVisitor::appendUnbarrieredPointer):
(JSC::SlotVisitor::appendUnbarrieredValue):
(JSC::SlotVisitor::appendUnbarrieredWeak):
(JSC::SlotVisitor::internalAppend):
(JSC):
(JSC::SlotVisitor::appendValues):
* jit/JITWriteBarrier.h:
(JSC::SlotVisitor::append):
* llint/LLIntCommon.h:
* runtime/Butterfly.h:
(Butterfly):
* runtime/ButterflyInlines.h:
(JSC::Butterfly::createUninitialized):
(JSC::Butterfly::create):
(JSC::Butterfly::growPropertyStorage):
(JSC::Butterfly::createOrGrowArrayRight):
(JSC):
(JSC::Butterfly::growArrayRight):
(JSC::Butterfly::resizeArray):
* runtime/JSArray.cpp:
(JSC::createArrayButterflyInDictionaryIndexingMode):
(JSC::JSArray::unshiftCountSlowCase):
* runtime/JSArray.h:
(JSC::createContiguousArrayButterfly):
(JSC::createArrayButterfly):
(JSC):
(JSC::JSArray::create):
(JSC::JSArray::tryCreateUninitialized):
* runtime/JSObject.cpp:
(JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
(JSC::JSObject::createInitialIndexedStorage):
(JSC::JSObject::createArrayStorage):
(JSC::JSObject::constructConvertedArrayStorageWithoutCopyingElements):
(JSC::JSObject::increaseVectorLength):
(JSC::JSObject::ensureLengthSlow):
(JSC::JSObject::growOutOfLineStorage):
* runtime/JSObject.h:
(JSC::JSObject::JSObject):
* runtime/Operations.h:
* runtime/RegExpMatchesArray.cpp:
(JSC::RegExpMatchesArray::create):
* runtime/StructureInlines.h:
(JSC):
* runtime/WriteBarrier.h:
(JSC):
Source/WTF:
Reviewed by Mark Hahnenberg.
* WTF.xcodeproj/project.pbxproj:
* wtf/DataLog.cpp:
(WTF):
(WTF::initializeLogFileOnce):
* wtf/FastMalloc.cpp:
(WTF::TCMalloc_ThreadCache::CreateCacheIfNecessary):
* wtf/Platform.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153189 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/API/JSManagedValue.mm b/Source/JavaScriptCore/API/JSManagedValue.mm
index f336ba6..758082f 100644
--- a/Source/JavaScriptCore/API/JSManagedValue.mm
+++ b/Source/JavaScriptCore/API/JSManagedValue.mm
@@ -31,12 +31,12 @@
#import "APICast.h"
#import "Heap.h"
-#import "JSCJSValueInlines.h"
#import "JSContextInternal.h"
#import "JSValueInternal.h"
#import "Weak.h"
#import "WeakHandleOwner.h"
#import "ObjcRuntimeExtras.h"
+#import "Operations.h"
class JSManagedValueHandleOwner : public JSC::WeakHandleOwner {
public:
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 5fda9ec..2eb4112 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,5 +1,80 @@
2013-05-27 Filip Pizlo <fpizlo@apple.com>
+ It should be possible to record heap operations (both FastMalloc and JSC GC)
+ https://bugs.webkit.org/show_bug.cgi?id=116848
+
+ Reviewed by Mark Hahnenberg.
+
+ Record GC heap operations if ENABLE(ALLOCATION_LOGGING).
+
+ * API/JSManagedValue.mm:
+ * dfg/DFGOperations.cpp:
+ * heap/Heap.cpp:
+ (JSC::Heap::collect):
+ * heap/Heap.h:
+ (Heap):
+ (JSC::Heap::allocateWithNormalDestructor):
+ (JSC::Heap::allocateWithImmortalStructureDestructor):
+ (JSC::Heap::allocateWithoutDestructor):
+ (JSC::Heap::tryAllocateStorage):
+ (JSC::Heap::tryReallocateStorage):
+ (JSC):
+ (JSC::Heap::ascribeOwner):
+ * heap/SlotVisitor.cpp:
+ (JSC::SlotVisitor::append):
+ (JSC::SlotVisitor::internalAppend):
+ * heap/SlotVisitor.h:
+ (SlotVisitor):
+ * heap/SlotVisitorInlines.h:
+ (JSC::SlotVisitor::append):
+ (JSC::SlotVisitor::appendUnbarrieredPointer):
+ (JSC::SlotVisitor::appendUnbarrieredValue):
+ (JSC::SlotVisitor::appendUnbarrieredWeak):
+ (JSC::SlotVisitor::internalAppend):
+ (JSC):
+ (JSC::SlotVisitor::appendValues):
+ * jit/JITWriteBarrier.h:
+ (JSC::SlotVisitor::append):
+ * llint/LLIntCommon.h:
+ * runtime/Butterfly.h:
+ (Butterfly):
+ * runtime/ButterflyInlines.h:
+ (JSC::Butterfly::createUninitialized):
+ (JSC::Butterfly::create):
+ (JSC::Butterfly::growPropertyStorage):
+ (JSC::Butterfly::createOrGrowArrayRight):
+ (JSC):
+ (JSC::Butterfly::growArrayRight):
+ (JSC::Butterfly::resizeArray):
+ * runtime/JSArray.cpp:
+ (JSC::createArrayButterflyInDictionaryIndexingMode):
+ (JSC::JSArray::unshiftCountSlowCase):
+ * runtime/JSArray.h:
+ (JSC::createContiguousArrayButterfly):
+ (JSC::createArrayButterfly):
+ (JSC):
+ (JSC::JSArray::create):
+ (JSC::JSArray::tryCreateUninitialized):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
+ (JSC::JSObject::createInitialIndexedStorage):
+ (JSC::JSObject::createArrayStorage):
+ (JSC::JSObject::constructConvertedArrayStorageWithoutCopyingElements):
+ (JSC::JSObject::increaseVectorLength):
+ (JSC::JSObject::ensureLengthSlow):
+ (JSC::JSObject::growOutOfLineStorage):
+ * runtime/JSObject.h:
+ (JSC::JSObject::JSObject):
+ * runtime/Operations.h:
+ * runtime/RegExpMatchesArray.cpp:
+ (JSC::RegExpMatchesArray::create):
+ * runtime/StructureInlines.h:
+ (JSC):
+ * runtime/WriteBarrier.h:
+ (JSC):
+
+2013-05-27 Filip Pizlo <fpizlo@apple.com>
+
testRunner should be able to tell you if a function is DFG compiled
https://bugs.webkit.org/show_bug.cgi?id=116847
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index baf11e8..c4c19a5 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -1486,7 +1486,7 @@
NativeCallFrameTracer tracer(&vm, exec);
return reinterpret_cast<char*>(
- Butterfly::createUninitialized(vm, 0, initialOutOfLineCapacity, false, 0));
+ Butterfly::createUninitialized(vm, 0, 0, initialOutOfLineCapacity, false, 0));
}
char* DFG_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize)
@@ -1495,7 +1495,7 @@
NativeCallFrameTracer tracer(&vm, exec);
return reinterpret_cast<char*>(
- Butterfly::createUninitialized(vm, 0, newSize, false, 0));
+ Butterfly::createUninitialized(vm, 0, 0, newSize, false, 0));
}
char* DFG_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp
index 96ffbd6..9741cf5 100644
--- a/Source/JavaScriptCore/heap/Heap.cpp
+++ b/Source/JavaScriptCore/heap/Heap.cpp
@@ -702,6 +702,10 @@
void Heap::collect(SweepToggle sweepToggle)
{
+#if ENABLE(ALLOCATION_LOGGING)
+ dataLogF("JSC GC starting collection.\n");
+#endif
+
SamplingRegion samplingRegion("Garbage Collection");
RELEASE_ASSERT(!m_deferralDepth);
@@ -814,6 +818,10 @@
if (Options::showObjectStatistics())
HeapStatistics::showObjectStatistics(this);
+
+#if ENABLE(ALLOCATION_LOGGING)
+ dataLogF("JSC GC finishing collection.\n");
+#endif
}
bool Heap::collectIfNecessaryOrDefer()
diff --git a/Source/JavaScriptCore/heap/Heap.h b/Source/JavaScriptCore/heap/Heap.h
index 6df105e..720a94a 100644
--- a/Source/JavaScriptCore/heap/Heap.h
+++ b/Source/JavaScriptCore/heap/Heap.h
@@ -119,8 +119,9 @@
MarkedAllocator& allocatorForObjectWithNormalDestructor(size_t bytes) { return m_objectSpace.normalDestructorAllocatorFor(bytes); }
MarkedAllocator& allocatorForObjectWithImmortalStructureDestructor(size_t bytes) { return m_objectSpace.immortalStructureDestructorAllocatorFor(bytes); }
CopiedAllocator& storageAllocator() { return m_storageSpace.allocator(); }
- CheckedBoolean tryAllocateStorage(size_t, void**);
- CheckedBoolean tryReallocateStorage(void**, size_t, size_t);
+ CheckedBoolean tryAllocateStorage(JSCell* intendedOwner, size_t, void**);
+ CheckedBoolean tryReallocateStorage(JSCell* intendedOwner, void**, size_t, size_t);
+ void ascribeOwner(JSCell* intendedOwner, void*);
typedef void (*Finalizer)(JSCell*);
JS_EXPORT_PRIVATE void addFinalizer(JSCell*, Finalizer);
@@ -384,30 +385,64 @@
inline void* Heap::allocateWithNormalDestructor(size_t bytes)
{
+#if ENABLE(ALLOCATION_LOGGING)
+ dataLogF("JSC GC allocating %lu bytes with normal destructor.\n", bytes);
+#endif
ASSERT(isValidAllocation(bytes));
return m_objectSpace.allocateWithNormalDestructor(bytes);
}
inline void* Heap::allocateWithImmortalStructureDestructor(size_t bytes)
{
+#if ENABLE(ALLOCATION_LOGGING)
+ dataLogF("JSC GC allocating %lu bytes with immortal structure destructor.\n", bytes);
+#endif
ASSERT(isValidAllocation(bytes));
return m_objectSpace.allocateWithImmortalStructureDestructor(bytes);
}
inline void* Heap::allocateWithoutDestructor(size_t bytes)
{
+#if ENABLE(ALLOCATION_LOGGING)
+ dataLogF("JSC GC allocating %lu bytes without destructor.\n", bytes);
+#endif
ASSERT(isValidAllocation(bytes));
return m_objectSpace.allocateWithoutDestructor(bytes);
}
- inline CheckedBoolean Heap::tryAllocateStorage(size_t bytes, void** outPtr)
+ inline CheckedBoolean Heap::tryAllocateStorage(JSCell* intendedOwner, size_t bytes, void** outPtr)
{
- return m_storageSpace.tryAllocate(bytes, outPtr);
+ CheckedBoolean result = m_storageSpace.tryAllocate(bytes, outPtr);
+#if ENABLE(ALLOCATION_LOGGING)
+ dataLogF("JSC GC allocating %lu bytes of storage for %p: %p.\n", bytes, intendedOwner, *outPtr);
+#else
+ UNUSED_PARAM(intendedOwner);
+#endif
+ return result;
}
- inline CheckedBoolean Heap::tryReallocateStorage(void** ptr, size_t oldSize, size_t newSize)
+ inline CheckedBoolean Heap::tryReallocateStorage(JSCell* intendedOwner, void** ptr, size_t oldSize, size_t newSize)
{
- return m_storageSpace.tryReallocate(ptr, oldSize, newSize);
+#if ENABLE(ALLOCATION_LOGGING)
+ void* oldPtr = *ptr;
+#endif
+ CheckedBoolean result = m_storageSpace.tryReallocate(ptr, oldSize, newSize);
+#if ENABLE(ALLOCATION_LOGGING)
+ dataLogF("JSC GC reallocating %lu -> %lu bytes of storage for %p: %p -> %p.\n", oldSize, newSize, intendedOwner, oldPtr, *ptr);
+#else
+ UNUSED_PARAM(intendedOwner);
+#endif
+ return result;
+ }
+
+ inline void Heap::ascribeOwner(JSCell* intendedOwner, void* storage)
+ {
+#if ENABLE(ALLOCATION_LOGGING)
+ dataLogF("JSC GC ascribing %p as owner of storage %p.\n", intendedOwner, storage);
+#else
+ UNUSED_PARAM(intendedOwner);
+ UNUSED_PARAM(storage);
+#endif
}
inline BlockAllocator& Heap::blockAllocator()
diff --git a/Source/JavaScriptCore/heap/SlotVisitor.cpp b/Source/JavaScriptCore/heap/SlotVisitor.cpp
index 6c2ded0..f0d5e57 100644
--- a/Source/JavaScriptCore/heap/SlotVisitor.cpp
+++ b/Source/JavaScriptCore/heap/SlotVisitor.cpp
@@ -65,7 +65,7 @@
JSCell** roots = conservativeRoots.roots();
size_t size = conservativeRoots.size();
for (size_t i = 0; i < size; ++i)
- internalAppend(roots[i]);
+ internalAppend(0, roots[i]);
}
ALWAYS_INLINE static void visitChildren(SlotVisitor& visitor, const JSCell* cell)
@@ -279,7 +279,7 @@
return ((length() > 1) && !isRope() && !isHashConsSingleton());
}
-ALWAYS_INLINE void SlotVisitor::internalAppend(JSValue* slot)
+ALWAYS_INLINE void SlotVisitor::internalAppend(void* from, JSValue* slot)
{
// This internalAppend is only intended for visits to object and array backing stores.
// as it can change the JSValue pointed to be the argument when the original JSValue
@@ -316,7 +316,7 @@
}
}
- internalAppend(cell);
+ internalAppend(from, cell);
}
void SlotVisitor::harvestWeakReferences()
diff --git a/Source/JavaScriptCore/heap/SlotVisitor.h b/Source/JavaScriptCore/heap/SlotVisitor.h
index e1808fa..b596e2d 100644
--- a/Source/JavaScriptCore/heap/SlotVisitor.h
+++ b/Source/JavaScriptCore/heap/SlotVisitor.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -106,10 +106,10 @@
void append(JSValue*);
void append(JSValue*, size_t count);
void append(JSCell**);
-
- void internalAppend(JSCell*);
- void internalAppend(JSValue);
- void internalAppend(JSValue*);
+
+ void internalAppend(void* from, JSCell*);
+ void internalAppend(void* from, JSValue);
+ void internalAppend(void* from, JSValue*);
JS_EXPORT_PRIVATE void mergeOpaqueRoots();
void mergeOpaqueRootsIfNecessary();
diff --git a/Source/JavaScriptCore/heap/SlotVisitorInlines.h b/Source/JavaScriptCore/heap/SlotVisitorInlines.h
index 4273a28..e308dd4 100644
--- a/Source/JavaScriptCore/heap/SlotVisitorInlines.h
+++ b/Source/JavaScriptCore/heap/SlotVisitorInlines.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -39,7 +39,7 @@
{
for (size_t i = 0; i < count; ++i) {
JSValue& value = slot[i];
- internalAppend(value);
+ internalAppend(&value, value);
}
}
@@ -48,25 +48,25 @@
{
ASSERT(slot);
JSCell* cell = *slot;
- internalAppend(cell);
+ internalAppend(slot, cell);
}
ALWAYS_INLINE void SlotVisitor::append(JSValue* slot)
{
ASSERT(slot);
- internalAppend(*slot);
+ internalAppend(slot, *slot);
}
ALWAYS_INLINE void SlotVisitor::appendUnbarrieredValue(JSValue* slot)
{
ASSERT(slot);
- internalAppend(*slot);
+ internalAppend(slot, *slot);
}
ALWAYS_INLINE void SlotVisitor::append(JSCell** slot)
{
ASSERT(slot);
- internalAppend(*slot);
+ internalAppend(slot, *slot);
}
template<typename T>
@@ -74,14 +74,50 @@
{
ASSERT(weak);
if (weak->get())
- internalAppend(weak->get());
+ internalAppend(0, weak->get());
}
-ALWAYS_INLINE void SlotVisitor::internalAppend(JSValue value)
+ALWAYS_INLINE void SlotVisitor::internalAppend(void* from, JSValue value)
{
if (!value || !value.isCell())
return;
- internalAppend(value.asCell());
+ internalAppend(from, value.asCell());
+}
+
+ALWAYS_INLINE void SlotVisitor::internalAppend(void* from, JSCell* cell)
+{
+ ASSERT(!m_isCheckingForDefaultMarkViolation);
+ if (!cell)
+ return;
+#if ENABLE(ALLOCATION_LOGGING)
+ dataLogF("JSC GC noticing reference from %p to %p.\n", from, cell);
+#else
+ UNUSED_PARAM(from);
+#endif
+#if ENABLE(GC_VALIDATION)
+ validate(cell);
+#endif
+ if (Heap::testAndSetMarked(cell) || !cell->structure())
+ return;
+
+ m_visitCount++;
+
+ MARK_LOG_CHILD(*this, cell);
+
+ // Should never attempt to mark something that is zapped.
+ ASSERT(!cell->isZapped());
+
+ m_stack.append(cell);
+}
+
+template<typename T> inline void SlotVisitor::append(WriteBarrierBase<T>* slot)
+{
+ internalAppend(slot, *slot->slot());
+}
+
+ALWAYS_INLINE void SlotVisitor::appendValues(WriteBarrierBase<Unknown>* barriers, size_t count)
+{
+ append(barriers->slot(), count);
}
inline void SlotVisitor::addWeakReferenceHarvester(WeakReferenceHarvester* weakReferenceHarvester)
diff --git a/Source/JavaScriptCore/jit/JITWriteBarrier.h b/Source/JavaScriptCore/jit/JITWriteBarrier.h
index 9da1ea7..ca2ca6e 100644
--- a/Source/JavaScriptCore/jit/JITWriteBarrier.h
+++ b/Source/JavaScriptCore/jit/JITWriteBarrier.h
@@ -137,7 +137,7 @@
template<typename T> inline void SlotVisitor::append(JITWriteBarrier<T>* slot)
{
- internalAppend(slot->get());
+ internalAppend(0, slot->get());
}
}
diff --git a/Source/JavaScriptCore/llint/LLIntCommon.h b/Source/JavaScriptCore/llint/LLIntCommon.h
index 1797ff0..61ffe18 100644
--- a/Source/JavaScriptCore/llint/LLIntCommon.h
+++ b/Source/JavaScriptCore/llint/LLIntCommon.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,7 +34,11 @@
// Disable inline allocation in the interpreter. This is great if you're changing
// how the GC allocates.
+#if ENABLE(ALLOCATION_LOGGING)
+#define LLINT_ALWAYS_ALLOCATE_SLOW 1
+#else
#define LLINT_ALWAYS_ALLOCATE_SLOW 0
+#endif
// Disable inline caching of get_by_id and put_by_id.
#define LLINT_ALWAYS_ACCESS_SLOW 0
@@ -42,7 +46,7 @@
// Enable OSR into the JIT. Disabling this while the LLInt is enabled effectively
// turns off all JIT'ing, since in LLInt's parlance, OSR subsumes any form of JIT
// invocation.
-#if ENABLE(JIT)
+#if ENABLE(JIT) && !ENABLE(ALLOCATION_LOGGING)
#define LLINT_OSR_TO_JIT 1
#else
#define LLINT_OSR_TO_JIT 0
diff --git a/Source/JavaScriptCore/runtime/Butterfly.h b/Source/JavaScriptCore/runtime/Butterfly.h
index eb6d82a..3fc0077 100644
--- a/Source/JavaScriptCore/runtime/Butterfly.h
+++ b/Source/JavaScriptCore/runtime/Butterfly.h
@@ -104,10 +104,10 @@
static ptrdiff_t offsetOfPublicLength() { return offsetOfIndexingHeader() + IndexingHeader::offsetOfPublicLength(); }
static ptrdiff_t offsetOfVectorLength() { return offsetOfIndexingHeader() + IndexingHeader::offsetOfVectorLength(); }
- static Butterfly* createUninitialized(VM&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes);
+ static Butterfly* createUninitialized(VM&, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes);
- static Butterfly* create(VM&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader&, size_t indexingPayloadSizeInBytes);
- static Butterfly* create(VM&, Structure*);
+ static Butterfly* create(VM&, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader&, size_t indexingPayloadSizeInBytes);
+ static Butterfly* create(VM&, JSCell* intendedOwner, Structure*);
static Butterfly* createUninitializedDuringCollection(CopyVisitor&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes);
IndexingHeader* indexingHeader() { return IndexingHeader::from(this); }
@@ -147,20 +147,23 @@
void* base(size_t preCapacity, size_t propertyCapacity) { return propertyStorage() - propertyCapacity - preCapacity; }
void* base(Structure*);
- static Butterfly* createOrGrowArrayRight(Butterfly*, VM&, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes);
+ static Butterfly* createOrGrowArrayRight(
+ Butterfly*, VM&, JSCell* intendedOwner, Structure* oldStructure,
+ size_t propertyCapacity, bool hadIndexingHeader,
+ size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes);
// The butterfly reallocation methods perform the reallocation itself but do not change any
// of the meta-data to reflect that the reallocation occurred. Note that this set of
// methods is not exhaustive and is not intended to encapsulate all possible allocation
// modes of butterflies - there are code paths that allocate butterflies by calling
// directly into Heap::tryAllocateStorage.
- Butterfly* growPropertyStorage(VM&, size_t preCapacity, size_t oldPropertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes, size_t newPropertyCapacity);
- Butterfly* growPropertyStorage(VM&, Structure* oldStructure, size_t oldPropertyCapacity, size_t newPropertyCapacity);
- Butterfly* growPropertyStorage(VM&, Structure* oldStructure, size_t newPropertyCapacity);
- Butterfly* growArrayRight(VM&, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes); // Assumes that preCapacity is zero, and asserts as much.
- Butterfly* growArrayRight(VM&, Structure*, size_t newIndexingPayloadSizeInBytes);
- Butterfly* resizeArray(VM&, size_t propertyCapacity, bool oldHasIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newPreCapacity, bool newHasIndexingHeader, size_t newIndexingPayloadSizeInBytes);
- Butterfly* resizeArray(VM&, Structure*, size_t newPreCapacity, size_t newIndexingPayloadSizeInBytes); // Assumes that you're not changing whether or not the object has an indexing header.
+ Butterfly* growPropertyStorage(VM&, JSCell* intendedOwner, size_t preCapacity, size_t oldPropertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes, size_t newPropertyCapacity);
+ Butterfly* growPropertyStorage(VM&, JSCell* intendedOwner, Structure* oldStructure, size_t oldPropertyCapacity, size_t newPropertyCapacity);
+ Butterfly* growPropertyStorage(VM&, JSCell* intendedOwner, Structure* oldStructure, size_t newPropertyCapacity);
+ Butterfly* growArrayRight(VM&, JSCell* intendedOwner, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes); // Assumes that preCapacity is zero, and asserts as much.
+ Butterfly* growArrayRight(VM&, JSCell* intendedOwner, Structure*, size_t newIndexingPayloadSizeInBytes);
+ Butterfly* resizeArray(VM&, JSCell* intendedOwner, size_t propertyCapacity, bool oldHasIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newPreCapacity, bool newHasIndexingHeader, size_t newIndexingPayloadSizeInBytes);
+ Butterfly* resizeArray(VM&, JSCell* intendedOwner, Structure*, size_t newPreCapacity, size_t newIndexingPayloadSizeInBytes); // Assumes that you're not changing whether or not the object has an indexing header.
Butterfly* unshift(Structure*, size_t numberOfSlots);
Butterfly* shift(Structure*, size_t numberOfSlots);
};
diff --git a/Source/JavaScriptCore/runtime/ButterflyInlines.h b/Source/JavaScriptCore/runtime/ButterflyInlines.h
index a0e2af1..44f23b6 100644
--- a/Source/JavaScriptCore/runtime/ButterflyInlines.h
+++ b/Source/JavaScriptCore/runtime/ButterflyInlines.h
@@ -35,27 +35,30 @@
namespace JSC {
-inline Butterfly* Butterfly::createUninitialized(VM& vm, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::createUninitialized(VM& vm, JSCell* intendedOwner, 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(size, &temp));
+ RELEASE_ASSERT(vm.heap.tryAllocateStorage(intendedOwner, size, &temp));
Butterfly* result = fromBase(temp, preCapacity, propertyCapacity);
return result;
}
-inline Butterfly* Butterfly::create(VM& vm, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::create(VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes)
{
Butterfly* result = createUninitialized(
- vm, preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);
+ vm, intendedOwner, preCapacity, propertyCapacity, hasIndexingHeader,
+ indexingPayloadSizeInBytes);
if (hasIndexingHeader)
*result->indexingHeader() = indexingHeader;
return result;
}
-inline Butterfly* Butterfly::create(VM& vm, Structure* structure)
+inline Butterfly* Butterfly::create(VM& vm, JSCell* intendedOwner, Structure* structure)
{
- return create(vm, 0, structure->outOfLineCapacity(), hasIndexingHeader(structure->indexingType()), IndexingHeader(), 0);
+ return create(
+ vm, intendedOwner, 0, structure->outOfLineCapacity(),
+ hasIndexingHeader(structure->indexingType()), IndexingHeader(), 0);
}
inline Butterfly* Butterfly::createUninitializedDuringCollection(CopyVisitor& visitor, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes)
@@ -72,11 +75,14 @@
return base(indexingHeader()->preCapacity(structure), structure->outOfLineCapacity());
}
-inline Butterfly* Butterfly::growPropertyStorage(VM& vm, size_t preCapacity, size_t oldPropertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes, size_t newPropertyCapacity)
+inline Butterfly* Butterfly::growPropertyStorage(
+ VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t oldPropertyCapacity,
+ bool hasIndexingHeader, size_t indexingPayloadSizeInBytes, size_t newPropertyCapacity)
{
RELEASE_ASSERT(newPropertyCapacity > oldPropertyCapacity);
Butterfly* result = createUninitialized(
- vm, preCapacity, newPropertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);
+ vm, intendedOwner, preCapacity, newPropertyCapacity, hasIndexingHeader,
+ indexingPayloadSizeInBytes);
memcpy(
result->propertyStorage() - oldPropertyCapacity,
propertyStorage() - oldPropertyCapacity,
@@ -84,51 +90,72 @@
return result;
}
-inline Butterfly* Butterfly::growPropertyStorage(VM& vm, Structure* structure, size_t oldPropertyCapacity, size_t newPropertyCapacity)
+inline Butterfly* Butterfly::growPropertyStorage(
+ VM& vm, JSCell* intendedOwner, Structure* structure, size_t oldPropertyCapacity,
+ size_t newPropertyCapacity)
{
return growPropertyStorage(
- vm, indexingHeader()->preCapacity(structure), oldPropertyCapacity,
+ vm, intendedOwner, indexingHeader()->preCapacity(structure), oldPropertyCapacity,
hasIndexingHeader(structure->indexingType()),
indexingHeader()->indexingPayloadSizeInBytes(structure), newPropertyCapacity);
}
-inline Butterfly* Butterfly::growPropertyStorage(VM& vm, Structure* oldStructure, size_t newPropertyCapacity)
+inline Butterfly* Butterfly::growPropertyStorage(
+ VM& vm, JSCell* intendedOwner, Structure* oldStructure, size_t newPropertyCapacity)
{
return growPropertyStorage(
- vm, oldStructure, oldStructure->outOfLineCapacity(), newPropertyCapacity);
+ vm, intendedOwner, oldStructure, oldStructure->outOfLineCapacity(),
+ newPropertyCapacity);
}
-inline Butterfly* Butterfly::createOrGrowArrayRight(Butterfly* oldButterfly, VM& vm, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::createOrGrowArrayRight(
+ Butterfly* oldButterfly, VM& vm, JSCell* intendedOwner, Structure* oldStructure,
+ size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes,
+ size_t newIndexingPayloadSizeInBytes)
{
- if (!oldButterfly)
- return create(vm, 0, propertyCapacity, true, IndexingHeader(), newIndexingPayloadSizeInBytes);
- return oldButterfly->growArrayRight(vm, oldStructure, propertyCapacity, hadIndexingHeader, oldIndexingPayloadSizeInBytes, newIndexingPayloadSizeInBytes);
+ if (!oldButterfly) {
+ return create(
+ vm, intendedOwner, 0, propertyCapacity, true, IndexingHeader(),
+ newIndexingPayloadSizeInBytes);
+ }
+ return oldButterfly->growArrayRight(
+ vm, intendedOwner, oldStructure, propertyCapacity, hadIndexingHeader,
+ oldIndexingPayloadSizeInBytes, newIndexingPayloadSizeInBytes);
}
-inline Butterfly* Butterfly::growArrayRight(VM& vm, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::growArrayRight(
+ VM& vm, JSCell* intendedOwner, Structure* oldStructure, size_t propertyCapacity,
+ bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes,
+ size_t newIndexingPayloadSizeInBytes)
{
ASSERT_UNUSED(oldStructure, !indexingHeader()->preCapacity(oldStructure));
ASSERT_UNUSED(oldStructure, hadIndexingHeader == hasIndexingHeader(oldStructure->indexingType()));
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(&theBase, oldSize, newSize))
+ if (!vm.heap.tryReallocateStorage(intendedOwner, &theBase, oldSize, newSize))
return 0;
return fromBase(theBase, 0, propertyCapacity);
}
-inline Butterfly* Butterfly::growArrayRight(VM& vm, Structure* oldStructure, size_t newIndexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::growArrayRight(
+ VM& vm, JSCell* intendedOwner, Structure* oldStructure,
+ size_t newIndexingPayloadSizeInBytes)
{
return growArrayRight(
- vm, oldStructure, oldStructure->outOfLineCapacity(),
+ vm, intendedOwner, oldStructure, oldStructure->outOfLineCapacity(),
hasIndexingHeader(oldStructure->indexingType()),
indexingHeader()->indexingPayloadSizeInBytes(oldStructure), newIndexingPayloadSizeInBytes);
}
-inline Butterfly* Butterfly::resizeArray(VM& vm, size_t propertyCapacity, bool oldHasIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newPreCapacity, bool newHasIndexingHeader, size_t newIndexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::resizeArray(
+ VM& vm, JSCell* intendedOwner, size_t propertyCapacity, bool oldHasIndexingHeader,
+ size_t oldIndexingPayloadSizeInBytes, size_t newPreCapacity, bool newHasIndexingHeader,
+ size_t newIndexingPayloadSizeInBytes)
{
Butterfly* result = createUninitialized(
- vm, newPreCapacity, propertyCapacity, newHasIndexingHeader, newIndexingPayloadSizeInBytes);
+ vm, intendedOwner, newPreCapacity, propertyCapacity, newHasIndexingHeader,
+ newIndexingPayloadSizeInBytes);
// FIXME: This could be made much more efficient if we used the property size,
// not the capacity.
void* to = result->propertyStorage() - propertyCapacity;
@@ -140,11 +167,13 @@
return result;
}
-inline Butterfly* Butterfly::resizeArray(VM& vm, Structure* structure, size_t newPreCapacity, size_t newIndexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::resizeArray(
+ VM& vm, JSCell* intendedOwner, Structure* structure, size_t newPreCapacity,
+ size_t newIndexingPayloadSizeInBytes)
{
bool hasIndexingHeader = JSC::hasIndexingHeader(structure->indexingType());
return resizeArray(
- vm, structure->outOfLineCapacity(), hasIndexingHeader,
+ vm, intendedOwner, structure->outOfLineCapacity(), hasIndexingHeader,
indexingHeader()->indexingPayloadSizeInBytes(structure), newPreCapacity,
hasIndexingHeader, newIndexingPayloadSizeInBytes);
}
diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp
index f97cced..b3df4ab 100644
--- a/Source/JavaScriptCore/runtime/JSArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSArray.cpp
@@ -48,10 +48,11 @@
const ClassInfo JSArray::s_info = {"Array", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSArray)};
-Butterfly* createArrayButterflyInDictionaryIndexingMode(VM& vm, unsigned initialLength)
+Butterfly* createArrayButterflyInDictionaryIndexingMode(
+ VM& vm, JSCell* intendedOwner, unsigned initialLength)
{
Butterfly* butterfly = Butterfly::create(
- vm, 0, 0, true, IndexingHeader(), ArrayStorage::sizeFor(0));
+ vm, intendedOwner, 0, 0, true, IndexingHeader(), ArrayStorage::sizeFor(0));
ArrayStorage* storage = butterfly->arrayStorage();
storage->setLength(initialLength);
storage->setVectorLength(0);
@@ -286,7 +287,7 @@
newStorageCapacity = currentCapacity;
} else {
size_t newSize = Butterfly::totalSize(0, propertyCapacity, true, ArrayStorage::sizeFor(desiredCapacity));
- if (!vm.heap.tryAllocateStorage(newSize, &newAllocBase))
+ if (!vm.heap.tryAllocateStorage(this, newSize, &newAllocBase))
return false;
newStorageCapacity = desiredCapacity;
}
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index af81d2e..6da3397 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -174,21 +174,22 @@
void compactForSorting(unsigned& numDefined, unsigned& newRelevantLength);
};
-inline Butterfly* createContiguousArrayButterfly(VM& vm, unsigned length, unsigned& vectorLength)
+inline Butterfly* createContiguousArrayButterfly(VM& vm, JSCell* intendedOwner, unsigned length, unsigned& vectorLength)
{
IndexingHeader header;
vectorLength = std::max(length, BASE_VECTOR_LEN);
header.setVectorLength(vectorLength);
header.setPublicLength(length);
Butterfly* result = Butterfly::create(
- vm, 0, 0, true, header, vectorLength * sizeof(EncodedJSValue));
+ vm, intendedOwner, 0, 0, true, header, vectorLength * sizeof(EncodedJSValue));
return result;
}
-inline Butterfly* createArrayButterfly(VM& vm, unsigned initialLength)
+inline Butterfly* createArrayButterfly(VM& vm, JSCell* intendedOwner, unsigned initialLength)
{
Butterfly* butterfly = Butterfly::create(
- vm, 0, 0, true, baseIndexingHeaderForArray(initialLength), ArrayStorage::sizeFor(BASE_VECTOR_LEN));
+ vm, intendedOwner, 0, 0, true, baseIndexingHeaderForArray(initialLength),
+ ArrayStorage::sizeFor(BASE_VECTOR_LEN));
ArrayStorage* storage = butterfly->arrayStorage();
storage->m_indexBias = 0;
storage->m_sparseMap.clear();
@@ -196,7 +197,8 @@
return butterfly;
}
-Butterfly* createArrayButterflyInDictionaryIndexingMode(VM&, unsigned initialLength);
+Butterfly* createArrayButterflyInDictionaryIndexingMode(
+ VM&, JSCell* intendedOwner, unsigned initialLength);
inline JSArray* JSArray::create(VM& vm, Structure* structure, unsigned initialLength)
{
@@ -208,7 +210,7 @@
|| hasDouble(structure->indexingType())
|| hasContiguous(structure->indexingType()));
unsigned vectorLength;
- butterfly = createContiguousArrayButterfly(vm, initialLength, vectorLength);
+ butterfly = createContiguousArrayButterfly(vm, 0, initialLength, vectorLength);
ASSERT(initialLength < MIN_SPARSE_ARRAY_INDEX);
if (hasDouble(structure->indexingType())) {
for (unsigned i = 0; i < vectorLength; ++i)
@@ -218,7 +220,7 @@
ASSERT(
structure->indexingType() == ArrayWithSlowPutArrayStorage
|| structure->indexingType() == ArrayWithArrayStorage);
- butterfly = createArrayButterfly(vm, initialLength);
+ butterfly = createArrayButterfly(vm, 0, initialLength);
}
JSArray* array = new (NotNull, allocateCell<JSArray>(vm.heap)) JSArray(vm, structure, butterfly);
array->finishCreation(vm);
@@ -240,7 +242,7 @@
|| hasContiguous(structure->indexingType()));
void* temp;
- if (!vm.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)), &temp))
+ if (!vm.heap.tryAllocateStorage(0, Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)), &temp))
return 0;
butterfly = Butterfly::fromBase(temp, 0, 0);
butterfly->setVectorLength(vectorLength);
@@ -251,7 +253,7 @@
}
} else {
void* temp;
- if (!vm.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(vectorLength)), &temp))
+ if (!vm.heap.tryAllocateStorage(0, Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(vectorLength)), &temp))
return 0;
butterfly = Butterfly::fromBase(temp, 0, 0);
*butterfly->indexingHeader() = indexingHeaderForArray(initialLength, vectorLength);
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index 2f1f274..40eda92 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -543,7 +543,7 @@
map->add(this, i).iterator->value.set(vm, this, value);
}
- Butterfly* newButterfly = storage->butterfly()->resizeArray(vm, structure(), 0, ArrayStorage::sizeFor(0));
+ Butterfly* newButterfly = storage->butterfly()->resizeArray(vm, this, structure(), 0, ArrayStorage::sizeFor(0));
RELEASE_ASSERT(newButterfly);
m_butterfly = newButterfly;
@@ -596,8 +596,8 @@
ASSERT(!structure()->needsSlowPutIndexing());
ASSERT(!indexingShouldBeSparse());
unsigned vectorLength = std::max(length, BASE_VECTOR_LEN);
- Butterfly* newButterfly = Butterfly::createOrGrowArrayRight(m_butterfly,
- vm, structure(), structure()->outOfLineCapacity(), false, 0,
+ Butterfly* newButterfly = Butterfly::createOrGrowArrayRight(
+ m_butterfly, vm, this, structure(), structure()->outOfLineCapacity(), false, 0,
elementSize * vectorLength);
newButterfly->setPublicLength(length);
newButterfly->setVectorLength(vectorLength);
@@ -642,8 +642,8 @@
{
IndexingType oldType = structure()->indexingType();
ASSERT_UNUSED(oldType, !hasIndexedProperties(oldType));
- Butterfly* newButterfly = Butterfly::createOrGrowArrayRight(m_butterfly,
- vm, structure(), structure()->outOfLineCapacity(), false, 0,
+ Butterfly* newButterfly = Butterfly::createOrGrowArrayRight(
+ m_butterfly, vm, this, structure(), structure()->outOfLineCapacity(), false, 0,
ArrayStorage::sizeFor(vectorLength));
RELEASE_ASSERT(newButterfly);
@@ -695,7 +695,7 @@
unsigned propertySize = structure()->outOfLineSize();
Butterfly* newButterfly = Butterfly::createUninitialized(
- vm, 0, propertyCapacity, true, ArrayStorage::sizeFor(neededLength));
+ vm, this, 0, propertyCapacity, true, ArrayStorage::sizeFor(neededLength));
memcpy(
newButterfly->propertyStorage() - propertySize,
@@ -2310,7 +2310,9 @@
// Fast case - there is no precapacity. In these cases a realloc makes sense.
if (LIKELY(!indexBias)) {
- Butterfly* newButterfly = storage->butterfly()->growArrayRight(vm, structure(), structure()->outOfLineCapacity(), true, ArrayStorage::sizeFor(vectorLength), ArrayStorage::sizeFor(newVectorLength));
+ Butterfly* newButterfly = storage->butterfly()->growArrayRight(
+ vm, this, structure(), structure()->outOfLineCapacity(), true,
+ ArrayStorage::sizeFor(vectorLength), ArrayStorage::sizeFor(newVectorLength));
if (!newButterfly)
return false;
m_butterfly = newButterfly;
@@ -2321,7 +2323,7 @@
// Remove some, but not all of the precapacity. Atomic decay, & capped to not overflow array length.
unsigned newIndexBias = std::min(indexBias >> 1, MAX_STORAGE_VECTOR_LENGTH - newVectorLength);
Butterfly* newButterfly = storage->butterfly()->resizeArray(
- vm,
+ vm, this,
structure()->outOfLineCapacity(), true, ArrayStorage::sizeFor(vectorLength),
newIndexBias, true, ArrayStorage::sizeFor(newVectorLength));
if (!newButterfly)
@@ -2344,7 +2346,7 @@
MAX_STORAGE_VECTOR_LENGTH);
unsigned oldVectorLength = m_butterfly->vectorLength();
m_butterfly = m_butterfly->growArrayRight(
- vm, structure(), structure()->outOfLineCapacity(), true,
+ vm, this, structure(), structure()->outOfLineCapacity(), true,
oldVectorLength * sizeof(EncodedJSValue),
newVectorLength * sizeof(EncodedJSValue));
if (hasDouble(structure()->indexingType())) {
@@ -2361,7 +2363,7 @@
// It's important that this function not rely on structure(), for the property
// capacity, since we might have already mutated the structure in-place.
- return m_butterfly->growPropertyStorage(vm, structure(), oldSize, newSize);
+ return m_butterfly->growPropertyStorage(vm, this, structure(), oldSize, newSize);
}
bool JSObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index a5a2545..143080d 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -39,7 +39,6 @@
#include "Structure.h"
#include "VM.h"
#include "JSString.h"
-#include "SlotVisitorInlines.h"
#include "SparseArrayValueMap.h"
#include <wtf/StdLibExtras.h>
@@ -1145,6 +1144,7 @@
: JSCell(vm, structure)
, m_butterfly(butterfly)
{
+ vm.heap.ascribeOwner(this, butterfly);
}
inline JSValue JSObject::prototype() const
diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h
index afac130..1be012b 100644
--- a/Source/JavaScriptCore/runtime/Operations.h
+++ b/Source/JavaScriptCore/runtime/Operations.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2002, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2002, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -28,6 +28,7 @@
#include "JSFunctionInlines.h"
#include "JSProxy.h"
#include "JSString.h"
+#include "SlotVisitorInlines.h"
#include "StructureInlines.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
index 062650a..cb1da7c 100644
--- a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
@@ -46,7 +46,7 @@
{
ASSERT(result);
VM& vm = exec->vm();
- Butterfly* butterfly = createArrayButterfly(vm, regExp->numSubpatterns() + 1);
+ Butterfly* butterfly = createArrayButterfly(vm, 0, regExp->numSubpatterns() + 1);
RegExpMatchesArray* array = new (NotNull, allocateCell<RegExpMatchesArray>(vm.heap)) RegExpMatchesArray(vm, butterfly, exec->lexicalGlobalObject(), input, regExp, result);
array->finishCreation(vm);
return array;
diff --git a/Source/JavaScriptCore/runtime/StructureInlines.h b/Source/JavaScriptCore/runtime/StructureInlines.h
index a1d1d77..83e36d4 100644
--- a/Source/JavaScriptCore/runtime/StructureInlines.h
+++ b/Source/JavaScriptCore/runtime/StructureInlines.h
@@ -109,27 +109,6 @@
return typeInfo().masqueradesAsUndefined() && globalObject() == lexicalGlobalObject;
}
-ALWAYS_INLINE void SlotVisitor::internalAppend(JSCell* cell)
-{
- ASSERT(!m_isCheckingForDefaultMarkViolation);
- if (!cell)
- return;
-#if ENABLE(GC_VALIDATION)
- validate(cell);
-#endif
- if (Heap::testAndSetMarked(cell) || !cell->structure())
- return;
-
- m_visitCount++;
-
- MARK_LOG_CHILD(*this, cell);
-
- // Should never attempt to mark something that is zapped.
- ASSERT(!cell->isZapped());
-
- m_stack.append(cell);
-}
-
inline bool Structure::transitivelyTransitionedFrom(Structure* structureToFind)
{
for (Structure* current = this; current; current = current->previousID()) {
diff --git a/Source/JavaScriptCore/runtime/WriteBarrier.h b/Source/JavaScriptCore/runtime/WriteBarrier.h
index fe07cf5..db4fa22 100644
--- a/Source/JavaScriptCore/runtime/WriteBarrier.h
+++ b/Source/JavaScriptCore/runtime/WriteBarrier.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -227,18 +227,6 @@
return lhs.get() == rhs.get();
}
-// SlotVisitor functions
-
-template<typename T> inline void SlotVisitor::append(WriteBarrierBase<T>* slot)
-{
- internalAppend(*slot->slot());
-}
-
-ALWAYS_INLINE void SlotVisitor::appendValues(WriteBarrierBase<Unknown>* barriers, size_t count)
-{
- append(barriers->slot(), count);
-}
-
} // namespace JSC
#endif // WriteBarrier_h