summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-11-09 12:15:52 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2012-11-09 12:16:06 +0100
commitde4f791e30be4e4239b381c11745ffa4d87ddb8b (patch)
tree885e3a5d6670828b454cf676b4d42f78e28b1f0e /Source/JavaScriptCore/runtime
parentb022df48697d40cdabdeafb2c29bb14fe489b6fe (diff)
downloadqtwebkit-de4f791e30be4e4239b381c11745ffa4d87ddb8b.tar.gz
Imported WebKit commit e2c32e2f53e02d388e70b9db88b91d8d9d28fc84 (http://svn.webkit.org/repository/webkit/trunk@133952)
Revert back to an older snapshot that should build on ARM
Diffstat (limited to 'Source/JavaScriptCore/runtime')
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.h446
-rw-r--r--Source/JavaScriptCore/runtime/ArrayConstructor.cpp14
-rw-r--r--Source/JavaScriptCore/runtime/ArrayConstructor.h54
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.cpp16
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.h32
-rw-r--r--Source/JavaScriptCore/runtime/Butterfly.h6
-rw-r--r--Source/JavaScriptCore/runtime/ButterflyInlineMethods.h (renamed from Source/JavaScriptCore/runtime/ButterflyInlines.h)11
-rw-r--r--Source/JavaScriptCore/runtime/CodeCache.cpp37
-rw-r--r--Source/JavaScriptCore/runtime/CodeCache.h50
-rw-r--r--Source/JavaScriptCore/runtime/Executable.cpp5
-rw-r--r--Source/JavaScriptCore/runtime/Executable.h2
-rw-r--r--Source/JavaScriptCore/runtime/FunctionPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h (renamed from Source/JavaScriptCore/runtime/IndexingHeaderInlines.h)9
-rw-r--r--Source/JavaScriptCore/runtime/IndexingType.cpp55
-rw-r--r--Source/JavaScriptCore/runtime/IndexingType.h46
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.cpp454
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.h36
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.cpp28
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.h56
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.cpp661
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h229
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/JSValueInlineMethods.h (renamed from Source/JavaScriptCore/runtime/JSValueInlines.h)7
-rw-r--r--Source/JavaScriptCore/runtime/LiteralParser.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/ObjectConstructor.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/Operations.h2
-rw-r--r--Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/RegExpObject.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/StringPrototype.cpp26
-rw-r--r--Source/JavaScriptCore/runtime/Structure.cpp13
-rw-r--r--Source/JavaScriptCore/runtime/StructureTransitionTable.h20
33 files changed, 550 insertions, 1797 deletions
diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h
index 8ae991422..7961d4bc8 100644
--- a/Source/JavaScriptCore/runtime/Arguments.h
+++ b/Source/JavaScriptCore/runtime/Arguments.h
@@ -34,246 +34,246 @@
namespace JSC {
-class Arguments : public JSDestructibleObject {
- friend class JIT;
- friend class DFG::SpeculativeJIT;
-public:
- typedef JSDestructibleObject Base;
+ class Arguments : public JSDestructibleObject {
+ friend class JIT;
+ friend class DFG::SpeculativeJIT;
+ public:
+ typedef JSDestructibleObject Base;
+
+ static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame)
+ {
+ Arguments* arguments = new (NotNull, allocateCell<Arguments>(globalData.heap)) Arguments(callFrame);
+ arguments->finishCreation(callFrame);
+ return arguments;
+ }
+
+ static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
+ {
+ Arguments* arguments = new (NotNull, allocateCell<Arguments>(globalData.heap)) Arguments(callFrame);
+ arguments->finishCreation(callFrame, inlineCallFrame);
+ return arguments;
+ }
+
+ enum { MaxArguments = 0x10000 };
+
+ private:
+ enum NoParametersType { NoParameters };
+
+ Arguments(CallFrame*);
+ Arguments(CallFrame*, NoParametersType);
+
+ void tearOffForInlineCallFrame(JSGlobalData& globalData, Register*, InlineCallFrame*);
- static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame)
+ public:
+ static const ClassInfo s_info;
+
+ static void visitChildren(JSCell*, SlotVisitor&);
+
+ void fillArgList(ExecState*, MarkedArgumentBuffer&);
+
+ uint32_t length(ExecState* exec) const
+ {
+ if (UNLIKELY(m_overrodeLength))
+ return get(exec, exec->propertyNames().length).toUInt32(exec);
+ return m_numArguments;
+ }
+
+ void copyToArguments(ExecState*, CallFrame*, uint32_t length);
+ void tearOff(CallFrame*);
+ void tearOff(CallFrame*, InlineCallFrame*);
+ bool isTornOff() const { return m_registerArray; }
+ void didTearOffActivation(ExecState*, JSActivation*);
+
+ static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ {
+ return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ }
+
+ protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
+
+ void finishCreation(CallFrame*);
+ void finishCreation(CallFrame*, InlineCallFrame*);
+
+ private:
+ static void destroy(JSCell*);
+ static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
+ static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
+ static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
+ static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+ static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+ static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
+ static bool deleteProperty(JSCell*, ExecState*, PropertyName);
+ static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
+ static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
+ void createStrictModeCallerIfNecessary(ExecState*);
+ void createStrictModeCalleeIfNecessary(ExecState*);
+
+ bool isArgument(size_t);
+ bool trySetArgument(JSGlobalData&, size_t argument, JSValue);
+ JSValue tryGetArgument(size_t argument);
+ bool isDeletedArgument(size_t);
+ bool tryDeleteArgument(size_t);
+ WriteBarrierBase<Unknown>& argument(size_t);
+ void allocateSlowArguments();
+
+ void init(CallFrame*);
+
+ WriteBarrier<JSActivation> m_activation;
+
+ unsigned m_numArguments;
+
+ // We make these full byte booleans to make them easy to test from the JIT,
+ // and because even if they were single-bit booleans we still wouldn't save
+ // any space.
+ bool m_overrodeLength;
+ bool m_overrodeCallee;
+ bool m_overrodeCaller;
+ bool m_isStrictMode;
+
+ WriteBarrierBase<Unknown>* m_registers;
+ OwnArrayPtr<WriteBarrier<Unknown> > m_registerArray;
+
+ OwnArrayPtr<SlowArgument> m_slowArguments;
+
+ WriteBarrier<JSFunction> m_callee;
+ };
+
+ Arguments* asArguments(JSValue);
+
+ inline Arguments* asArguments(JSValue value)
{
- Arguments* arguments = new (NotNull, allocateCell<Arguments>(globalData.heap)) Arguments(callFrame);
- arguments->finishCreation(callFrame);
- return arguments;
+ ASSERT(asObject(value)->inherits(&Arguments::s_info));
+ return static_cast<Arguments*>(asObject(value));
}
-
- static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
+
+ inline Arguments::Arguments(CallFrame* callFrame)
+ : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
{
- Arguments* arguments = new (NotNull, allocateCell<Arguments>(globalData.heap)) Arguments(callFrame);
- arguments->finishCreation(callFrame, inlineCallFrame);
- return arguments;
}
- enum { MaxArguments = 0x10000 };
+ inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
+ : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
+ {
+ }
-private:
- enum NoParametersType { NoParameters };
-
- Arguments(CallFrame*);
- Arguments(CallFrame*, NoParametersType);
-
- void tearOffForInlineCallFrame(JSGlobalData& globalData, Register*, InlineCallFrame*);
+ inline void Arguments::allocateSlowArguments()
+ {
+ if (m_slowArguments)
+ return;
+ m_slowArguments = adoptArrayPtr(new SlowArgument[m_numArguments]);
+ for (size_t i = 0; i < m_numArguments; ++i) {
+ ASSERT(m_slowArguments[i].status == SlowArgument::Normal);
+ m_slowArguments[i].index = CallFrame::argumentOffset(i);
+ }
+ }
-public:
- static const ClassInfo s_info;
+ inline bool Arguments::tryDeleteArgument(size_t argument)
+ {
+ if (!isArgument(argument))
+ return false;
+ allocateSlowArguments();
+ m_slowArguments[argument].status = SlowArgument::Deleted;
+ return true;
+ }
- static void visitChildren(JSCell*, SlotVisitor&);
+ inline bool Arguments::trySetArgument(JSGlobalData& globalData, size_t argument, JSValue value)
+ {
+ if (!isArgument(argument))
+ return false;
+ this->argument(argument).set(globalData, this, value);
+ return true;
+ }
- void fillArgList(ExecState*, MarkedArgumentBuffer&);
+ inline JSValue Arguments::tryGetArgument(size_t argument)
+ {
+ if (!isArgument(argument))
+ return JSValue();
+ return this->argument(argument).get();
+ }
- uint32_t length(ExecState* exec) const
+ inline bool Arguments::isDeletedArgument(size_t argument)
{
- if (UNLIKELY(m_overrodeLength))
- return get(exec, exec->propertyNames().length).toUInt32(exec);
- return m_numArguments;
+ if (argument >= m_numArguments)
+ return false;
+ if (!m_slowArguments)
+ return false;
+ if (m_slowArguments[argument].status != SlowArgument::Deleted)
+ return false;
+ return true;
}
-
- void copyToArguments(ExecState*, CallFrame*, uint32_t length);
- void tearOff(CallFrame*);
- void tearOff(CallFrame*, InlineCallFrame*);
- bool isTornOff() const { return m_registerArray; }
- void didTearOffActivation(ExecState*, JSActivation*);
-
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
- {
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+
+ inline bool Arguments::isArgument(size_t argument)
+ {
+ if (argument >= m_numArguments)
+ return false;
+ if (m_slowArguments && m_slowArguments[argument].status == SlowArgument::Deleted)
+ return false;
+ return true;
}
-
-protected:
- static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
-
- void finishCreation(CallFrame*);
- void finishCreation(CallFrame*, InlineCallFrame*);
-
-private:
- static void destroy(JSCell*);
- static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
- static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
- static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
- static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
- static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
- static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
- static bool deleteProperty(JSCell*, ExecState*, PropertyName);
- static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
- static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
- void createStrictModeCallerIfNecessary(ExecState*);
- void createStrictModeCalleeIfNecessary(ExecState*);
-
- bool isArgument(size_t);
- bool trySetArgument(JSGlobalData&, size_t argument, JSValue);
- JSValue tryGetArgument(size_t argument);
- bool isDeletedArgument(size_t);
- bool tryDeleteArgument(size_t);
- WriteBarrierBase<Unknown>& argument(size_t);
- void allocateSlowArguments();
-
- void init(CallFrame*);
-
- WriteBarrier<JSActivation> m_activation;
-
- unsigned m_numArguments;
-
- // We make these full byte booleans to make them easy to test from the JIT,
- // and because even if they were single-bit booleans we still wouldn't save
- // any space.
- bool m_overrodeLength;
- bool m_overrodeCallee;
- bool m_overrodeCaller;
- bool m_isStrictMode;
-
- WriteBarrierBase<Unknown>* m_registers;
- OwnArrayPtr<WriteBarrier<Unknown> > m_registerArray;
-
- OwnArrayPtr<SlowArgument> m_slowArguments;
-
- WriteBarrier<JSFunction> m_callee;
-};
-
-Arguments* asArguments(JSValue);
-
-inline Arguments* asArguments(JSValue value)
-{
- ASSERT(asObject(value)->inherits(&Arguments::s_info));
- return static_cast<Arguments*>(asObject(value));
-}
-
-inline Arguments::Arguments(CallFrame* callFrame)
- : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
-{
-}
-
-inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
- : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
-{
-}
-
-inline void Arguments::allocateSlowArguments()
-{
- if (m_slowArguments)
- return;
- m_slowArguments = adoptArrayPtr(new SlowArgument[m_numArguments]);
- for (size_t i = 0; i < m_numArguments; ++i) {
- ASSERT(m_slowArguments[i].status == SlowArgument::Normal);
- m_slowArguments[i].index = CallFrame::argumentOffset(i);
+
+ inline WriteBarrierBase<Unknown>& Arguments::argument(size_t argument)
+ {
+ ASSERT(isArgument(argument));
+ if (!m_slowArguments)
+ return m_registers[CallFrame::argumentOffset(argument)];
+
+ int index = m_slowArguments[argument].index;
+ if (!m_activation || m_slowArguments[argument].status != SlowArgument::Captured)
+ return m_registers[index];
+
+ return m_activation->registerAt(index);
}
-}
-
-inline bool Arguments::tryDeleteArgument(size_t argument)
-{
- if (!isArgument(argument))
- return false;
- allocateSlowArguments();
- m_slowArguments[argument].status = SlowArgument::Deleted;
- return true;
-}
-
-inline bool Arguments::trySetArgument(JSGlobalData& globalData, size_t argument, JSValue value)
-{
- if (!isArgument(argument))
- return false;
- this->argument(argument).set(globalData, this, value);
- return true;
-}
-
-inline JSValue Arguments::tryGetArgument(size_t argument)
-{
- if (!isArgument(argument))
- return JSValue();
- return this->argument(argument).get();
-}
-
-inline bool Arguments::isDeletedArgument(size_t argument)
-{
- if (argument >= m_numArguments)
- return false;
- if (!m_slowArguments)
- return false;
- if (m_slowArguments[argument].status != SlowArgument::Deleted)
- return false;
- return true;
-}
-
-inline bool Arguments::isArgument(size_t argument)
-{
- if (argument >= m_numArguments)
- return false;
- if (m_slowArguments && m_slowArguments[argument].status == SlowArgument::Deleted)
- return false;
- return true;
-}
-
-inline WriteBarrierBase<Unknown>& Arguments::argument(size_t argument)
-{
- ASSERT(isArgument(argument));
- if (!m_slowArguments)
- return m_registers[CallFrame::argumentOffset(argument)];
-
- int index = m_slowArguments[argument].index;
- if (!m_activation || m_slowArguments[argument].status != SlowArgument::Captured)
- return m_registers[index];
-
- return m_activation->registerAt(index);
-}
-
-inline void Arguments::finishCreation(CallFrame* callFrame)
-{
- Base::finishCreation(callFrame->globalData());
- ASSERT(inherits(&s_info));
-
- JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
- m_numArguments = callFrame->argumentCount();
- m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers());
- m_callee.set(callFrame->globalData(), this, callee);
- m_overrodeLength = false;
- m_overrodeCallee = false;
- m_overrodeCaller = false;
- m_isStrictMode = callFrame->codeBlock()->isStrictMode();
-
- SharedSymbolTable* symbolTable = callFrame->codeBlock()->symbolTable();
- const SlowArgument* slowArguments = symbolTable->slowArguments();
- if (slowArguments) {
- allocateSlowArguments();
- size_t count = std::min<unsigned>(m_numArguments, symbolTable->parameterCount());
- for (size_t i = 0; i < count; ++i)
- m_slowArguments[i] = slowArguments[i];
+
+ inline void Arguments::finishCreation(CallFrame* callFrame)
+ {
+ Base::finishCreation(callFrame->globalData());
+ ASSERT(inherits(&s_info));
+
+ JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
+ m_numArguments = callFrame->argumentCount();
+ m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers());
+ m_callee.set(callFrame->globalData(), this, callee);
+ m_overrodeLength = false;
+ m_overrodeCallee = false;
+ m_overrodeCaller = false;
+ m_isStrictMode = callFrame->codeBlock()->isStrictMode();
+
+ SharedSymbolTable* symbolTable = callFrame->codeBlock()->symbolTable();
+ const SlowArgument* slowArguments = symbolTable->slowArguments();
+ if (slowArguments) {
+ allocateSlowArguments();
+ size_t count = std::min<unsigned>(m_numArguments, symbolTable->parameterCount());
+ for (size_t i = 0; i < count; ++i)
+ m_slowArguments[i] = slowArguments[i];
+ }
+
+ // The bytecode generator omits op_tear_off_activation in cases of no
+ // declared parameters, so we need to tear off immediately.
+ if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
+ tearOff(callFrame);
}
- // The bytecode generator omits op_tear_off_activation in cases of no
- // declared parameters, so we need to tear off immediately.
- if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
- tearOff(callFrame);
-}
-
-inline void Arguments::finishCreation(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
-{
- Base::finishCreation(callFrame->globalData());
- ASSERT(inherits(&s_info));
-
- JSFunction* callee = inlineCallFrame->callee.get();
- m_numArguments = inlineCallFrame->arguments.size() - 1;
- m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset;
- m_callee.set(callFrame->globalData(), this, callee);
- m_overrodeLength = false;
- m_overrodeCallee = false;
- m_overrodeCaller = false;
- m_isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode();
- ASSERT(!jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->symbolTable(inlineCallFrame->isCall ? CodeForCall : CodeForConstruct)->slowArguments());
-
- // The bytecode generator omits op_tear_off_activation in cases of no
- // declared parameters, so we need to tear off immediately.
- if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
- tearOff(callFrame, inlineCallFrame);
-}
+ inline void Arguments::finishCreation(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
+ {
+ Base::finishCreation(callFrame->globalData());
+ ASSERT(inherits(&s_info));
+
+ JSFunction* callee = inlineCallFrame->callee.get();
+ m_numArguments = inlineCallFrame->arguments.size() - 1;
+ m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset;
+ m_callee.set(callFrame->globalData(), this, callee);
+ m_overrodeLength = false;
+ m_overrodeCallee = false;
+ m_overrodeCaller = false;
+ m_isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode();
+ ASSERT(!jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->symbolTable(inlineCallFrame->isCall ? CodeForCall : CodeForConstruct)->slowArguments());
+
+ // The bytecode generator omits op_tear_off_activation in cases of no
+ // declared parameters, so we need to tear off immediately.
+ if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
+ tearOff(callFrame, inlineCallFrame);
+ }
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
index a3fce45f2..5c2cd7167 100644
--- a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -25,8 +25,8 @@
#include "ArrayConstructor.h"
#include "ArrayPrototype.h"
-#include "ButterflyInlines.h"
-#include "CopiedSpaceInlines.h"
+#include "ButterflyInlineMethods.h"
+#include "CopiedSpaceInlineMethods.h"
#include "Error.h"
#include "ExceptionHelpers.h"
#include "JSArray.h"
@@ -77,15 +77,15 @@ bool ArrayConstructor::getOwnPropertyDescriptor(JSObject* object, ExecState* exe
// ------------------------------ Functions ---------------------------
-JSObject* constructArrayWithSizeQuirk(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, JSValue length)
+JSObject* constructArrayWithSizeQuirk(ExecState* exec, JSGlobalObject* globalObject, JSValue length)
{
if (!length.isNumber())
- return constructArray(exec, profile, globalObject, &length, 1);
+ return constructArray(exec, globalObject, &length, 1);
uint32_t n = length.toUInt32(exec);
if (n != length.toNumber(exec))
return throwError(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer.")));
- return constructEmptyArray(exec, profile, globalObject, n);
+ return constructEmptyArray(exec, globalObject, n);
}
static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args)
@@ -94,10 +94,10 @@ static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgLi
// a single numeric argument denotes the array size (!)
if (args.size() == 1)
- return constructArrayWithSizeQuirk(exec, 0, globalObject, args.at(0));
+ return constructArrayWithSizeQuirk(exec, globalObject, args.at(0));
// otherwise the array is constructed with the arguments in it
- return constructArray(exec, 0, globalObject, args);
+ return constructArray(exec, globalObject, args);
}
static EncodedJSValue JSC_HOST_CALL constructWithArrayConstructor(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.h b/Source/JavaScriptCore/runtime/ArrayConstructor.h
index 96860b0fc..dcbf0a1b3 100644
--- a/Source/JavaScriptCore/runtime/ArrayConstructor.h
+++ b/Source/JavaScriptCore/runtime/ArrayConstructor.h
@@ -25,42 +25,42 @@
namespace JSC {
-class ArrayPrototype;
-class JSArray;
+ class ArrayPrototype;
+ class JSArray;
-class ArrayConstructor : public InternalFunction {
-public:
- typedef InternalFunction Base;
+ class ArrayConstructor : public InternalFunction {
+ public:
+ typedef InternalFunction Base;
- static ArrayConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, ArrayPrototype* arrayPrototype)
- {
- ArrayConstructor* constructor = new (NotNull, allocateCell<ArrayConstructor>(*exec->heap())) ArrayConstructor(globalObject, structure);
- constructor->finishCreation(exec, arrayPrototype);
- return constructor;
- }
+ static ArrayConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, ArrayPrototype* arrayPrototype)
+ {
+ ArrayConstructor* constructor = new (NotNull, allocateCell<ArrayConstructor>(*exec->heap())) ArrayConstructor(globalObject, structure);
+ constructor->finishCreation(exec, arrayPrototype);
+ return constructor;
+ }
- static const ClassInfo s_info;
+ static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
- {
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
- }
+ static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ {
+ return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ }
-protected:
- void finishCreation(ExecState*, ArrayPrototype*);
- static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
+ protected:
+ void finishCreation(ExecState*, ArrayPrototype*);
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
-private:
- ArrayConstructor(JSGlobalObject*, Structure*);
- static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
+ private:
+ ArrayConstructor(JSGlobalObject*, Structure*);
+ static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
- static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
+ static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
- static ConstructType getConstructData(JSCell*, ConstructData&);
- static CallType getCallData(JSCell*, CallData&);
-};
+ static ConstructType getConstructData(JSCell*, ConstructData&);
+ static CallType getCallData(JSCell*, CallData&);
+ };
-JSObject* constructArrayWithSizeQuirk(ExecState*, ArrayAllocationProfile*, JSGlobalObject*, JSValue);
+ JSObject* constructArrayWithSizeQuirk(ExecState*, JSGlobalObject*, JSValue);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index cc847d8ff..6975dc778 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -24,10 +24,10 @@
#include "config.h"
#include "ArrayPrototype.h"
-#include "ButterflyInlines.h"
+#include "ButterflyInlineMethods.h"
#include "CachedCall.h"
#include "CodeBlock.h"
-#include "CopiedSpaceInlines.h"
+#include "CopiedSpaceInlineMethods.h"
#include "Interpreter.h"
#include "JIT.h"
#include "JSStringBuilder.h"
@@ -456,7 +456,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
- JSArray* arr = constructEmptyArray(exec, 0);
+ JSArray* arr = constructEmptyArray(exec);
unsigned n = 0;
JSValue curArg = thisValue.toObject(exec);
if (exec->hadException())
@@ -618,7 +618,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
return JSValue::encode(jsUndefined());
// We return a new array
- JSArray* resObj = constructEmptyArray(exec, 0);
+ JSArray* resObj = constructEmptyArray(exec);
JSValue result = resObj;
unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
@@ -733,7 +733,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
return JSValue::encode(jsUndefined());
if (!exec->argumentCount())
- return JSValue::encode(constructEmptyArray(exec, 0));
+ return JSValue::encode(constructEmptyArray(exec));
unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
@@ -748,7 +748,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
deleteCount = static_cast<unsigned>(deleteDouble);
}
- JSArray* resObj = JSArray::tryCreateUninitialized(exec->globalData(), exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), deleteCount);
+ JSArray* resObj = JSArray::tryCreateUninitialized(exec->globalData(), exec->lexicalGlobalObject()->arrayStructure(), deleteCount);
if (!resObj)
return JSValue::encode(throwOutOfMemoryError(exec));
@@ -820,7 +820,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
return throwVMTypeError(exec);
JSValue applyThis = exec->argument(1);
- JSArray* resultArray = constructEmptyArray(exec, 0);
+ JSArray* resultArray = constructEmptyArray(exec);
unsigned filterIndex = 0;
unsigned k = 0;
@@ -880,7 +880,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
JSValue applyThis = exec->argument(1);
- JSArray* resultArray = constructEmptyArray(exec, 0, length);
+ JSArray* resultArray = constructEmptyArray(exec, length);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(thisObj)) {
JSFunction* f = jsCast<JSFunction*>(function);
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.h b/Source/JavaScriptCore/runtime/ArrayPrototype.h
index 2b83d39b7..b33021121 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.h
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.h
@@ -26,28 +26,28 @@
namespace JSC {
-class ArrayPrototype : public JSArray {
-private:
- ArrayPrototype(JSGlobalObject*, Structure*, Butterfly*);
+ class ArrayPrototype : public JSArray {
+ private:
+ ArrayPrototype(JSGlobalObject*, Structure*, Butterfly*);
-public:
- typedef JSArray Base;
+ public:
+ typedef JSArray Base;
- static ArrayPrototype* create(ExecState*, JSGlobalObject*, Structure*);
+ static ArrayPrototype* create(ExecState*, JSGlobalObject*, Structure*);
- static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
- static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
+ static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
+ static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
- static const ClassInfo s_info;
+ static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
- {
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info, ArrayWithArrayStorage);
- }
+ static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ {
+ return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info, ArrayWithArrayStorage);
+ }
-protected:
- void finishCreation(JSGlobalObject*);
-};
+ protected:
+ void finishCreation(JSGlobalObject*);
+ };
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/Butterfly.h b/Source/JavaScriptCore/runtime/Butterfly.h
index 4b8d53f7e..cb93aea8a 100644
--- a/Source/JavaScriptCore/runtime/Butterfly.h
+++ b/Source/JavaScriptCore/runtime/Butterfly.h
@@ -88,18 +88,12 @@ public:
template<typename T>
T* indexingPayload() { return reinterpret_cast<T*>(this); }
ArrayStorage* arrayStorage() { return indexingPayload<ArrayStorage>(); }
- WriteBarrier<Unknown>* contiguousInt32() { return indexingPayload<WriteBarrier<Unknown> >(); }
- double* contiguousDouble() { return indexingPayload<double>(); }
WriteBarrier<Unknown>* contiguous() { return indexingPayload<WriteBarrier<Unknown> >(); }
static Butterfly* fromContiguous(WriteBarrier<Unknown>* contiguous)
{
return reinterpret_cast<Butterfly*>(contiguous);
}
- static Butterfly* fromContiguous(double* contiguous)
- {
- return reinterpret_cast<Butterfly*>(contiguous);
- }
static ptrdiff_t offsetOfPropertyStorage() { return -static_cast<ptrdiff_t>(sizeof(IndexingHeader)); }
static int indexOfPropertyStorage()
diff --git a/Source/JavaScriptCore/runtime/ButterflyInlines.h b/Source/JavaScriptCore/runtime/ButterflyInlineMethods.h
index 9167497a4..86a836bef 100644
--- a/Source/JavaScriptCore/runtime/ButterflyInlines.h
+++ b/Source/JavaScriptCore/runtime/ButterflyInlineMethods.h
@@ -23,12 +23,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ButterflyInlines_h
-#define ButterflyInlines_h
+#ifndef ButterflyInlineMethods_h
+#define ButterflyInlineMethods_h
#include "ArrayStorage.h"
#include "Butterfly.h"
-#include "CopiedSpaceInlines.h"
+#include "CopiedSpaceInlineMethods.h"
#include "CopyVisitor.h"
#include "JSGlobalData.h"
#include "Structure.h"
@@ -61,9 +61,8 @@ inline Butterfly* Butterfly::create(JSGlobalData& globalData, Structure* structu
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),
+ visitor.allocateNewSpace(totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes)),
preCapacity, propertyCapacity);
return result;
}
@@ -176,5 +175,5 @@ inline Butterfly* Butterfly::shift(Structure* structure, size_t numberOfSlots)
} // namespace JSC
-#endif // ButterflyInlines_h
+#endif // ButterflyInlineMethods_h
diff --git a/Source/JavaScriptCore/runtime/CodeCache.cpp b/Source/JavaScriptCore/runtime/CodeCache.cpp
index 068919528..4de760e49 100644
--- a/Source/JavaScriptCore/runtime/CodeCache.cpp
+++ b/Source/JavaScriptCore/runtime/CodeCache.cpp
@@ -36,6 +36,7 @@
namespace JSC {
CodeCache::CodeCache()
+ : m_randomGenerator(static_cast<uint32_t>(randomNumber() * UINT32_MAX))
{
}
@@ -66,9 +67,9 @@ UnlinkedCodeBlockType* CodeCache::getCodeBlock(JSGlobalData& globalData, Executa
CodeBlockKey key = makeCodeBlockKey(source, CacheTypes<UnlinkedCodeBlockType>::codeType, strictness);
bool storeInCache = false;
if (debuggerMode == DebuggerOff && profilerMode == ProfilerOff) {
- const Strong<UnlinkedCodeBlock>* result = m_cachedCodeBlocks.find(key);
- if (result) {
- UnlinkedCodeBlockType* unlinkedCode = jsCast<UnlinkedCodeBlockType*>(result->get());
+ CodeBlockIndicesMap::iterator result = m_cachedCodeBlockIndices.find(key);
+ if (result != m_cachedCodeBlockIndices.end()) {
+ UnlinkedCodeBlockType* unlinkedCode = jsCast<UnlinkedCodeBlockType*>(m_cachedCodeBlocks[result->value].second.get());
unsigned firstLine = source.firstLine() + unlinkedCode->firstLine();
executable->recordParse(unlinkedCode->codeFeatures(), unlinkedCode->hasCapturedVariables(), firstLine, firstLine + unlinkedCode->lineCount());
return unlinkedCode;
@@ -90,8 +91,14 @@ UnlinkedCodeBlockType* CodeCache::getCodeBlock(JSGlobalData& globalData, Executa
if (error.m_type != ParserError::ErrorNone)
return 0;
- if (storeInCache)
- m_cachedCodeBlocks.add(key, Strong<UnlinkedCodeBlock>(globalData, unlinkedCode));
+ if (storeInCache) {
+ size_t index = m_randomGenerator.getUint32() % kMaxCodeBlockEntries;
+ if (m_cachedCodeBlocks[index].second)
+ m_cachedCodeBlockIndices.remove(m_cachedCodeBlocks[index].first);
+ m_cachedCodeBlockIndices.set(key, index);
+ m_cachedCodeBlocks[index].second.set(globalData, unlinkedCode);
+ m_cachedCodeBlocks[index].first = key;
+ }
return unlinkedCode;
}
@@ -126,7 +133,6 @@ UnlinkedFunctionCodeBlock* CodeCache::generateFunctionCodeBlock(JSGlobalData& gl
body->destroyData();
if (error.m_type != ParserError::ErrorNone)
return 0;
- m_cachedFunctionCode.add(result, Strong<UnlinkedFunctionCodeBlock>(globalData, result));
return result;
}
@@ -143,9 +149,9 @@ CodeCache::GlobalFunctionKey CodeCache::makeGlobalFunctionKey(const SourceCode&
UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(JSGlobalData& globalData, const Identifier& name, const SourceCode& source, ParserError& error)
{
GlobalFunctionKey key = makeGlobalFunctionKey(source, name.string());
- const Strong<UnlinkedFunctionExecutable>* result = m_cachedGlobalFunctions.find(key);
- if (result)
- return result->get();
+ GlobalFunctionIndicesMap::iterator result = m_cachedGlobalFunctionIndices.find(key);
+ if (result != m_cachedGlobalFunctionIndices.end())
+ return m_cachedGlobalFunctions[result->value].second.get();
RefPtr<ProgramNode> program = parse<ProgramNode>(&globalData, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error);
if (!program) {
@@ -167,13 +173,14 @@ UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(JSGlo
UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&globalData, source, body);
functionExecutable->m_nameValue.set(globalData, functionExecutable, jsString(&globalData, name.string()));
- m_cachedGlobalFunctions.add(key, Strong<UnlinkedFunctionExecutable>(globalData, functionExecutable));
- return functionExecutable;
-}
+ size_t index = m_randomGenerator.getUint32() % kMaxGlobalFunctionEntries;
+ if (m_cachedGlobalFunctions[index].second)
+ m_cachedGlobalFunctionIndices.remove(m_cachedGlobalFunctions[index].first);
+ m_cachedGlobalFunctionIndices.set(key, index);
+ m_cachedGlobalFunctions[index].second.set(globalData, functionExecutable);
+ m_cachedGlobalFunctions[index].first = key;
-void CodeCache::usedFunctionCode(JSGlobalData& globalData, UnlinkedFunctionCodeBlock* codeBlock)
-{
- m_cachedFunctionCode.add(codeBlock, Strong<UnlinkedFunctionCodeBlock>(globalData, codeBlock));
+ return functionExecutable;
}
}
diff --git a/Source/JavaScriptCore/runtime/CodeCache.h b/Source/JavaScriptCore/runtime/CodeCache.h
index 740aaa6df..4d4617189 100644
--- a/Source/JavaScriptCore/runtime/CodeCache.h
+++ b/Source/JavaScriptCore/runtime/CodeCache.h
@@ -34,7 +34,6 @@
#include <wtf/FixedArray.h>
#include <wtf/Forward.h>
#include <wtf/PassOwnPtr.h>
-#include <wtf/RandomNumber.h>
#include <wtf/text/WTFString.h>
namespace JSC {
@@ -52,41 +51,6 @@ struct ParserError;
class SourceCode;
class SourceProvider;
-template <typename KeyType, typename EntryType, int CacheSize> class Thingy {
- typedef typename HashMap<KeyType, unsigned>::iterator iterator;
-public:
- Thingy()
- : m_randomGenerator((static_cast<uint32_t>(randomNumber() * UINT32_MAX)))
- {
- }
- const EntryType* find(const KeyType& key)
- {
- iterator result = m_map.find(key);
- if (result == m_map.end())
- return 0;
- return &m_data[result->value].second;
- }
- void add(const KeyType& key, const EntryType& value)
- {
- iterator result = m_map.find(key);
- if (result != m_map.end()) {
- m_data[result->value].second = value;
- return;
- }
- size_t newIndex = m_randomGenerator.getUint32() % CacheSize;
- if (m_data[newIndex].second)
- m_map.remove(m_data[newIndex].first);
- m_map.add(key, newIndex);
- m_data[newIndex].first = key;
- m_data[newIndex].second = value;
- ASSERT(m_map.size() <= CacheSize);
- }
-private:
- HashMap<KeyType, unsigned> m_map;
- FixedArray<std::pair<KeyType, EntryType>, CacheSize> m_data;
- WeakRandom m_randomGenerator;
-};
-
class CodeCache {
public:
static PassOwnPtr<CodeCache> create() { return adoptPtr(new CodeCache); }
@@ -95,12 +59,13 @@ public:
UnlinkedEvalCodeBlock* getEvalCodeBlock(JSGlobalData&, EvalExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
UnlinkedFunctionCodeBlock* getFunctionCodeBlock(JSGlobalData&, UnlinkedFunctionExecutable*, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, ParserError&);
UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(JSGlobalData&, const Identifier&, const SourceCode&, ParserError&);
- void usedFunctionCode(JSGlobalData&, UnlinkedFunctionCodeBlock*);
~CodeCache();
enum CodeType { EvalType, ProgramType, FunctionType };
typedef std::pair<String, unsigned> CodeBlockKey;
+ typedef HashMap<CodeBlockKey, unsigned> CodeBlockIndicesMap;
typedef std::pair<String, String> GlobalFunctionKey;
+ typedef HashMap<GlobalFunctionKey, unsigned> GlobalFunctionIndicesMap;
private:
CodeCache();
@@ -109,17 +74,18 @@ private:
template <class UnlinkedCodeBlockType, class ExecutableType> inline UnlinkedCodeBlockType* getCodeBlock(JSGlobalData&, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
CodeBlockKey makeCodeBlockKey(const SourceCode&, CodeType, JSParserStrictness);
+ CodeBlockIndicesMap m_cachedCodeBlockIndices;
GlobalFunctionKey makeGlobalFunctionKey(const SourceCode&, const String&);
+ GlobalFunctionIndicesMap m_cachedGlobalFunctionIndices;
enum {
kMaxCodeBlockEntries = 1024,
- kMaxGlobalFunctionEntries = 1024,
- kMaxFunctionCodeBlocks = 1024
+ kMaxGlobalFunctionEntries = 1024
};
- Thingy<CodeBlockKey, Strong<UnlinkedCodeBlock>, kMaxCodeBlockEntries> m_cachedCodeBlocks;
- Thingy<GlobalFunctionKey, Strong<UnlinkedFunctionExecutable>, kMaxGlobalFunctionEntries> m_cachedGlobalFunctions;
- Thingy<UnlinkedFunctionCodeBlock*, Strong<UnlinkedFunctionCodeBlock>, kMaxFunctionCodeBlocks> m_cachedFunctionCode;
+ FixedArray<std::pair<CodeBlockKey, Strong<UnlinkedCodeBlock> >, kMaxCodeBlockEntries> m_cachedCodeBlocks;
+ FixedArray<std::pair<GlobalFunctionKey, Strong<UnlinkedFunctionExecutable> >, kMaxGlobalFunctionEntries> m_cachedGlobalFunctions;
+ WeakRandom m_randomGenerator;
};
}
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp
index 49a0e256d..20a2e2acb 100644
--- a/Source/JavaScriptCore/runtime/Executable.cpp
+++ b/Source/JavaScriptCore/runtime/Executable.cpp
@@ -620,17 +620,18 @@ void FunctionExecutable::clearCodeIfNotCompiling()
clearCode();
}
-void FunctionExecutable::clearUnlinkedCodeForRecompilationIfNotCompiling()
+void FunctionExecutable::clearUnlinkedCodeIfNotCompiling()
{
if (isCompiling())
return;
- m_unlinkedExecutable->clearCodeForRecompilation();
+ m_unlinkedExecutable->clearCode();
}
void FunctionExecutable::clearCode()
{
m_codeBlockForCall.clear();
m_codeBlockForConstruct.clear();
+ m_unlinkedExecutable->clearCode();
Base::clearCode();
}
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h
index 98471b85b..74b4add75 100644
--- a/Source/JavaScriptCore/runtime/Executable.h
+++ b/Source/JavaScriptCore/runtime/Executable.h
@@ -704,7 +704,7 @@ namespace JSC {
SharedSymbolTable* symbolTable(CodeSpecializationKind kind) const { return m_unlinkedExecutable->symbolTable(kind); }
void clearCodeIfNotCompiling();
- void clearUnlinkedCodeForRecompilationIfNotCompiling();
+ void clearUnlinkedCodeIfNotCompiling();
static void visitChildren(JSCell*, SlotVisitor&);
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
{
diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
index 8e4390b1b..a4b2202c1 100644
--- a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -186,7 +186,7 @@ EncodedJSValue JSC_HOST_CALL functionProtoFuncBind(ExecState* exec)
// Let A be a new (possibly empty) internal list of all of the argument values provided after thisArg (arg1, arg2 etc), in order.
size_t numBoundArgs = exec->argumentCount() > 1 ? exec->argumentCount() - 1 : 0;
- JSArray* boundArgs = JSArray::tryCreateUninitialized(exec->globalData(), globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), numBoundArgs);
+ JSArray* boundArgs = JSArray::tryCreateUninitialized(exec->globalData(), globalObject->arrayStructure(), numBoundArgs);
if (!boundArgs)
return JSValue::encode(throwOutOfMemoryError(exec));
diff --git a/Source/JavaScriptCore/runtime/IndexingHeaderInlines.h b/Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h
index cfad1c8c2..22785ce24 100644
--- a/Source/JavaScriptCore/runtime/IndexingHeaderInlines.h
+++ b/Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h
@@ -23,8 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef IndexingHeaderInlines_h
-#define IndexingHeaderInlines_h
+#ifndef IndexingHeaderInlineMethods_h
+#define IndexingHeaderInlineMethods_h
#include "ArrayStorage.h"
#include "IndexingHeader.h"
@@ -43,9 +43,6 @@ inline size_t IndexingHeader::preCapacity(Structure* structure)
inline size_t IndexingHeader::indexingPayloadSizeInBytes(Structure* structure)
{
switch (structure->indexingType()) {
- case ALL_UNDECIDED_INDEXING_TYPES:
- case ALL_INT32_INDEXING_TYPES:
- case ALL_DOUBLE_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
return vectorLength() * sizeof(EncodedJSValue);
@@ -60,5 +57,5 @@ inline size_t IndexingHeader::indexingPayloadSizeInBytes(Structure* structure)
} // namespace JSC
-#endif // IndexingHeaderInlines_h
+#endif // IndexingHeaderInlineMethods_h
diff --git a/Source/JavaScriptCore/runtime/IndexingType.cpp b/Source/JavaScriptCore/runtime/IndexingType.cpp
index dc2733ad1..7261847a2 100644
--- a/Source/JavaScriptCore/runtime/IndexingType.cpp
+++ b/Source/JavaScriptCore/runtime/IndexingType.cpp
@@ -31,46 +31,6 @@
namespace JSC {
-IndexingType leastUpperBoundOfIndexingTypes(IndexingType a, IndexingType b)
-{
- // It doesn't make sense to LUB something that is an array with something that isn't.
- ASSERT((a & IsArray) == (b & IsArray));
-
- // Boy, this sure is easy right now.
- return std::max(a, b);
-}
-
-IndexingType leastUpperBoundOfIndexingTypeAndType(IndexingType indexingType, SpeculatedType type)
-{
- if (!type)
- return indexingType;
- switch (indexingType) {
- case ALL_BLANK_INDEXING_TYPES:
- case ALL_UNDECIDED_INDEXING_TYPES:
- case ALL_INT32_INDEXING_TYPES:
- if (isInt32Speculation(type))
- return (indexingType & ~IndexingShapeMask) | Int32Shape;
- if (isNumberSpeculation(type))
- return (indexingType & ~IndexingShapeMask) | DoubleShape;
- return (indexingType & ~IndexingShapeMask) | ContiguousShape;
- case ALL_DOUBLE_INDEXING_TYPES:
- if (isNumberSpeculation(type))
- return indexingType;
- return (indexingType & ~IndexingShapeMask) | ContiguousShape;
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return indexingType;
- default:
- CRASH();
- return 0;
- }
-}
-
-IndexingType leastUpperBoundOfIndexingTypeAndValue(IndexingType indexingType, JSValue value)
-{
- return leastUpperBoundOfIndexingTypeAndType(indexingType, speculationFromValue(value));
-}
-
const char* indexingTypeToString(IndexingType indexingType)
{
static char result[128];
@@ -79,12 +39,6 @@ const char* indexingTypeToString(IndexingType indexingType)
case NonArray:
basicName = "NonArray";
break;
- case NonArrayWithInt32:
- basicName = "NonArrayWithInt32";
- break;
- case NonArrayWithDouble:
- basicName = "NonArrayWithDouble";
- break;
case NonArrayWithContiguous:
basicName = "NonArrayWithContiguous";
break;
@@ -97,15 +51,6 @@ const char* indexingTypeToString(IndexingType indexingType)
case ArrayClass:
basicName = "ArrayClass";
break;
- case ArrayWithUndecided:
- basicName = "ArrayWithUndecided";
- break;
- case ArrayWithInt32:
- basicName = "ArrayWithInt32";
- break;
- case ArrayWithDouble:
- basicName = "ArrayWithDouble";
- break;
case ArrayWithContiguous:
basicName = "ArrayWithContiguous";
break;
diff --git a/Source/JavaScriptCore/runtime/IndexingType.h b/Source/JavaScriptCore/runtime/IndexingType.h
index ab253be1e..4bbe3cfa0 100644
--- a/Source/JavaScriptCore/runtime/IndexingType.h
+++ b/Source/JavaScriptCore/runtime/IndexingType.h
@@ -26,7 +26,6 @@
#ifndef IndexingType_h
#define IndexingType_h
-#include "SpeculatedType.h"
#include <wtf/StdLibExtras.h>
namespace JSC {
@@ -38,32 +37,21 @@ static const IndexingType IsArray = 1;
// The shape of the indexed property storage.
static const IndexingType IndexingShapeMask = 30;
-static const IndexingType NoIndexingShape = 0;
-static const IndexingType UndecidedShape = 2; // Only useful for arrays.
-static const IndexingType Int32Shape = 20;
-static const IndexingType DoubleShape = 22;
+static const IndexingType NoIndexingShape = 0;
static const IndexingType ContiguousShape = 26;
static const IndexingType ArrayStorageShape = 28;
static const IndexingType SlowPutArrayStorageShape = 30;
-static const IndexingType IndexingShapeShift = 1;
-static const IndexingType NumberOfIndexingShapes = 16;
-
// Additional flags for tracking the history of the type. These are usually
// masked off unless you ask for them directly.
static const IndexingType MayHaveIndexedAccessors = 32;
// List of acceptable array types.
static const IndexingType NonArray = 0;
-static const IndexingType NonArrayWithInt32 = Int32Shape;
-static const IndexingType NonArrayWithDouble = DoubleShape;
static const IndexingType NonArrayWithContiguous = ContiguousShape;
static const IndexingType NonArrayWithArrayStorage = ArrayStorageShape;
static const IndexingType NonArrayWithSlowPutArrayStorage = SlowPutArrayStorageShape;
static const IndexingType ArrayClass = IsArray; // I'd want to call this "Array" but this would lead to disastrous namespace pollution.
-static const IndexingType ArrayWithUndecided = IsArray | UndecidedShape;
-static const IndexingType ArrayWithInt32 = IsArray | Int32Shape;
-static const IndexingType ArrayWithDouble = IsArray | DoubleShape;
static const IndexingType ArrayWithContiguous = IsArray | ContiguousShape;
static const IndexingType ArrayWithArrayStorage = IsArray | ArrayStorageShape;
static const IndexingType ArrayWithSlowPutArrayStorage = IsArray | SlowPutArrayStorageShape;
@@ -72,17 +60,6 @@ static const IndexingType ArrayWithSlowPutArrayStorage = IsArray | SlowPutArr
NonArray: \
case ArrayClass
-#define ALL_UNDECIDED_INDEXING_TYPES \
- ArrayWithUndecided
-
-#define ALL_INT32_INDEXING_TYPES \
- NonArrayWithInt32: \
- case ArrayWithInt32
-
-#define ALL_DOUBLE_INDEXING_TYPES \
- NonArrayWithDouble: \
- case ArrayWithDouble
-
#define ALL_CONTIGUOUS_INDEXING_TYPES \
NonArrayWithContiguous: \
case ArrayWithContiguous
@@ -106,21 +83,6 @@ static inline bool hasIndexingHeader(IndexingType type)
return hasIndexedProperties(type);
}
-static inline bool hasUndecided(IndexingType indexingType)
-{
- return (indexingType & IndexingShapeMask) == UndecidedShape;
-}
-
-static inline bool hasInt32(IndexingType indexingType)
-{
- return (indexingType & IndexingShapeMask) == Int32Shape;
-}
-
-static inline bool hasDouble(IndexingType indexingType)
-{
- return (indexingType & IndexingShapeMask) == DoubleShape;
-}
-
static inline bool hasContiguous(IndexingType indexingType)
{
return (indexingType & IndexingShapeMask) == ContiguousShape;
@@ -143,12 +105,6 @@ static inline bool shouldUseSlowPut(IndexingType indexingType)
return (indexingType & IndexingShapeMask) == SlowPutArrayStorageShape;
}
-// Return an indexing type that can handle all of the elements of both indexing types.
-IndexingType leastUpperBoundOfIndexingTypes(IndexingType, IndexingType);
-
-IndexingType leastUpperBoundOfIndexingTypeAndType(IndexingType, SpeculatedType);
-IndexingType leastUpperBoundOfIndexingTypeAndValue(IndexingType, JSValue);
-
const char* indexingTypeToString(IndexingType);
// Mask of all possible types.
diff --git a/Source/JavaScriptCore/runtime/JSActivation.h b/Source/JavaScriptCore/runtime/JSActivation.h
index b8f5621af..fc6336463 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.h
+++ b/Source/JavaScriptCore/runtime/JSActivation.h
@@ -30,7 +30,7 @@
#define JSActivation_h
#include "CodeBlock.h"
-#include "CopiedSpaceInlines.h"
+#include "CopiedSpaceInlineMethods.h"
#include "JSVariableObject.h"
#include "Nodes.h"
#include "SymbolTable.h"
diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp
index 4ba5cc2bd..d1ece1a36 100644
--- a/Source/JavaScriptCore/runtime/JSArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSArray.cpp
@@ -24,14 +24,14 @@
#include "JSArray.h"
#include "ArrayPrototype.h"
-#include "ButterflyInlines.h"
-#include "CachedCall.h"
+#include "ButterflyInlineMethods.h"
#include "CopiedSpace.h"
-#include "CopiedSpaceInlines.h"
+#include "CopiedSpaceInlineMethods.h"
+#include "CachedCall.h"
#include "Error.h"
#include "Executable.h"
#include "GetterSetter.h"
-#include "IndexingHeaderInlines.h"
+#include "IndexingHeaderInlineMethods.h"
#include "PropertyNameArray.h"
#include "Reject.h"
#include <wtf/AVLTree.h>
@@ -410,33 +410,25 @@ bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException
exec, newLength, throwException,
convertContiguousToArrayStorage(exec->globalData()));
}
- createInitialUndecided(exec->globalData(), newLength);
+ createInitialContiguous(exec->globalData(), newLength);
return true;
- case ArrayWithUndecided:
- case ArrayWithInt32:
- case ArrayWithDouble:
case ArrayWithContiguous:
if (newLength == m_butterfly->publicLength())
return true;
if (newLength >= MAX_ARRAY_INDEX // This case ensures that we can do fast push.
|| (newLength >= MIN_SPARSE_ARRAY_INDEX
- && !isDenseEnoughForVector(newLength, countElements()))) {
+ && !isDenseEnoughForVector(newLength, countElementsInContiguous(m_butterfly)))) {
return setLengthWithArrayStorage(
exec, newLength, throwException,
- ensureArrayStorage(exec->globalData()));
+ convertContiguousToArrayStorage(exec->globalData()));
}
if (newLength > m_butterfly->publicLength()) {
- ensureLength(exec->globalData(), newLength);
+ ensureContiguousLength(exec->globalData(), newLength);
return true;
}
- if (structure()->indexingType() == ArrayWithDouble) {
- for (unsigned i = m_butterfly->publicLength(); i-- > newLength;)
- m_butterfly->contiguousDouble()[i] = QNaN;
- } else {
- for (unsigned i = m_butterfly->publicLength(); i-- > newLength;)
- m_butterfly->contiguous()[i].clear();
- }
+ for (unsigned i = m_butterfly->publicLength(); i-- > newLength;)
+ m_butterfly->contiguous()[i].clear();
m_butterfly->setPublicLength(newLength);
return true;
@@ -456,13 +448,6 @@ JSValue JSArray::pop(ExecState* exec)
case ArrayClass:
return jsUndefined();
- case ArrayWithUndecided:
- if (!m_butterfly->publicLength())
- return jsUndefined();
- // We have nothing but holes. So, drop down to the slow version.
- break;
-
- case ArrayWithInt32:
case ArrayWithContiguous: {
unsigned length = m_butterfly->publicLength();
@@ -479,22 +464,6 @@ JSValue JSArray::pop(ExecState* exec)
break;
}
- case ArrayWithDouble: {
- unsigned length = m_butterfly->publicLength();
-
- if (!length--)
- return jsUndefined();
-
- ASSERT(length < m_butterfly->vectorLength());
- double value = m_butterfly->contiguousDouble()[length];
- if (value == value) {
- m_butterfly->contiguousDouble()[length] = QNaN;
- m_butterfly->setPublicLength(length);
- return JSValue(JSValue::EncodeAsDouble, value);
- }
- break;
- }
-
case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
@@ -549,42 +518,10 @@ void JSArray::push(ExecState* exec, JSValue value)
{
switch (structure()->indexingType()) {
case ArrayClass: {
- createInitialUndecided(exec->globalData(), 0);
- // Fall through.
- }
-
- case ArrayWithUndecided: {
- convertUndecidedForValue(exec->globalData(), value);
- push(exec, value);
- return;
+ putByIndexBeyondVectorLengthWithArrayStorage(exec, 0, value, true, createInitialArrayStorage(exec->globalData()));
+ break;
}
- case ArrayWithInt32: {
- if (!value.isInt32()) {
- convertInt32ForValue(exec->globalData(), value);
- push(exec, value);
- return;
- }
-
- unsigned length = m_butterfly->publicLength();
- ASSERT(length <= m_butterfly->vectorLength());
- if (length < m_butterfly->vectorLength()) {
- m_butterfly->contiguousInt32()[length].setWithoutWriteBarrier(value);
- m_butterfly->setPublicLength(length + 1);
- return;
- }
-
- if (length > MAX_ARRAY_INDEX) {
- methodTable()->putByIndex(this, exec, length, value, true);
- if (!exec->hadException())
- throwError(exec, createRangeError(exec, "Invalid array length"));
- return;
- }
-
- putByIndexBeyondVectorLengthWithoutAttributes<Int32Shape>(exec, length, value);
- return;
- }
-
case ArrayWithContiguous: {
unsigned length = m_butterfly->publicLength();
ASSERT(length <= m_butterfly->vectorLength());
@@ -601,42 +538,10 @@ void JSArray::push(ExecState* exec, JSValue value)
return;
}
- putByIndexBeyondVectorLengthWithoutAttributes<ContiguousShape>(exec, length, value);
+ putByIndexBeyondVectorLengthContiguousWithoutAttributes(exec, length, value);
return;
}
- case ArrayWithDouble: {
- if (!value.isNumber()) {
- convertDoubleToContiguous(exec->globalData());
- push(exec, value);
- return;
- }
- double valueAsDouble = value.asNumber();
- if (valueAsDouble != valueAsDouble) {
- convertDoubleToContiguous(exec->globalData());
- push(exec, value);
- return;
- }
-
- unsigned length = m_butterfly->publicLength();
- ASSERT(length <= m_butterfly->vectorLength());
- if (length < m_butterfly->vectorLength()) {
- m_butterfly->contiguousDouble()[length] = valueAsDouble;
- m_butterfly->setPublicLength(length + 1);
- return;
- }
-
- if (length > MAX_ARRAY_INDEX) {
- methodTable()->putByIndex(this, exec, length, value, true);
- if (!exec->hadException())
- throwError(exec, createRangeError(exec, "Invalid array length"));
- return;
- }
-
- putByIndexBeyondVectorLengthWithoutAttributes<DoubleShape>(exec, length, value);
- break;
- }
-
case ArrayWithSlowPutArrayStorage: {
unsigned oldLength = length();
if (attemptToInterceptPutByIndexOnHole(exec, oldLength, value, true)) {
@@ -742,11 +647,6 @@ bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex
case ArrayClass:
return true;
- case ArrayWithUndecided:
- // Don't handle this because it's confusing and it shouldn't come up.
- return false;
-
- case ArrayWithInt32:
case ArrayWithContiguous: {
unsigned oldLength = m_butterfly->publicLength();
ASSERT(count <= oldLength);
@@ -754,7 +654,7 @@ bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex
// We may have to walk the entire array to do the shift. We're willing to do
// so only if it's not horribly slow.
if (oldLength - (startIndex + count) >= MIN_SPARSE_ARRAY_INDEX)
- return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData()));
+ return shiftCountWithArrayStorage(startIndex, count, convertContiguousToArrayStorage(exec->globalData()));
unsigned end = oldLength - count;
for (unsigned i = startIndex; i < end; ++i) {
@@ -768,7 +668,7 @@ bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex
// about holes (at least for now), but it can detect them quickly. So
// we convert to array storage and then allow the array storage path to
// figure it out.
- return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData()));
+ return shiftCountWithArrayStorage(startIndex, count, convertContiguousToArrayStorage(exec->globalData()));
}
// No need for a barrier since we're just moving data around in the same vector.
// This is in line with our standing assumption that we won't have a deletion
@@ -782,41 +682,6 @@ bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex
return true;
}
- case ArrayWithDouble: {
- unsigned oldLength = m_butterfly->publicLength();
- ASSERT(count <= oldLength);
-
- // We may have to walk the entire array to do the shift. We're willing to do
- // so only if it's not horribly slow.
- if (oldLength - (startIndex + count) >= MIN_SPARSE_ARRAY_INDEX)
- return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData()));
-
- unsigned end = oldLength - count;
- for (unsigned i = startIndex; i < end; ++i) {
- // Storing to a hole is fine since we're still having a good time. But reading
- // from a hole is totally not fine, since we might have to read from the proto
- // chain.
- double v = m_butterfly->contiguousDouble()[i + count];
- if (UNLIKELY(v != v)) {
- // The purpose of this path is to ensure that we don't make the same
- // mistake in the future: shiftCountWithArrayStorage() can't do anything
- // about holes (at least for now), but it can detect them quickly. So
- // we convert to array storage and then allow the array storage path to
- // figure it out.
- return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData()));
- }
- // No need for a barrier since we're just moving data around in the same vector.
- // This is in line with our standing assumption that we won't have a deletion
- // barrier.
- m_butterfly->contiguousDouble()[i] = v;
- }
- for (unsigned i = end; i < oldLength; ++i)
- m_butterfly->contiguousDouble()[i] = QNaN;
-
- m_butterfly->setPublicLength(oldLength - count);
- return true;
- }
-
case ArrayWithArrayStorage:
case ArrayWithSlowPutArrayStorage:
return shiftCountWithArrayStorage(startIndex, count, arrayStorage());
@@ -875,25 +740,23 @@ bool JSArray::unshiftCountWithAnyIndexingType(ExecState* exec, unsigned startInd
{
switch (structure()->indexingType()) {
case ArrayClass:
- case ArrayWithUndecided:
// We could handle this. But it shouldn't ever come up, so we won't.
return false;
-
- case ArrayWithInt32:
+
case ArrayWithContiguous: {
unsigned oldLength = m_butterfly->publicLength();
// We may have to walk the entire array to do the unshift. We're willing to do so
// only if it's not horribly slow.
if (oldLength - startIndex >= MIN_SPARSE_ARRAY_INDEX)
- return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData()));
+ return unshiftCountWithArrayStorage(exec, startIndex, count, convertContiguousToArrayStorage(exec->globalData()));
- ensureLength(exec->globalData(), oldLength + count);
+ ensureContiguousLength(exec->globalData(), oldLength + count);
for (unsigned i = oldLength; i-- > startIndex;) {
JSValue v = m_butterfly->contiguous()[i].get();
if (UNLIKELY(!v))
- return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData()));
+ return unshiftCountWithArrayStorage(exec, startIndex, count, convertContiguousToArrayStorage(exec->globalData()));
m_butterfly->contiguous()[i + count].setWithoutWriteBarrier(v);
}
@@ -905,31 +768,6 @@ bool JSArray::unshiftCountWithAnyIndexingType(ExecState* exec, unsigned startInd
return true;
}
- case ArrayWithDouble: {
- unsigned oldLength = m_butterfly->publicLength();
-
- // We may have to walk the entire array to do the unshift. We're willing to do so
- // only if it's not horribly slow.
- if (oldLength - startIndex >= MIN_SPARSE_ARRAY_INDEX)
- return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData()));
-
- ensureLength(exec->globalData(), oldLength + count);
-
- for (unsigned i = oldLength; i-- > startIndex;) {
- double v = m_butterfly->contiguousDouble()[i];
- if (UNLIKELY(v != v))
- return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData()));
- m_butterfly->contiguousDouble()[i + count] = v;
- }
-
- // NOTE: we're leaving being garbage in the part of the array that we shifted out
- // of. This is fine because the caller is required to store over that area, and
- // in contiguous mode storing into a hole is guaranteed to behave exactly the same
- // as storing over an existing element.
-
- return true;
- }
-
case ArrayWithArrayStorage:
case ArrayWithSlowPutArrayStorage:
return unshiftCountWithArrayStorage(exec, startIndex, count, arrayStorage());
@@ -940,20 +778,6 @@ bool JSArray::unshiftCountWithAnyIndexingType(ExecState* exec, unsigned startInd
}
}
-static int compareNumbersForQSortWithInt32(const void* a, const void* b)
-{
- int32_t ia = static_cast<const JSValue*>(a)->asInt32();
- int32_t ib = static_cast<const JSValue*>(b)->asInt32();
- return ia - ib;
-}
-
-static int compareNumbersForQSortWithDouble(const void* a, const void* b)
-{
- double da = *static_cast<const double*>(a);
- double db = *static_cast<const double*>(b);
- return (da > db) - (da < db);
-}
-
static int compareNumbersForQSort(const void* a, const void* b)
{
double da = static_cast<const JSValue*>(a)->asNumber();
@@ -971,7 +795,7 @@ static int compareByStringPairForQSort(const void* a, const void* b)
template<IndexingType indexingType>
void JSArray::sortNumericVector(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
{
- ASSERT(indexingType == ArrayWithInt32 || indexingType == ArrayWithDouble || indexingType == ArrayWithContiguous || indexingType == ArrayWithArrayStorage);
+ ASSERT(indexingType == ArrayWithContiguous || indexingType == ArrayWithArrayStorage);
unsigned lengthNotIncludingUndefined;
unsigned newRelevantLength;
@@ -990,19 +814,11 @@ void JSArray::sortNumericVector(ExecState* exec, JSValue compareFunction, CallTy
return;
bool allValuesAreNumbers = true;
- switch (indexingType) {
- case ArrayWithInt32:
- case ArrayWithDouble:
- break;
-
- default:
- for (size_t i = 0; i < newRelevantLength; ++i) {
- if (!data[i].isNumber()) {
- allValuesAreNumbers = false;
- break;
- }
+ for (size_t i = 0; i < newRelevantLength; ++i) {
+ if (!data[i].isNumber()) {
+ allValuesAreNumbers = false;
+ break;
}
- break;
}
if (!allValuesAreNumbers)
@@ -1011,23 +827,7 @@ void JSArray::sortNumericVector(ExecState* exec, JSValue compareFunction, CallTy
// For numeric comparison, which is fast, qsort is faster than mergesort. We
// also don't require mergesort's stability, since there's no user visible
// side-effect from swapping the order of equal primitive values.
- int (*compare)(const void*, const void*);
- switch (indexingType) {
- case ArrayWithInt32:
- compare = compareNumbersForQSortWithInt32;
- break;
-
- case ArrayWithDouble:
- compare = compareNumbersForQSortWithDouble;
- ASSERT(sizeof(WriteBarrier<Unknown>) == sizeof(double));
- break;
-
- default:
- compare = compareNumbersForQSort;
- break;
- }
-
- qsort(data, newRelevantLength, sizeof(WriteBarrier<Unknown>), compare);
+ qsort(data, newRelevantLength, sizeof(WriteBarrier<Unknown>), compareNumbersForQSort);
return;
}
@@ -1039,14 +839,6 @@ void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType cal
case ArrayClass:
return;
- case ArrayWithInt32:
- sortNumericVector<ArrayWithInt32>(exec, compareFunction, callType, callData);
- break;
-
- case ArrayWithDouble:
- sortNumericVector<ArrayWithDouble>(exec, compareFunction, callType, callData);
- break;
-
case ArrayWithContiguous:
sortNumericVector<ArrayWithContiguous>(exec, compareFunction, callType, callData);
return;
@@ -1062,7 +854,7 @@ void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType cal
}
template<IndexingType indexingType>
-void JSArray::sortCompactedVector(ExecState* exec, void* begin, unsigned relevantLength)
+void JSArray::sortCompactedVector(ExecState* exec, WriteBarrier<Unknown>* begin, unsigned relevantLength)
{
if (!relevantLength)
return;
@@ -1083,31 +875,11 @@ void JSArray::sortCompactedVector(ExecState* exec, void* begin, unsigned relevan
Heap::heap(this)->pushTempSortVector(&values);
bool isSortingPrimitiveValues = true;
- switch (indexingType) {
- case ArrayWithInt32:
- for (size_t i = 0; i < relevantLength; i++) {
- JSValue value = static_cast<WriteBarrier<Unknown>*>(begin)[i].get();
- ASSERT(value.isInt32());
- values[i].first = value;
- }
- break;
-
- case ArrayWithDouble:
- for (size_t i = 0; i < relevantLength; i++) {
- double value = static_cast<double*>(begin)[i];
- ASSERT(value == value);
- values[i].first = JSValue(JSValue::EncodeAsDouble, value);
- }
- break;
-
- default:
- for (size_t i = 0; i < relevantLength; i++) {
- JSValue value = static_cast<WriteBarrier<Unknown>*>(begin)[i].get();
- ASSERT(!value.isUndefined());
- values[i].first = value;
- isSortingPrimitiveValues = isSortingPrimitiveValues && value.isPrimitive();
- }
- break;
+ for (size_t i = 0; i < relevantLength; i++) {
+ JSValue value = begin[i].get();
+ ASSERT(!value.isUndefined());
+ values[i].first = value;
+ isSortingPrimitiveValues = isSortingPrimitiveValues && value.isPrimitive();
}
// FIXME: The following loop continues to call toString on subsequent values even after
@@ -1138,10 +910,8 @@ void JSArray::sortCompactedVector(ExecState* exec, void* begin, unsigned relevan
// If the toString function changed the length of the array or vector storage,
// increase the length to handle the orignal number of actual values.
switch (indexingType) {
- case ArrayWithInt32:
- case ArrayWithDouble:
case ArrayWithContiguous:
- ensureLength(globalData, relevantLength);
+ ensureContiguousLength(globalData, relevantLength);
break;
case ArrayWithArrayStorage:
@@ -1157,12 +927,8 @@ void JSArray::sortCompactedVector(ExecState* exec, void* begin, unsigned relevan
CRASH();
}
- for (size_t i = 0; i < relevantLength; i++) {
- if (indexingType == ArrayWithDouble)
- static_cast<double*>(begin)[i] = values[i].first.asNumber();
- else
- static_cast<WriteBarrier<Unknown>*>(begin)[i].set(globalData, this, values[i].first);
- }
+ for (size_t i = 0; i < relevantLength; i++)
+ begin[i].set(globalData, this, values[i].first);
Heap::heap(this)->popTempSortVector(&values);
}
@@ -1173,31 +939,8 @@ void JSArray::sort(ExecState* exec)
switch (structure()->indexingType()) {
case ArrayClass:
- case ArrayWithUndecided:
return;
- case ArrayWithInt32: {
- unsigned lengthNotIncludingUndefined;
- unsigned newRelevantLength;
- compactForSorting<ArrayWithInt32>(
- lengthNotIncludingUndefined, newRelevantLength);
-
- sortCompactedVector<ArrayWithInt32>(
- exec, m_butterfly->contiguousInt32(), lengthNotIncludingUndefined);
- return;
- }
-
- case ArrayWithDouble: {
- unsigned lengthNotIncludingUndefined;
- unsigned newRelevantLength;
- compactForSorting<ArrayWithDouble>(
- lengthNotIncludingUndefined, newRelevantLength);
-
- sortCompactedVector<ArrayWithDouble>(
- exec, m_butterfly->contiguousDouble(), lengthNotIncludingUndefined);
- return;
- }
-
case ArrayWithContiguous: {
unsigned lengthNotIncludingUndefined;
unsigned newRelevantLength;
@@ -1344,12 +1087,12 @@ void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType call
unsigned numDefined = 0;
unsigned numUndefined = 0;
-
+
// Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree.
for (; numDefined < usedVectorLength; ++numDefined) {
if (numDefined > m_butterfly->vectorLength())
break;
- JSValue v = getHolyIndexQuickly(numDefined);
+ JSValue v = currentIndexingData()[numDefined].get();
if (!v || v.isUndefined())
break;
tree.abstractor().m_nodes[numDefined].value = v;
@@ -1358,7 +1101,7 @@ void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType call
for (unsigned i = numDefined; i < usedVectorLength; ++i) {
if (i > m_butterfly->vectorLength())
break;
- JSValue v = getHolyIndexQuickly(i);
+ JSValue v = currentIndexingData()[i].get();
if (v) {
if (v.isUndefined())
++numUndefined;
@@ -1369,7 +1112,7 @@ void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType call
}
}
}
-
+
unsigned newUsedVectorLength = numDefined + numUndefined;
// The array size may have changed. Figure out the new bounds.
@@ -1384,31 +1127,16 @@ void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType call
iter.start_iter_least(tree);
JSGlobalData& globalData = exec->globalData();
for (unsigned i = 0; i < elementsToExtractThreshold; ++i) {
- if (structure()->indexingType() == ArrayWithDouble)
- butterfly()->contiguousDouble()[i] = tree.abstractor().m_nodes[*iter].value.asNumber();
- else
- currentIndexingData()[i].set(globalData, this, tree.abstractor().m_nodes[*iter].value);
+ currentIndexingData()[i].set(globalData, this, tree.abstractor().m_nodes[*iter].value);
++iter;
}
// Put undefined values back in.
- switch (structure()->indexingType()) {
- case ArrayWithInt32:
- case ArrayWithDouble:
- ASSERT(elementsToExtractThreshold == undefinedElementsThreshold);
- break;
-
- default:
- for (unsigned i = elementsToExtractThreshold; i < undefinedElementsThreshold; ++i)
- currentIndexingData()[i].setUndefined();
- }
+ for (unsigned i = elementsToExtractThreshold; i < undefinedElementsThreshold; ++i)
+ currentIndexingData()[i].setUndefined();
// Ensure that unused values in the vector are zeroed out.
- for (unsigned i = undefinedElementsThreshold; i < clearElementsThreshold; ++i) {
- if (structure()->indexingType() == ArrayWithDouble)
- butterfly()->contiguousDouble()[i] = QNaN;
- else
- currentIndexingData()[i].clear();
- }
+ for (unsigned i = undefinedElementsThreshold; i < clearElementsThreshold; ++i)
+ currentIndexingData()[i].clear();
if (hasArrayStorage(structure()->indexingType()))
arrayStorage()->m_numValuesInVector = newUsedVectorLength;
@@ -1420,17 +1148,8 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
switch (structure()->indexingType()) {
case ArrayClass:
- case ArrayWithUndecided:
return;
- case ArrayWithInt32:
- sortVector<ArrayWithInt32>(exec, compareFunction, callType, callData);
- return;
-
- case ArrayWithDouble:
- sortVector<ArrayWithDouble>(exec, compareFunction, callType, callData);
- return;
-
case ArrayWithContiguous:
sortVector<ArrayWithContiguous>(exec, compareFunction, callType, callData);
return;
@@ -1454,30 +1173,11 @@ void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
case ArrayClass:
return;
- case ArrayWithUndecided: {
- vector = 0;
- vectorEnd = 0;
- break;
- }
-
- case ArrayWithInt32:
case ArrayWithContiguous: {
vectorEnd = m_butterfly->publicLength();
vector = m_butterfly->contiguous();
break;
}
-
- case ArrayWithDouble: {
- vector = 0;
- vectorEnd = 0;
- for (; i < m_butterfly->publicLength(); ++i) {
- double v = butterfly()->contiguousDouble()[i];
- if (v != v)
- break;
- args.append(JSValue(JSValue::EncodeAsDouble, v));
- }
- break;
- }
case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
@@ -1516,31 +1216,12 @@ void JSArray::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t le
case ArrayClass:
return;
- case ArrayWithUndecided: {
- vector = 0;
- vectorEnd = 0;
- break;
- }
-
- case ArrayWithInt32:
case ArrayWithContiguous: {
vector = m_butterfly->contiguous();
vectorEnd = m_butterfly->publicLength();
break;
}
- case ArrayWithDouble: {
- vector = 0;
- vectorEnd = 0;
- for (; i < m_butterfly->publicLength(); ++i) {
- double v = m_butterfly->contiguousDouble()[i];
- if (v != v)
- break;
- callFrame->setArgument(i, JSValue(JSValue::EncodeAsDouble, v));
- }
- break;
- }
-
case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
vector = storage->m_vector;
@@ -1578,40 +1259,12 @@ void JSArray::compactForSorting(unsigned& numDefined, unsigned& newRelevantLengt
unsigned numUndefined = 0;
for (; numDefined < myRelevantLength; ++numDefined) {
- if (indexingType == ArrayWithInt32) {
- JSValue v = m_butterfly->contiguousInt32()[numDefined].get();
- if (!v)
- break;
- ASSERT(v.isInt32());
- continue;
- }
- if (indexingType == ArrayWithDouble) {
- double v = m_butterfly->contiguousDouble()[numDefined];
- if (v != v)
- break;
- continue;
- }
JSValue v = indexingData<indexingType>()[numDefined].get();
if (!v || v.isUndefined())
break;
}
for (unsigned i = numDefined; i < myRelevantLength; ++i) {
- if (indexingType == ArrayWithInt32) {
- JSValue v = m_butterfly->contiguousInt32()[i].get();
- if (!v)
- continue;
- ASSERT(v.isInt32());
- m_butterfly->contiguousInt32()[numDefined++].setWithoutWriteBarrier(v);
- continue;
- }
- if (indexingType == ArrayWithDouble) {
- double v = m_butterfly->contiguousDouble()[i];
- if (v != v)
- continue;
- m_butterfly->contiguousDouble()[numDefined++] = v;
- continue;
- }
JSValue v = indexingData<indexingType>()[i].get();
if (v) {
if (v.isUndefined())
@@ -1626,23 +1279,10 @@ void JSArray::compactForSorting(unsigned& numDefined, unsigned& newRelevantLengt
if (hasArrayStorage(indexingType))
ASSERT(!arrayStorage()->m_sparseMap);
- switch (indexingType) {
- case ArrayWithInt32:
- case ArrayWithDouble:
- ASSERT(numDefined == newRelevantLength);
- break;
-
- default:
- for (unsigned i = numDefined; i < newRelevantLength; ++i)
- indexingData<indexingType>()[i].setUndefined();
- break;
- }
- for (unsigned i = newRelevantLength; i < myRelevantLength; ++i) {
- if (indexingType == ArrayWithDouble)
- m_butterfly->contiguousDouble()[i] = QNaN;
- else
- indexingData<indexingType>()[i].clear();
- }
+ for (unsigned i = numDefined; i < newRelevantLength; ++i)
+ indexingData<indexingType>()[i].setUndefined();
+ for (unsigned i = newRelevantLength; i < myRelevantLength; ++i)
+ indexingData<indexingType>()[i].clear();
if (hasArrayStorage(indexingType))
arrayStorage()->m_numValuesInVector = newRelevantLength;
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index ea1ed9047..1d1e64173 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -22,7 +22,7 @@
#define JSArray_h
#include "ArrayConventions.h"
-#include "ButterflyInlines.h"
+#include "ButterflyInlineMethods.h"
#include "JSObject.h"
namespace JSC {
@@ -162,7 +162,7 @@ private:
void sortNumericVector(ExecState*, JSValue compareFunction, CallType, const CallData&);
template<IndexingType indexingType>
- void sortCompactedVector(ExecState*, void* begin, unsigned relevantLength);
+ void sortCompactedVector(ExecState*, WriteBarrier<Unknown>* begin, unsigned relevantLength);
template<IndexingType indexingType>
void sortVector(ExecState*, JSValue compareFunction, CallType, const CallData&);
@@ -174,14 +174,13 @@ private:
void compactForSorting(unsigned& numDefined, unsigned& newRelevantLength);
};
-inline Butterfly* createContiguousArrayButterfly(JSGlobalData& globalData, unsigned length, unsigned& vectorLength)
+inline Butterfly* createContiguousArrayButterfly(JSGlobalData& globalData, unsigned length)
{
IndexingHeader header;
- vectorLength = std::max(length, BASE_VECTOR_LEN);
- header.setVectorLength(vectorLength);
+ header.setVectorLength(std::max(length, BASE_VECTOR_LEN));
header.setPublicLength(length);
Butterfly* result = Butterfly::create(
- globalData, 0, 0, true, header, vectorLength * sizeof(EncodedJSValue));
+ globalData, 0, 0, true, header, header.vectorLength() * sizeof(EncodedJSValue));
return result;
}
@@ -201,23 +200,13 @@ Butterfly* createArrayButterflyInDictionaryIndexingMode(JSGlobalData&, unsigned
inline JSArray* JSArray::create(JSGlobalData& globalData, Structure* structure, unsigned initialLength)
{
Butterfly* butterfly;
- if (LIKELY(!hasArrayStorage(structure->indexingType()))) {
- ASSERT(
- hasUndecided(structure->indexingType())
- || hasInt32(structure->indexingType())
- || hasDouble(structure->indexingType())
- || hasContiguous(structure->indexingType()));
- unsigned vectorLength;
- butterfly = createContiguousArrayButterfly(globalData, initialLength, vectorLength);
+ if (LIKELY(structure->indexingType() == ArrayWithContiguous)) {
+ butterfly = createContiguousArrayButterfly(globalData, initialLength);
ASSERT(initialLength < MIN_SPARSE_ARRAY_INDEX);
- if (hasDouble(structure->indexingType())) {
- for (unsigned i = 0; i < vectorLength; ++i)
- butterfly->contiguousDouble()[i] = QNaN;
- }
} else {
ASSERT(
structure->indexingType() == ArrayWithSlowPutArrayStorage
- || structure->indexingType() == ArrayWithArrayStorage);
+ || (initialLength && structure->indexingType() == ArrayWithArrayStorage));
butterfly = createArrayButterfly(globalData, initialLength);
}
JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure, butterfly);
@@ -232,13 +221,8 @@ inline JSArray* JSArray::tryCreateUninitialized(JSGlobalData& globalData, Struct
return 0;
Butterfly* butterfly;
- if (LIKELY(!hasArrayStorage(structure->indexingType()))) {
- ASSERT(
- hasUndecided(structure->indexingType())
- || hasInt32(structure->indexingType())
- || hasDouble(structure->indexingType())
- || hasContiguous(structure->indexingType()));
-
+ if (LIKELY(structure->indexingType() == ArrayWithContiguous)) {
+
void* temp;
if (!globalData.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)), &temp))
return 0;
diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h
index df31b8542..3b37613d1 100644
--- a/Source/JavaScriptCore/runtime/JSCell.h
+++ b/Source/JavaScriptCore/runtime/JSCell.h
@@ -28,9 +28,9 @@
#include "ConstructData.h"
#include "Heap.h"
#include "JSLock.h"
-#include "JSValueInlines.h"
+#include "JSValueInlineMethods.h"
#include "SlotVisitor.h"
-#include "SlotVisitorInlines.h"
+#include "SlotVisitorInlineMethods.h"
#include "TypedArrayDescriptor.h"
#include "WriteBarrier.h"
#include <wtf/Noncopyable.h>
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index a7c6c8c18..c466a2b04 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -230,16 +230,9 @@ void JSGlobalObject::reset(JSValue prototype)
m_callbackObjectStructure.set(exec->globalData(), this, JSCallbackObject<JSDestructibleObject>::createStructure(exec->globalData(), this, m_objectPrototype.get()));
m_arrayPrototype.set(exec->globalData(), this, ArrayPrototype::create(exec, this, ArrayPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get())));
-
- m_originalArrayStructureForIndexingShape[UndecidedShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithUndecided));
- m_originalArrayStructureForIndexingShape[Int32Shape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithInt32));
- m_originalArrayStructureForIndexingShape[DoubleShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithDouble));
- m_originalArrayStructureForIndexingShape[ContiguousShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithContiguous));
- m_originalArrayStructureForIndexingShape[ArrayStorageShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithArrayStorage));
- m_originalArrayStructureForIndexingShape[SlowPutArrayStorageShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithSlowPutArrayStorage));
- for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
- m_arrayStructureForIndexingShapeDuringAllocation[i] = m_originalArrayStructureForIndexingShape[i];
-
+ m_arrayStructure.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithContiguous));
+ m_arrayStructureWithArrayStorage.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithArrayStorage));
+ m_arrayStructureForSlowPut.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithSlowPutArrayStorage));
m_regExpMatchesArrayStructure.set(exec->globalData(), this, RegExpMatchesArray::createStructure(exec->globalData(), this, m_arrayPrototype.get()));
m_stringPrototype.set(exec->globalData(), this, StringPrototype::create(exec, this, StringPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get())));
@@ -367,9 +360,7 @@ inline bool hasBrokenIndexing(JSObject* object)
{
// This will change if we have more indexing types.
IndexingType type = object->structure()->indexingType();
- // This could be made obviously more efficient, but isn't made so right now, because
- // we expect this to be an unlikely slow path anyway.
- return hasUndecided(type) || hasInt32(type) || hasDouble(type) || hasContiguous(type) || hasFastArrayStorage(type);
+ return hasContiguous(type) || hasFastArrayStorage(type);
}
void ObjectsWithBrokenIndexingFinder::operator()(JSCell* cell)
@@ -421,8 +412,8 @@ void JSGlobalObject::haveABadTime(JSGlobalData& globalData)
// Make sure that all JSArray allocations that load the appropriate structure from
// this object now load a structure that uses SlowPut.
- for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
- m_arrayStructureForIndexingShapeDuringAllocation[i].set(globalData, this, originalArrayStructureForIndexingType(ArrayWithSlowPutArrayStorage));
+ m_arrayStructure.set(globalData, this, m_arrayStructureForSlowPut.get());
+ m_arrayStructureWithArrayStorage.set(globalData, this, m_arrayStructureForSlowPut.get());
// Make sure that all objects that have indexed storage switch to the slow kind of
// indexed storage.
@@ -497,10 +488,9 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
visitor.append(&thisObject->m_activationStructure);
visitor.append(&thisObject->m_nameScopeStructure);
visitor.append(&thisObject->m_argumentsStructure);
- for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
- visitor.append(&thisObject->m_originalArrayStructureForIndexingShape[i]);
- for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
- visitor.append(&thisObject->m_arrayStructureForIndexingShapeDuringAllocation[i]);
+ visitor.append(&thisObject->m_arrayStructure);
+ visitor.append(&thisObject->m_arrayStructureWithArrayStorage);
+ visitor.append(&thisObject->m_arrayStructureForSlowPut);
visitor.append(&thisObject->m_booleanObjectStructure);
visitor.append(&thisObject->m_callbackConstructorStructure);
visitor.append(&thisObject->m_callbackFunctionStructure);
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index 121b71b72..3212363ab 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -22,7 +22,6 @@
#ifndef JSGlobalObject_h
#define JSGlobalObject_h
-#include "ArrayAllocationProfile.h"
#include "JSArray.h"
#include "JSGlobalData.h"
#include "JSSegmentedVariableObject.h"
@@ -131,12 +130,9 @@ namespace JSC {
WriteBarrier<Structure> m_activationStructure;
WriteBarrier<Structure> m_nameScopeStructure;
WriteBarrier<Structure> m_argumentsStructure;
-
- // Lists the actual structures used for having these particular indexing shapes.
- WriteBarrier<Structure> m_originalArrayStructureForIndexingShape[NumberOfIndexingShapes];
- // Lists the structures we should use during allocation for these particular indexing shapes.
- WriteBarrier<Structure> m_arrayStructureForIndexingShapeDuringAllocation[NumberOfIndexingShapes];
-
+ WriteBarrier<Structure> m_arrayStructure; // This gets set to m_arrayStructureForSlowPut as soon as we decide to have a bad time.
+ WriteBarrier<Structure> m_arrayStructureWithArrayStorage; // This gets set to m_arrayStructureForSlowPut as soon as we decide to have a bad time.
+ WriteBarrier<Structure> m_arrayStructureForSlowPut;
WriteBarrier<Structure> m_booleanObjectStructure;
WriteBarrier<Structure> m_callbackConstructorStructure;
WriteBarrier<Structure> m_callbackFunctionStructure;
@@ -279,26 +275,14 @@ namespace JSC {
Structure* activationStructure() const { return m_activationStructure.get(); }
Structure* nameScopeStructure() const { return m_nameScopeStructure.get(); }
Structure* argumentsStructure() const { return m_argumentsStructure.get(); }
- Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const
- {
- ASSERT(indexingType & IsArray);
- return m_originalArrayStructureForIndexingShape[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get();
- }
- Structure* arrayStructureForIndexingTypeDuringAllocation(IndexingType indexingType) const
- {
- ASSERT(indexingType & IsArray);
- return m_arrayStructureForIndexingShapeDuringAllocation[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get();
- }
- Structure* arrayStructureForProfileDuringAllocation(ArrayAllocationProfile* profile) const
- {
- return arrayStructureForIndexingTypeDuringAllocation(ArrayAllocationProfile::selectIndexingTypeFor(profile));
- }
-
+ Structure* arrayStructure() const { return m_arrayStructure.get(); }
+ Structure* arrayStructureWithArrayStorage() const { return m_arrayStructureWithArrayStorage.get(); }
+ void* addressOfArrayStructure() { return &m_arrayStructure; }
+ void* addressOfArrayStructureWithArrayStorage() { return &m_arrayStructureWithArrayStorage; }
bool isOriginalArrayStructure(Structure* structure)
{
- return originalArrayStructureForIndexingType(structure->indexingType() | IsArray) == structure;
+ return structure == m_arrayStructure.get() || structure == m_arrayStructureWithArrayStorage.get();
}
-
Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); }
Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); }
Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); }
@@ -513,34 +497,34 @@ namespace JSC {
return constructEmptyObject(exec, exec->lexicalGlobalObject());
}
- inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0)
+ inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject, unsigned initialLength = 0)
{
- return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->globalData(), initialLength >= MIN_SPARSE_ARRAY_INDEX ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : globalObject->arrayStructureForProfileDuringAllocation(profile), initialLength));
+ return JSArray::create(exec->globalData(), initialLength >= MIN_SPARSE_ARRAY_INDEX ? globalObject->arrayStructureWithArrayStorage() : globalObject->arrayStructure(), initialLength);
}
- inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, unsigned initialLength = 0)
+ inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength = 0)
{
- return constructEmptyArray(exec, profile, exec->lexicalGlobalObject(), initialLength);
+ return constructEmptyArray(exec, exec->lexicalGlobalObject(), initialLength);
}
- inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const ArgList& values)
+ inline JSArray* constructArray(ExecState* exec, JSGlobalObject* globalObject, const ArgList& values)
{
- return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values));
+ return constructArray(exec, globalObject->arrayStructure(), values);
}
- inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const ArgList& values)
+ inline JSArray* constructArray(ExecState* exec, const ArgList& values)
{
- return constructArray(exec, profile, exec->lexicalGlobalObject(), values);
+ return constructArray(exec, exec->lexicalGlobalObject(), values);
}
- inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length)
+ inline JSArray* constructArray(ExecState* exec, JSGlobalObject* globalObject, const JSValue* values, unsigned length)
{
- return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values, length));
+ return constructArray(exec, globalObject->arrayStructure(), values, length);
}
- inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length)
+ inline JSArray* constructArray(ExecState* exec, const JSValue* values, unsigned length)
{
- return constructArray(exec, profile, exec->lexicalGlobalObject(), values, length);
+ return constructArray(exec, exec->lexicalGlobalObject(), values, length);
}
class DynamicGlobalObjectScope {
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index a67896b1a..6a3fb84e4 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -24,14 +24,14 @@
#include "config.h"
#include "JSObject.h"
-#include "ButterflyInlines.h"
-#include "CopiedSpaceInlines.h"
+#include "ButterflyInlineMethods.h"
+#include "CopiedSpaceInlineMethods.h"
#include "CopyVisitor.h"
-#include "CopyVisitorInlines.h"
+#include "CopyVisitorInlineMethods.h"
#include "DatePrototype.h"
#include "ErrorConstructor.h"
#include "GetterSetter.h"
-#include "IndexingHeaderInlines.h"
+#include "IndexingHeaderInlineMethods.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "Lookup.h"
@@ -42,7 +42,7 @@
#include "PropertyDescriptor.h"
#include "PropertyNameArray.h"
#include "Reject.h"
-#include "SlotVisitorInlines.h"
+#include "SlotVisitorInlineMethods.h"
#include <math.h>
#include <wtf/Assertions.h>
@@ -129,16 +129,7 @@ ALWAYS_INLINE void JSObject::copyButterfly(CopyVisitor& visitor, Butterfly* butt
size_t count;
switch (structure->indexingType()) {
- case ALL_UNDECIDED_INDEXING_TYPES: {
- currentTarget = 0;
- currentSource = 0;
- count = 0;
- break;
- }
-
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- case ALL_INT32_INDEXING_TYPES:
- case ALL_DOUBLE_INDEXING_TYPES: {
+ case ALL_CONTIGUOUS_INDEXING_TYPES: {
currentTarget = newButterfly->contiguous();
currentSource = butterfly->contiguous();
ASSERT(newButterfly->publicLength() <= newButterfly->vectorLength());
@@ -161,7 +152,8 @@ ALWAYS_INLINE void JSObject::copyButterfly(CopyVisitor& visitor, Butterfly* butt
break;
}
- memcpy(currentTarget, currentSource, count * sizeof(EncodedJSValue));
+ while (count--)
+ (currentTarget++)->setWithoutWriteBarrier((currentSource++)->get());
}
m_butterfly = newButterfly;
@@ -280,10 +272,8 @@ bool JSObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned
switch (thisObject->structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
- case ALL_UNDECIDED_INDEXING_TYPES:
break;
- case ALL_INT32_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES: {
Butterfly* butterfly = thisObject->m_butterfly;
if (i >= butterfly->vectorLength())
@@ -298,20 +288,6 @@ bool JSObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned
return false;
}
- case ALL_DOUBLE_INDEXING_TYPES: {
- Butterfly* butterfly = thisObject->m_butterfly;
- if (i >= butterfly->vectorLength())
- return false;
-
- double value = butterfly->contiguousDouble()[i];
- if (value == value) {
- slot.setValue(JSValue(JSValue::EncodeAsDouble, value));
- return true;
- }
-
- return false;
- }
-
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = thisObject->m_butterfly->arrayStorage();
if (i >= storage->length())
@@ -429,22 +405,6 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
case ALL_BLANK_INDEXING_TYPES:
break;
- case ALL_UNDECIDED_INDEXING_TYPES: {
- thisObject->convertUndecidedForValue(exec->globalData(), value);
- // Reloop.
- putByIndex(cell, exec, propertyName, value, shouldThrow);
- return;
- }
-
- case ALL_INT32_INDEXING_TYPES: {
- if (!value.isInt32()) {
- thisObject->convertInt32ForValue(exec->globalData(), value);
- putByIndex(cell, exec, propertyName, value, shouldThrow);
- return;
- }
- // Fall through.
- }
-
case ALL_CONTIGUOUS_INDEXING_TYPES: {
Butterfly* butterfly = thisObject->m_butterfly;
if (propertyName >= butterfly->vectorLength())
@@ -455,29 +415,6 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
return;
}
- case ALL_DOUBLE_INDEXING_TYPES: {
- if (!value.isNumber()) {
- thisObject->convertDoubleToContiguous(exec->globalData());
- // Reloop.
- putByIndex(cell, exec, propertyName, value, shouldThrow);
- return;
- }
- double valueAsDouble = value.asNumber();
- if (valueAsDouble != valueAsDouble) {
- thisObject->convertDoubleToContiguous(exec->globalData());
- // Reloop.
- putByIndex(cell, exec, propertyName, value, shouldThrow);
- return;
- }
- Butterfly* butterfly = thisObject->m_butterfly;
- if (propertyName >= butterfly->vectorLength())
- break;
- butterfly->contiguousDouble()[propertyName] = valueAsDouble;
- if (propertyName >= butterfly->publicLength())
- butterfly->setPublicLength(propertyName + 1);
- return;
- }
-
case NonArrayWithArrayStorage:
case ArrayWithArrayStorage: {
ArrayStorage* storage = thisObject->m_butterfly->arrayStorage();
@@ -570,13 +507,10 @@ ArrayStorage* JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists
void JSObject::enterDictionaryIndexingMode(JSGlobalData& globalData)
{
switch (structure()->indexingType()) {
- case ALL_UNDECIDED_INDEXING_TYPES:
- case ALL_INT32_INDEXING_TYPES:
- case ALL_DOUBLE_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
// NOTE: this is horribly inefficient, as it will perform two conversions. We could optimize
// this case if we ever cared.
- enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, ensureArrayStorageSlow(globalData));
+ enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertContiguousToArrayStorage(globalData));
break;
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, m_butterfly->arrayStorage());
@@ -600,7 +534,7 @@ void JSObject::notifyPresenceOfIndexedAccessors(JSGlobalData& globalData)
globalObject()->haveABadTime(globalData);
}
-Butterfly* JSObject::createInitialIndexedStorage(JSGlobalData& globalData, unsigned length, size_t elementSize)
+WriteBarrier<Unknown>* JSObject::createInitialContiguous(JSGlobalData& globalData, unsigned length)
{
ASSERT(length < MAX_ARRAY_INDEX);
IndexingType oldType = structure()->indexingType();
@@ -610,41 +544,9 @@ Butterfly* JSObject::createInitialIndexedStorage(JSGlobalData& globalData, unsig
unsigned vectorLength = std::max(length, BASE_VECTOR_LEN);
Butterfly* newButterfly = m_butterfly->growArrayRight(
globalData, structure(), structure()->outOfLineCapacity(), false, 0,
- elementSize * vectorLength);
+ sizeof(EncodedJSValue) * vectorLength);
newButterfly->setPublicLength(length);
newButterfly->setVectorLength(vectorLength);
- return newButterfly;
-}
-
-Butterfly* JSObject::createInitialUndecided(JSGlobalData& globalData, unsigned length)
-{
- Butterfly* newButterfly = createInitialIndexedStorage(globalData, length, sizeof(EncodedJSValue));
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateUndecided);
- setButterfly(globalData, newButterfly, newStructure);
- return newButterfly;
-}
-
-WriteBarrier<Unknown>* JSObject::createInitialInt32(JSGlobalData& globalData, unsigned length)
-{
- Butterfly* newButterfly = createInitialIndexedStorage(globalData, length, sizeof(EncodedJSValue));
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateInt32);
- setButterfly(globalData, newButterfly, newStructure);
- return newButterfly->contiguousInt32();
-}
-
-double* JSObject::createInitialDouble(JSGlobalData& globalData, unsigned length)
-{
- Butterfly* newButterfly = createInitialIndexedStorage(globalData, length, sizeof(double));
- for (unsigned i = newButterfly->vectorLength(); i--;)
- newButterfly->contiguousDouble()[i] = QNaN;
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateDouble);
- setButterfly(globalData, newButterfly, newStructure);
- return newButterfly->contiguousDouble();
-}
-
-WriteBarrier<Unknown>* JSObject::createInitialContiguous(JSGlobalData& globalData, unsigned length)
-{
- Butterfly* newButterfly = createInitialIndexedStorage(globalData, length, sizeof(EncodedJSValue));
Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateContiguous);
setButterfly(globalData, newButterfly, newStructure);
return newButterfly->contiguous();
@@ -675,33 +577,10 @@ ArrayStorage* JSObject::createInitialArrayStorage(JSGlobalData& globalData)
return createArrayStorage(globalData, 0, BASE_VECTOR_LEN);
}
-WriteBarrier<Unknown>* JSObject::convertUndecidedToInt32(JSGlobalData& globalData)
-{
- ASSERT(hasUndecided(structure()->indexingType()));
- setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateInt32));
- return m_butterfly->contiguousInt32();
-}
-
-double* JSObject::convertUndecidedToDouble(JSGlobalData& globalData)
+ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength)
{
- ASSERT(hasUndecided(structure()->indexingType()));
-
- for (unsigned i = m_butterfly->vectorLength(); i--;)
- m_butterfly->contiguousDouble()[i] = QNaN;
+ ASSERT(hasContiguous(structure()->indexingType()));
- setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateDouble));
- return m_butterfly->contiguousDouble();
-}
-
-WriteBarrier<Unknown>* JSObject::convertUndecidedToContiguous(JSGlobalData& globalData)
-{
- ASSERT(hasUndecided(structure()->indexingType()));
- setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateContiguous));
- return m_butterfly->contiguous();
-}
-
-ArrayStorage* JSObject::constructConvertedArrayStorageWithoutCopyingElements(JSGlobalData& globalData, unsigned neededLength)
-{
unsigned publicLength = m_butterfly->publicLength();
unsigned propertyCapacity = structure()->outOfLineCapacity();
unsigned propertySize = structure()->outOfLineSize();
@@ -720,141 +599,7 @@ ArrayStorage* JSObject::constructConvertedArrayStorageWithoutCopyingElements(JSG
newStorage->m_sparseMap.clear();
newStorage->m_indexBias = 0;
newStorage->m_numValuesInVector = 0;
-
- return newStorage;
-}
-
-ArrayStorage* JSObject::convertUndecidedToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength)
-{
- ASSERT(hasUndecided(structure()->indexingType()));
-
- ArrayStorage* storage = constructConvertedArrayStorageWithoutCopyingElements(globalData, neededLength);
- // No need to copy elements.
-
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), transition);
- setButterfly(globalData, storage->butterfly(), newStructure);
- return storage;
-}
-
-ArrayStorage* JSObject::convertUndecidedToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition)
-{
- return convertUndecidedToArrayStorage(globalData, transition, m_butterfly->vectorLength());
-}
-
-ArrayStorage* JSObject::convertUndecidedToArrayStorage(JSGlobalData& globalData)
-{
- return convertUndecidedToArrayStorage(globalData, structure()->suggestedArrayStorageTransition());
-}
-
-double* JSObject::convertInt32ToDouble(JSGlobalData& globalData)
-{
- ASSERT(hasInt32(structure()->indexingType()));
-
- for (unsigned i = m_butterfly->vectorLength(); i--;) {
- WriteBarrier<Unknown>* current = &m_butterfly->contiguousInt32()[i];
- double* currentAsDouble = bitwise_cast<double*>(current);
- JSValue v = current->get();
- if (!v) {
- *currentAsDouble = QNaN;
- continue;
- }
- ASSERT(v.isInt32());
- *currentAsDouble = v.asInt32();
- }
-
- setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateDouble));
- return m_butterfly->contiguousDouble();
-}
-
-WriteBarrier<Unknown>* JSObject::convertInt32ToContiguous(JSGlobalData& globalData)
-{
- ASSERT(hasInt32(structure()->indexingType()));
-
- setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateContiguous));
- return m_butterfly->contiguous();
-}
-
-ArrayStorage* JSObject::convertInt32ToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength)
-{
- ASSERT(hasInt32(structure()->indexingType()));
-
- ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(globalData, neededLength);
- for (unsigned i = m_butterfly->publicLength(); i--;) {
- JSValue v = m_butterfly->contiguous()[i].get();
- if (!v)
- continue;
- newStorage->m_vector[i].setWithoutWriteBarrier(v);
- newStorage->m_numValuesInVector++;
- }
-
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), transition);
- setButterfly(globalData, newStorage->butterfly(), newStructure);
- return newStorage;
-}
-
-ArrayStorage* JSObject::convertInt32ToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition)
-{
- return convertInt32ToArrayStorage(globalData, transition, m_butterfly->vectorLength());
-}
-
-ArrayStorage* JSObject::convertInt32ToArrayStorage(JSGlobalData& globalData)
-{
- return convertInt32ToArrayStorage(globalData, structure()->suggestedArrayStorageTransition());
-}
-
-WriteBarrier<Unknown>* JSObject::convertDoubleToContiguous(JSGlobalData& globalData)
-{
- ASSERT(hasDouble(structure()->indexingType()));
-
- for (unsigned i = m_butterfly->vectorLength(); i--;) {
- double* current = &m_butterfly->contiguousDouble()[i];
- WriteBarrier<Unknown>* currentAsValue = bitwise_cast<WriteBarrier<Unknown>*>(current);
- double value = *current;
- if (value != value) {
- currentAsValue->clear();
- continue;
- }
- currentAsValue->setWithoutWriteBarrier(JSValue(JSValue::EncodeAsDouble, value));
- }
-
- setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateContiguous));
- return m_butterfly->contiguous();
-}
-
-ArrayStorage* JSObject::convertDoubleToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength)
-{
- ASSERT(hasDouble(structure()->indexingType()));
-
- ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(globalData, neededLength);
- for (unsigned i = m_butterfly->publicLength(); i--;) {
- double value = m_butterfly->contiguousDouble()[i];
- if (value != value)
- continue;
- newStorage->m_vector[i].setWithoutWriteBarrier(JSValue(JSValue::EncodeAsDouble, value));
- newStorage->m_numValuesInVector++;
- }
-
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), transition);
- setButterfly(globalData, newStorage->butterfly(), newStructure);
- return newStorage;
-}
-
-ArrayStorage* JSObject::convertDoubleToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition)
-{
- return convertDoubleToArrayStorage(globalData, transition, m_butterfly->vectorLength());
-}
-
-ArrayStorage* JSObject::convertDoubleToArrayStorage(JSGlobalData& globalData)
-{
- return convertDoubleToArrayStorage(globalData, structure()->suggestedArrayStorageTransition());
-}
-
-ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength)
-{
- ASSERT(hasContiguous(structure()->indexingType()));
-
- ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(globalData, neededLength);
- for (unsigned i = m_butterfly->publicLength(); i--;) {
+ for (unsigned i = publicLength; i--;) {
JSValue v = m_butterfly->contiguous()[i].get();
if (!v)
continue;
@@ -863,7 +608,7 @@ ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData
}
Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), transition);
- setButterfly(globalData, newStorage->butterfly(), newStructure);
+ setButterfly(globalData, newButterfly, newStructure);
return newStorage;
}
@@ -877,154 +622,48 @@ ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData
return convertContiguousToArrayStorage(globalData, structure()->suggestedArrayStorageTransition());
}
-void JSObject::convertUndecidedForValue(JSGlobalData& globalData, JSValue value)
-{
- if (value.isInt32()) {
- convertUndecidedToInt32(globalData);
- return;
- }
-
- if (value.isDouble()) {
- convertUndecidedToDouble(globalData);
- return;
- }
-
- convertUndecidedToContiguous(globalData);
-}
-
-void JSObject::convertInt32ForValue(JSGlobalData& globalData, JSValue value)
-{
- ASSERT(!value.isInt32());
-
- if (value.isDouble()) {
- convertInt32ToDouble(globalData);
- return;
- }
-
- convertInt32ToContiguous(globalData);
-}
-
-void JSObject::setIndexQuicklyToUndecided(JSGlobalData& globalData, unsigned index, JSValue value)
-{
- ASSERT(index < m_butterfly->publicLength());
- ASSERT(index < m_butterfly->vectorLength());
- convertUndecidedForValue(globalData, value);
- setIndexQuickly(globalData, index, value);
-}
-
-void JSObject::convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(JSGlobalData& globalData, unsigned index, JSValue value)
-{
- ASSERT(!value.isInt32());
- convertInt32ForValue(globalData, value);
- setIndexQuickly(globalData, index, value);
-}
-
-void JSObject::convertDoubleToContiguousWhilePerformingSetIndex(JSGlobalData& globalData, unsigned index, JSValue value)
-{
- ASSERT(!value.isNumber() || value.asNumber() != value.asNumber());
- convertDoubleToContiguous(globalData);
- setIndexQuickly(globalData, index, value);
-}
-
-WriteBarrier<Unknown>* JSObject::ensureInt32Slow(JSGlobalData& globalData)
+WriteBarrier<Unknown>* JSObject::ensureContiguousSlow(JSGlobalData& globalData)
{
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
if (UNLIKELY(indexingShouldBeSparse() || structure()->needsSlowPutIndexing()))
return 0;
- return createInitialInt32(globalData, 0);
-
- case ALL_UNDECIDED_INDEXING_TYPES:
- return convertUndecidedToInt32(globalData);
-
- case ALL_DOUBLE_INDEXING_TYPES:
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return 0;
+ return createInitialContiguous(globalData, 0);
default:
- CRASH();
+ ASSERT_NOT_REACHED();
return 0;
}
}
-double* JSObject::ensureDoubleSlow(JSGlobalData& globalData)
+ArrayStorage* JSObject::ensureArrayStorageSlow(JSGlobalData& globalData)
{
switch (structure()->indexingType()) {
- case ALL_BLANK_INDEXING_TYPES:
- if (UNLIKELY(indexingShouldBeSparse() || structure()->needsSlowPutIndexing()))
- return 0;
- return createInitialDouble(globalData, 0);
-
- case ALL_UNDECIDED_INDEXING_TYPES:
- return convertUndecidedToDouble(globalData);
-
- case ALL_INT32_INDEXING_TYPES:
- return convertInt32ToDouble(globalData);
-
case ALL_CONTIGUOUS_INDEXING_TYPES:
- case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return 0;
+ ASSERT(!indexingShouldBeSparse());
+ ASSERT(!structure()->needsSlowPutIndexing());
+ return convertContiguousToArrayStorage(globalData);
- default:
- CRASH();
- return 0;
- }
-}
-
-WriteBarrier<Unknown>* JSObject::ensureContiguousSlow(JSGlobalData& globalData)
-{
- switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
- if (UNLIKELY(indexingShouldBeSparse() || structure()->needsSlowPutIndexing()))
- return 0;
- return createInitialContiguous(globalData, 0);
-
- case ALL_UNDECIDED_INDEXING_TYPES:
- return convertUndecidedToContiguous(globalData);
-
- case ALL_INT32_INDEXING_TYPES:
- return convertInt32ToContiguous(globalData);
-
- case ALL_DOUBLE_INDEXING_TYPES:
- return convertDoubleToContiguous(globalData);
-
- case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return 0;
+ if (UNLIKELY(indexingShouldBeSparse()))
+ return ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData);
+ return createInitialArrayStorage(globalData);
default:
- CRASH();
+ ASSERT_NOT_REACHED();
return 0;
}
}
-ArrayStorage* JSObject::ensureArrayStorageSlow(JSGlobalData& globalData)
+Butterfly* JSObject::ensureIndexedStorageSlow(JSGlobalData& globalData)
{
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
+ if (UNLIKELY(structure()->needsSlowPutIndexing()))
+ return createInitialArrayStorage(globalData)->butterfly();
if (UNLIKELY(indexingShouldBeSparse()))
- return ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData);
- return createInitialArrayStorage(globalData);
-
- case ALL_UNDECIDED_INDEXING_TYPES:
- ASSERT(!indexingShouldBeSparse());
- ASSERT(!structure()->needsSlowPutIndexing());
- return convertUndecidedToArrayStorage(globalData);
-
- case ALL_INT32_INDEXING_TYPES:
- ASSERT(!indexingShouldBeSparse());
- ASSERT(!structure()->needsSlowPutIndexing());
- return convertInt32ToArrayStorage(globalData);
-
- case ALL_DOUBLE_INDEXING_TYPES:
- ASSERT(!indexingShouldBeSparse());
- ASSERT(!structure()->needsSlowPutIndexing());
- return convertDoubleToArrayStorage(globalData);
-
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- ASSERT(!indexingShouldBeSparse());
- ASSERT(!structure()->needsSlowPutIndexing());
- return convertContiguousToArrayStorage(globalData);
+ return ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData)->butterfly();
+ return Butterfly::fromContiguous(createInitialContiguous(globalData, 0));
default:
ASSERT_NOT_REACHED();
@@ -1035,6 +674,13 @@ ArrayStorage* JSObject::ensureArrayStorageSlow(JSGlobalData& globalData)
ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(JSGlobalData& globalData)
{
switch (structure()->indexingType()) {
+ case ALL_CONTIGUOUS_INDEXING_TYPES:
+ // FIXME: This could be made way more efficient, if we cared.
+ return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertContiguousToArrayStorage(globalData));
+
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
+ return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, m_butterfly->arrayStorage());
+
case ALL_BLANK_INDEXING_TYPES: {
createArrayStorage(globalData, 0, 0);
SparseArrayValueMap* map = allocateSparseIndexMap(globalData);
@@ -1042,23 +688,8 @@ ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(J
return arrayStorage();
}
- case ALL_UNDECIDED_INDEXING_TYPES:
- return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertUndecidedToArrayStorage(globalData));
-
- case ALL_INT32_INDEXING_TYPES:
- return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertInt32ToArrayStorage(globalData));
-
- case ALL_DOUBLE_INDEXING_TYPES:
- return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertDoubleToArrayStorage(globalData));
-
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertContiguousToArrayStorage(globalData));
-
- case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, m_butterfly->arrayStorage());
-
default:
- CRASH();
+ ASSERT_NOT_REACHED();
return 0;
}
}
@@ -1066,21 +697,10 @@ ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(J
void JSObject::switchToSlowPutArrayStorage(JSGlobalData& globalData)
{
switch (structure()->indexingType()) {
- case ALL_UNDECIDED_INDEXING_TYPES:
- convertUndecidedToArrayStorage(globalData, AllocateSlowPutArrayStorage);
- break;
-
- case ALL_INT32_INDEXING_TYPES:
- convertInt32ToArrayStorage(globalData, AllocateSlowPutArrayStorage);
- break;
-
- case ALL_DOUBLE_INDEXING_TYPES:
- convertDoubleToArrayStorage(globalData, AllocateSlowPutArrayStorage);
- break;
-
- case ALL_CONTIGUOUS_INDEXING_TYPES:
+ case ALL_CONTIGUOUS_INDEXING_TYPES: {
convertContiguousToArrayStorage(globalData, AllocateSlowPutArrayStorage);
break;
+ }
case NonArrayWithArrayStorage:
case ArrayWithArrayStorage: {
@@ -1090,7 +710,7 @@ void JSObject::switchToSlowPutArrayStorage(JSGlobalData& globalData)
}
default:
- CRASH();
+ ASSERT_NOT_REACHED();
break;
}
}
@@ -1257,10 +877,8 @@ bool JSObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
switch (thisObject->structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
- case ALL_UNDECIDED_INDEXING_TYPES:
return true;
- case ALL_INT32_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES: {
Butterfly* butterfly = thisObject->m_butterfly;
if (i >= butterfly->vectorLength())
@@ -1269,14 +887,6 @@ bool JSObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
return true;
}
- case ALL_DOUBLE_INDEXING_TYPES: {
- Butterfly* butterfly = thisObject->m_butterfly;
- if (i >= butterfly->vectorLength())
- return true;
- butterfly->contiguousDouble()[i] = QNaN;
- return true;
- }
-
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = thisObject->m_butterfly->arrayStorage();
@@ -1448,10 +1058,8 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa
// which almost certainly means a different structure for PropertyNameArray.
switch (object->structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
- case ALL_UNDECIDED_INDEXING_TYPES:
break;
- case ALL_INT32_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES: {
Butterfly* butterfly = object->m_butterfly;
unsigned usedLength = butterfly->publicLength();
@@ -1463,18 +1071,6 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa
break;
}
- case ALL_DOUBLE_INDEXING_TYPES: {
- Butterfly* butterfly = object->m_butterfly;
- unsigned usedLength = butterfly->publicLength();
- for (unsigned i = 0; i < usedLength; ++i) {
- double value = butterfly->contiguousDouble()[i];
- if (value != value)
- continue;
- propertyNames.add(Identifier::from(exec, i));
- }
- break;
- }
-
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = object->m_butterfly->arrayStorage();
@@ -1864,10 +1460,9 @@ bool JSObject::attemptToInterceptPutByIndexOnHole(ExecState* exec, unsigned i, J
return asObject(prototypeValue)->attemptToInterceptPutByIndexOnHoleForPrototype(exec, this, i, value, shouldThrow);
}
-template<IndexingType indexingShape>
-void JSObject::putByIndexBeyondVectorLengthWithoutAttributes(ExecState* exec, unsigned i, JSValue value)
+void JSObject::putByIndexBeyondVectorLengthContiguousWithoutAttributes(ExecState* exec, unsigned i, JSValue value)
{
- ASSERT((structure()->indexingType() & IndexingShapeMask) == indexingShape);
+ ASSERT(hasContiguous(structure()->indexingType()));
ASSERT(!indexingShouldBeSparse());
// For us to get here, the index is either greater than the public length, or greater than
@@ -1878,9 +1473,9 @@ void JSObject::putByIndexBeyondVectorLengthWithoutAttributes(ExecState* exec, un
if (i >= MAX_ARRAY_INDEX - 1
|| (i >= MIN_SPARSE_ARRAY_INDEX
- && !isDenseEnoughForVector(i, countElements<indexingShape>(m_butterfly)))) {
+ && !isDenseEnoughForVector(i, countElementsInContiguous(m_butterfly)))) {
ASSERT(i <= MAX_ARRAY_INDEX);
- ensureArrayStorageSlow(globalData);
+ convertContiguousToArrayStorage(globalData, AllocateArrayStorage);
SparseArrayValueMap* map = allocateSparseIndexMap(globalData);
map->putEntry(exec, this, i, value, false);
ASSERT(i >= arrayStorage()->length());
@@ -1888,30 +1483,10 @@ void JSObject::putByIndexBeyondVectorLengthWithoutAttributes(ExecState* exec, un
return;
}
- ensureLength(globalData, i + 1);
+ ensureContiguousLength(globalData, i + 1);
ASSERT(i < m_butterfly->vectorLength());
- switch (indexingShape) {
- case Int32Shape:
- ASSERT(value.isInt32());
- m_butterfly->contiguousInt32()[i].setWithoutWriteBarrier(value);
- break;
-
- case DoubleShape: {
- ASSERT(value.isNumber());
- double valueAsDouble = value.asNumber();
- ASSERT(valueAsDouble == valueAsDouble);
- m_butterfly->contiguousDouble()[i] = valueAsDouble;
- break;
- }
-
- case ContiguousShape:
- m_butterfly->contiguous()[i].set(globalData, this, value);
- break;
-
- default:
- CRASH();
- }
+ m_butterfly->contiguous()[i].set(globalData, this, value);
}
void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, unsigned i, JSValue value, bool shouldThrow, ArrayStorage* storage)
@@ -2017,23 +1592,8 @@ void JSObject::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue
break;
}
- case ALL_UNDECIDED_INDEXING_TYPES: {
- CRASH();
- break;
- }
-
- case ALL_INT32_INDEXING_TYPES: {
- putByIndexBeyondVectorLengthWithoutAttributes<Int32Shape>(exec, i, value);
- break;
- }
-
- case ALL_DOUBLE_INDEXING_TYPES: {
- putByIndexBeyondVectorLengthWithoutAttributes<DoubleShape>(exec, i, value);
- break;
- }
-
case ALL_CONTIGUOUS_INDEXING_TYPES: {
- putByIndexBeyondVectorLengthWithoutAttributes<ContiguousShape>(exec, i, value);
+ putByIndexBeyondVectorLengthContiguousWithoutAttributes(exec, i, value);
break;
}
@@ -2164,49 +1724,12 @@ bool JSObject::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSV
return true;
}
- case ALL_UNDECIDED_INDEXING_TYPES: {
- convertUndecidedForValue(exec->globalData(), value);
- // Reloop.
- return putDirectIndex(exec, i, value, attributes, mode);
- }
-
- case ALL_INT32_INDEXING_TYPES: {
- if (attributes & (ReadOnly | Accessor)) {
- return putDirectIndexBeyondVectorLengthWithArrayStorage(
- exec, i, value, attributes, mode, convertInt32ToArrayStorage(globalData));
- }
- if (!value.isInt32()) {
- convertInt32ForValue(globalData, value);
- return putDirectIndexBeyondVectorLength(exec, i, value, attributes, mode);
- }
- putByIndexBeyondVectorLengthWithoutAttributes<Int32Shape>(exec, i, value);
- return true;
- }
-
- case ALL_DOUBLE_INDEXING_TYPES: {
- if (attributes & (ReadOnly | Accessor)) {
- return putDirectIndexBeyondVectorLengthWithArrayStorage(
- exec, i, value, attributes, mode, convertDoubleToArrayStorage(globalData));
- }
- if (!value.isNumber()) {
- convertDoubleToContiguous(globalData);
- return putDirectIndexBeyondVectorLength(exec, i, value, attributes, mode);
- }
- double valueAsDouble = value.asNumber();
- if (valueAsDouble != valueAsDouble) {
- convertDoubleToContiguous(globalData);
- return putDirectIndexBeyondVectorLength(exec, i, value, attributes, mode);
- }
- putByIndexBeyondVectorLengthWithoutAttributes<DoubleShape>(exec, i, value);
- return true;
- }
-
case ALL_CONTIGUOUS_INDEXING_TYPES: {
if (attributes & (ReadOnly | Accessor)) {
return putDirectIndexBeyondVectorLengthWithArrayStorage(
exec, i, value, attributes, mode, convertContiguousToArrayStorage(globalData));
}
- putByIndexBeyondVectorLengthWithoutAttributes<ContiguousShape>(exec, i, value);
+ putByIndexBeyondVectorLengthContiguousWithoutAttributes(exec, i, value);
return true;
}
@@ -2246,65 +1769,33 @@ ALWAYS_INLINE unsigned JSObject::getNewVectorLength(unsigned desiredLength)
unsigned vectorLength;
unsigned length;
- if (hasIndexedProperties(structure()->indexingType())) {
- vectorLength = m_butterfly->vectorLength();
- length = m_butterfly->publicLength();
- } else {
+ switch (structure()->indexingType()) {
+ case ALL_BLANK_INDEXING_TYPES:
vectorLength = 0;
length = 0;
+ break;
+ case ALL_CONTIGUOUS_INDEXING_TYPES:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
+ vectorLength = m_butterfly->vectorLength();
+ length = m_butterfly->publicLength();
+ break;
+ default:
+ CRASH();
+ return 0;
}
-
return getNewVectorLength(vectorLength, length, desiredLength);
}
-template<IndexingType indexingShape>
-unsigned JSObject::countElements(Butterfly* butterfly)
+unsigned JSObject::countElementsInContiguous(Butterfly* butterfly)
{
unsigned numValues = 0;
for (unsigned i = butterfly->publicLength(); i--;) {
- switch (indexingShape) {
- case Int32Shape:
- case ContiguousShape:
- if (butterfly->contiguous()[i])
- numValues++;
- break;
-
- case DoubleShape: {
- double value = butterfly->contiguousDouble()[i];
- if (value == value)
- numValues++;
- break;
- }
-
- default:
- CRASH();
- }
+ if (butterfly->contiguous()[i])
+ numValues++;
}
return numValues;
}
-unsigned JSObject::countElements()
-{
- switch (structure()->indexingType()) {
- case ALL_BLANK_INDEXING_TYPES:
- case ALL_UNDECIDED_INDEXING_TYPES:
- return 0;
-
- case ALL_INT32_INDEXING_TYPES:
- return countElements<Int32Shape>(m_butterfly);
-
- case ALL_DOUBLE_INDEXING_TYPES:
- return countElements<DoubleShape>(m_butterfly);
-
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- return countElements<ContiguousShape>(m_butterfly);
-
- default:
- CRASH();
- return 0;
- }
-}
-
bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength)
{
// This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map
@@ -2348,24 +1839,19 @@ bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength
return true;
}
-void JSObject::ensureLengthSlow(JSGlobalData& globalData, unsigned length)
+void JSObject::ensureContiguousLengthSlow(JSGlobalData& globalData, unsigned length)
{
ASSERT(length < MAX_ARRAY_INDEX);
- ASSERT(hasContiguous(structure()->indexingType()) || hasInt32(structure()->indexingType()) || hasDouble(structure()->indexingType()) || hasUndecided(structure()->indexingType()));
+ ASSERT(hasContiguous(structure()->indexingType()));
ASSERT(length > m_butterfly->vectorLength());
unsigned newVectorLength = std::min(
length << 1,
MAX_STORAGE_VECTOR_LENGTH);
- unsigned oldVectorLength = m_butterfly->vectorLength();
m_butterfly = m_butterfly->growArrayRight(
globalData, structure(), structure()->outOfLineCapacity(), true,
- oldVectorLength * sizeof(EncodedJSValue),
+ m_butterfly->vectorLength() * sizeof(EncodedJSValue),
newVectorLength * sizeof(EncodedJSValue));
- if (hasDouble(structure()->indexingType())) {
- for (unsigned i = oldVectorLength; i < newVectorLength; ++i)
- m_butterfly->contiguousDouble()[i] = QNaN;
- }
m_butterfly->setVectorLength(newVectorLength);
}
@@ -2395,10 +1881,8 @@ bool JSObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, Prope
switch (object->structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
- case ALL_UNDECIDED_INDEXING_TYPES:
return false;
- case ALL_INT32_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES: {
Butterfly* butterfly = object->m_butterfly;
if (i >= butterfly->vectorLength())
@@ -2410,17 +1894,6 @@ bool JSObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, Prope
return true;
}
- case ALL_DOUBLE_INDEXING_TYPES: {
- Butterfly* butterfly = object->m_butterfly;
- if (i >= butterfly->vectorLength())
- return false;
- double value = butterfly->contiguousDouble()[i];
- if (value != value)
- return false;
- descriptor.setDescriptor(JSValue(JSValue::EncodeAsDouble, value), 0);
- return true;
- }
-
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = object->m_butterfly->arrayStorage();
if (i >= storage->length())
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index f9ae73ed4..82455390f 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -151,16 +151,30 @@ public:
unsigned getArrayLength() const
{
- if (!hasIndexedProperties(structure()->indexingType()))
+ switch (structure()->indexingType()) {
+ case ALL_BLANK_INDEXING_TYPES:
return 0;
- return m_butterfly->publicLength();
+ case ALL_CONTIGUOUS_INDEXING_TYPES:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
+ return m_butterfly->publicLength();
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
}
unsigned getVectorLength()
{
- if (!hasIndexedProperties(structure()->indexingType()))
+ switch (structure()->indexingType()) {
+ case ALL_BLANK_INDEXING_TYPES:
return 0;
- return m_butterfly->vectorLength();
+ case ALL_CONTIGUOUS_INDEXING_TYPES:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
+ return m_butterfly->vectorLength();
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
}
JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
@@ -200,19 +214,9 @@ public:
{
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
- case ALL_UNDECIDED_INDEXING_TYPES:
return false;
- case ALL_INT32_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
return i < m_butterfly->vectorLength() && m_butterfly->contiguous()[i];
- case ALL_DOUBLE_INDEXING_TYPES: {
- if (i >= m_butterfly->vectorLength())
- return false;
- double value = m_butterfly->contiguousDouble()[i];
- if (value != value)
- return false;
- return true;
- }
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return i < m_butterfly->arrayStorage()->vectorLength() && m_butterfly->arrayStorage()->m_vector[i];
default:
@@ -224,11 +228,8 @@ public:
JSValue getIndexQuickly(unsigned i)
{
switch (structure()->indexingType()) {
- case ALL_INT32_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
return m_butterfly->contiguous()[i].get();
- case ALL_DOUBLE_INDEXING_TYPES:
- return JSValue(JSValue::EncodeAsDouble, m_butterfly->contiguousDouble()[i]);
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage()->m_vector[i].get();
default:
@@ -242,19 +243,10 @@ public:
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
break;
- case ALL_INT32_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
if (i < m_butterfly->publicLength())
return m_butterfly->contiguous()[i].get();
break;
- case ALL_DOUBLE_INDEXING_TYPES: {
- if (i >= m_butterfly->publicLength())
- break;
- double result = m_butterfly->contiguousDouble()[i];
- if (result != result)
- break;
- return JSValue(JSValue::EncodeAsDouble, result);
- }
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
if (i < m_butterfly->arrayStorage()->vectorLength())
return m_butterfly->arrayStorage()->m_vector[i].get();
@@ -287,10 +279,7 @@ public:
{
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
- case ALL_UNDECIDED_INDEXING_TYPES:
return false;
- case ALL_INT32_INDEXING_TYPES:
- case ALL_DOUBLE_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
case NonArrayWithArrayStorage:
case ArrayWithArrayStorage:
@@ -309,10 +298,7 @@ public:
{
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
- case ALL_UNDECIDED_INDEXING_TYPES:
return false;
- case ALL_INT32_INDEXING_TYPES:
- case ALL_DOUBLE_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return i < m_butterfly->vectorLength();
@@ -325,14 +311,6 @@ public:
void setIndexQuickly(JSGlobalData& globalData, unsigned i, JSValue v)
{
switch (structure()->indexingType()) {
- case ALL_INT32_INDEXING_TYPES: {
- ASSERT(i < m_butterfly->vectorLength());
- if (!v.isInt32()) {
- convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(globalData, i, v);
- return;
- }
- // Fall through to contiguous case.
- }
case ALL_CONTIGUOUS_INDEXING_TYPES: {
ASSERT(i < m_butterfly->vectorLength());
m_butterfly->contiguous()[i].set(globalData, this, v);
@@ -340,22 +318,6 @@ public:
m_butterfly->setPublicLength(i + 1);
break;
}
- case ALL_DOUBLE_INDEXING_TYPES: {
- ASSERT(i < m_butterfly->vectorLength());
- if (!v.isNumber()) {
- convertDoubleToContiguousWhilePerformingSetIndex(globalData, i, v);
- return;
- }
- double value = v.asNumber();
- if (value != value) {
- convertDoubleToContiguousWhilePerformingSetIndex(globalData, i, v);
- return;
- }
- m_butterfly->contiguousDouble()[i] = value;
- if (i >= m_butterfly->publicLength())
- m_butterfly->setPublicLength(i + 1);
- break;
- }
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
WriteBarrier<Unknown>& x = storage->m_vector[i];
@@ -376,40 +338,12 @@ public:
void initializeIndex(JSGlobalData& globalData, unsigned i, JSValue v)
{
switch (structure()->indexingType()) {
- case ALL_UNDECIDED_INDEXING_TYPES: {
- setIndexQuicklyToUndecided(globalData, i, v);
- break;
- }
- case ALL_INT32_INDEXING_TYPES: {
- ASSERT(i < m_butterfly->publicLength());
- ASSERT(i < m_butterfly->vectorLength());
- if (!v.isInt32()) {
- convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(globalData, i, v);
- break;
- }
- // Fall through.
- }
case ALL_CONTIGUOUS_INDEXING_TYPES: {
ASSERT(i < m_butterfly->publicLength());
ASSERT(i < m_butterfly->vectorLength());
m_butterfly->contiguous()[i].set(globalData, this, v);
break;
}
- case ALL_DOUBLE_INDEXING_TYPES: {
- ASSERT(i < m_butterfly->publicLength());
- ASSERT(i < m_butterfly->vectorLength());
- if (!v.isNumber()) {
- convertDoubleToContiguousWhilePerformingSetIndex(globalData, i, v);
- return;
- }
- double value = v.asNumber();
- if (value != value) {
- convertDoubleToContiguousWhilePerformingSetIndex(globalData, i, v);
- return;
- }
- m_butterfly->contiguousDouble()[i] = value;
- break;
- }
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
ASSERT(i < storage->length());
@@ -426,9 +360,6 @@ public:
{
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
- case ALL_UNDECIDED_INDEXING_TYPES:
- case ALL_INT32_INDEXING_TYPES:
- case ALL_DOUBLE_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
return false;
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
@@ -443,9 +374,6 @@ public:
{
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
- case ALL_UNDECIDED_INDEXING_TYPES:
- case ALL_INT32_INDEXING_TYPES:
- case ALL_DOUBLE_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
return false;
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
@@ -643,30 +571,6 @@ public:
// foo->attemptToInterceptPutByIndexOnHole(...);
bool attemptToInterceptPutByIndexOnHoleForPrototype(ExecState*, JSValue thisValue, unsigned propertyName, JSValue, bool shouldThrow);
- // Returns 0 if int32 storage cannot be created - either because
- // indexing should be sparse, we're having a bad time, or because
- // we already have a more general form of storage (double,
- // contiguous, array storage).
- WriteBarrier<Unknown>* ensureInt32(JSGlobalData& globalData)
- {
- if (LIKELY(hasInt32(structure()->indexingType())))
- return m_butterfly->contiguousInt32();
-
- return ensureInt32Slow(globalData);
- }
-
- // Returns 0 if double storage cannot be created - either because
- // indexing should be sparse, we're having a bad time, or because
- // we already have a more general form of storage (contiguous,
- // or array storage).
- double* ensureDouble(JSGlobalData& globalData)
- {
- if (LIKELY(hasDouble(structure()->indexingType())))
- return m_butterfly->contiguousDouble();
-
- return ensureDoubleSlow(globalData);
- }
-
// Returns 0 if contiguous storage cannot be created - either because
// indexing should be sparse or because we're having a bad time.
WriteBarrier<Unknown>* ensureContiguous(JSGlobalData& globalData)
@@ -689,6 +593,14 @@ public:
return ensureArrayStorageSlow(globalData);
}
+ Butterfly* ensureIndexedStorage(JSGlobalData& globalData)
+ {
+ if (LIKELY(hasIndexedProperties(structure()->indexingType())))
+ return m_butterfly;
+
+ return ensureIndexedStorageSlow(globalData);
+ }
+
static size_t offsetOfInlineStorage();
static ptrdiff_t butterflyOffset()
@@ -749,47 +661,19 @@ protected:
return 0;
}
}
-
- Butterfly* createInitialUndecided(JSGlobalData&, unsigned length);
- WriteBarrier<Unknown>* createInitialInt32(JSGlobalData&, unsigned length);
- double* createInitialDouble(JSGlobalData&, unsigned length);
- WriteBarrier<Unknown>* createInitialContiguous(JSGlobalData&, unsigned length);
-
- void convertUndecidedForValue(JSGlobalData&, JSValue);
- void convertInt32ForValue(JSGlobalData&, JSValue);
-
+
ArrayStorage* createArrayStorage(JSGlobalData&, unsigned length, unsigned vectorLength);
ArrayStorage* createInitialArrayStorage(JSGlobalData&);
-
- WriteBarrier<Unknown>* convertUndecidedToInt32(JSGlobalData&);
- double* convertUndecidedToDouble(JSGlobalData&);
- WriteBarrier<Unknown>* convertUndecidedToContiguous(JSGlobalData&);
- ArrayStorage* convertUndecidedToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength);
- ArrayStorage* convertUndecidedToArrayStorage(JSGlobalData&, NonPropertyTransition);
- ArrayStorage* convertUndecidedToArrayStorage(JSGlobalData&);
-
- double* convertInt32ToDouble(JSGlobalData&);
- WriteBarrier<Unknown>* convertInt32ToContiguous(JSGlobalData&);
- ArrayStorage* convertInt32ToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength);
- ArrayStorage* convertInt32ToArrayStorage(JSGlobalData&, NonPropertyTransition);
- ArrayStorage* convertInt32ToArrayStorage(JSGlobalData&);
-
- WriteBarrier<Unknown>* convertDoubleToContiguous(JSGlobalData&);
- ArrayStorage* convertDoubleToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength);
- ArrayStorage* convertDoubleToArrayStorage(JSGlobalData&, NonPropertyTransition);
- ArrayStorage* convertDoubleToArrayStorage(JSGlobalData&);
-
+ WriteBarrier<Unknown>* createInitialContiguous(JSGlobalData&, unsigned length);
ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength);
ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&, NonPropertyTransition);
ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&);
-
ArrayStorage* ensureArrayStorageExistsAndEnterDictionaryIndexingMode(JSGlobalData&);
bool defineOwnNonIndexProperty(ExecState*, PropertyName, PropertyDescriptor&, bool throwException);
- template<IndexingType indexingShape>
- void putByIndexBeyondVectorLengthWithoutAttributes(ExecState*, unsigned propertyName, JSValue);
+ void putByIndexBeyondVectorLengthContiguousWithoutAttributes(ExecState*, unsigned propertyName, JSValue);
void putByIndexBeyondVectorLengthWithArrayStorage(ExecState*, unsigned propertyName, JSValue, bool shouldThrow, ArrayStorage*);
bool increaseVectorLength(JSGlobalData&, unsigned newLength);
@@ -803,33 +687,24 @@ protected:
// Call this if you want setIndexQuickly to succeed and you're sure that
// the array is contiguous.
- void ensureLength(JSGlobalData& globalData, unsigned length)
+ void ensureContiguousLength(JSGlobalData& globalData, unsigned length)
{
ASSERT(length < MAX_ARRAY_INDEX);
- ASSERT(hasContiguous(structure()->indexingType()) || hasInt32(structure()->indexingType()) || hasDouble(structure()->indexingType()) || hasUndecided(structure()->indexingType()));
+ ASSERT(hasContiguous(structure()->indexingType()));
if (m_butterfly->vectorLength() < length)
- ensureLengthSlow(globalData, length);
+ ensureContiguousLengthSlow(globalData, length);
if (m_butterfly->publicLength() < length)
m_butterfly->setPublicLength(length);
}
- template<IndexingType indexingShape>
- unsigned countElements(Butterfly*);
+ unsigned countElementsInContiguous(Butterfly*);
- // This is relevant to undecided, int32, double, and contiguous.
- unsigned countElements();
-
- // This strange method returns a pointer to the start of the indexed data
- // as if it contained JSValues. But it won't always contain JSValues.
- // Make sure you cast this to the appropriate type before using.
template<IndexingType indexingType>
WriteBarrier<Unknown>* indexingData()
{
switch (indexingType) {
- case ALL_INT32_INDEXING_TYPES:
- case ALL_DOUBLE_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
return m_butterfly->contiguous();
@@ -845,7 +720,6 @@ protected:
WriteBarrier<Unknown>* currentIndexingData()
{
switch (structure()->indexingType()) {
- case ALL_INT32_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
return m_butterfly->contiguous();
@@ -858,32 +732,10 @@ protected:
}
}
- JSValue getHolyIndexQuickly(unsigned i)
- {
- switch (structure()->indexingType()) {
- case ALL_INT32_INDEXING_TYPES:
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- return m_butterfly->contiguous()[i].get();
- case ALL_DOUBLE_INDEXING_TYPES: {
- double value = m_butterfly->contiguousDouble()[i];
- if (value == value)
- return JSValue(JSValue::EncodeAsDouble, value);
- return JSValue();
- }
- case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return m_butterfly->arrayStorage()->m_vector[i].get();
- default:
- CRASH();
- return JSValue();
- }
- }
-
template<IndexingType indexingType>
unsigned relevantLength()
{
switch (indexingType) {
- case ALL_INT32_INDEXING_TYPES:
- case ALL_DOUBLE_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
return m_butterfly->publicLength();
@@ -901,8 +753,6 @@ protected:
unsigned currentRelevantLength()
{
switch (structure()->indexingType()) {
- case ALL_INT32_INDEXING_TYPES:
- case ALL_DOUBLE_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
return m_butterfly->publicLength();
@@ -928,8 +778,6 @@ private:
void isObject();
void isString();
- Butterfly* createInitialIndexedStorage(JSGlobalData&, unsigned length, size_t elementSize);
-
ArrayStorage* enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(JSGlobalData&, ArrayStorage*);
template<PutMode>
@@ -952,18 +800,11 @@ private:
JS_EXPORT_PRIVATE bool getOwnPropertySlotSlow(ExecState*, PropertyName, PropertySlot&);
- ArrayStorage* constructConvertedArrayStorageWithoutCopyingElements(JSGlobalData&, unsigned neededLength);
-
- JS_EXPORT_PRIVATE void setIndexQuicklyToUndecided(JSGlobalData&, unsigned index, JSValue);
- JS_EXPORT_PRIVATE void convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(JSGlobalData&, unsigned index, JSValue);
- JS_EXPORT_PRIVATE void convertDoubleToContiguousWhilePerformingSetIndex(JSGlobalData&, unsigned index, JSValue);
-
- void ensureLengthSlow(JSGlobalData&, unsigned length);
+ void ensureContiguousLengthSlow(JSGlobalData&, unsigned length);
- WriteBarrier<Unknown>* ensureInt32Slow(JSGlobalData&);
- double* ensureDoubleSlow(JSGlobalData&);
WriteBarrier<Unknown>* ensureContiguousSlow(JSGlobalData&);
ArrayStorage* ensureArrayStorageSlow(JSGlobalData&);
+ Butterfly* ensureIndexedStorageSlow(JSGlobalData&);
protected:
Butterfly* m_butterfly;
diff --git a/Source/JavaScriptCore/runtime/JSValue.cpp b/Source/JavaScriptCore/runtime/JSValue.cpp
index 8f245f98d..e7f8cad17 100644
--- a/Source/JavaScriptCore/runtime/JSValue.cpp
+++ b/Source/JavaScriptCore/runtime/JSValue.cpp
@@ -215,8 +215,8 @@ char* JSValue::description() const
#endif
} else if (isCell()) {
snprintf(
- description, size, "Cell: %p -> %p (%p: %s, %s)",
- asCell(), isObject() ? asObject(*this)->butterfly() : 0, asCell()->structure(), asCell()->structure()->classInfo()->className,
+ description, size, "Cell: %p (%p: %s, %s)",
+ asCell(), asCell()->structure(), asCell()->structure()->classInfo()->className,
indexingTypeToString(asCell()->structure()->indexingTypeIncludingHistory()));
} else if (isTrue())
snprintf(description, size, "True");
diff --git a/Source/JavaScriptCore/runtime/JSValueInlines.h b/Source/JavaScriptCore/runtime/JSValueInlineMethods.h
index c5a42f67f..224982e9e 100644
--- a/Source/JavaScriptCore/runtime/JSValueInlines.h
+++ b/Source/JavaScriptCore/runtime/JSValueInlineMethods.h
@@ -23,8 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef JSValueInlines_h
-#define JSValueInlines_h
+#ifndef JSValueInlineMethods_h
+#define JSValueInlineMethods_h
#include "JSValue.h"
@@ -493,5 +493,4 @@ namespace JSC {
} // namespace JSC
-#endif // JSValueInlines_h
-
+#endif // JSValueInlineMethods_h
diff --git a/Source/JavaScriptCore/runtime/LiteralParser.cpp b/Source/JavaScriptCore/runtime/LiteralParser.cpp
index bf27327bf..cd854417b 100644
--- a/Source/JavaScriptCore/runtime/LiteralParser.cpp
+++ b/Source/JavaScriptCore/runtime/LiteralParser.cpp
@@ -27,8 +27,8 @@
#include "config.h"
#include "LiteralParser.h"
-#include "ButterflyInlines.h"
-#include "CopiedSpaceInlines.h"
+#include "ButterflyInlineMethods.h"
+#include "CopiedSpaceInlineMethods.h"
#include "JSArray.h"
#include "JSString.h"
#include "Lexer.h"
@@ -548,7 +548,7 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState)
switch(state) {
startParseArray:
case StartParseArray: {
- JSArray* array = constructEmptyArray(m_exec, 0);
+ JSArray* array = constructEmptyArray(m_exec);
objectStack.append(array);
// fallthrough
}
diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
index 7e74a914b..7df047d28 100644
--- a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -21,8 +21,8 @@
#include "config.h"
#include "ObjectConstructor.h"
-#include "ButterflyInlines.h"
-#include "CopiedSpaceInlines.h"
+#include "ButterflyInlineMethods.h"
+#include "CopiedSpaceInlineMethods.h"
#include "Error.h"
#include "ExceptionHelpers.h"
#include "JSFunction.h"
@@ -182,7 +182,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState* exe
return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested property names of a value that is not an object.")));
PropertyNameArray properties(exec);
asObject(exec->argument(0))->methodTable()->getOwnPropertyNames(asObject(exec->argument(0)), exec, properties, IncludeDontEnumProperties);
- JSArray* names = constructEmptyArray(exec, 0);
+ JSArray* names = constructEmptyArray(exec);
size_t numProperties = properties.size();
for (size_t i = 0; i < numProperties; i++)
names->push(exec, jsOwnedString(exec, properties[i].string()));
@@ -196,7 +196,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec)
return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested keys of a value that is not an object.")));
PropertyNameArray properties(exec);
asObject(exec->argument(0))->methodTable()->getOwnPropertyNames(asObject(exec->argument(0)), exec, properties, ExcludeDontEnumProperties);
- JSArray* keys = constructEmptyArray(exec, 0);
+ JSArray* keys = constructEmptyArray(exec);
size_t numProperties = properties.size();
for (size_t i = 0; i < numProperties; i++)
keys->push(exec, jsOwnedString(exec, properties[i].string()));
diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h
index ed14e895f..01df7e98c 100644
--- a/Source/JavaScriptCore/runtime/Operations.h
+++ b/Source/JavaScriptCore/runtime/Operations.h
@@ -26,7 +26,7 @@
#include "Interpreter.h"
#include "JSProxy.h"
#include "JSString.h"
-#include "JSValueInlines.h"
+#include "JSValueInlineMethods.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
index 19f3b81ad..ce9c2d2db 100644
--- a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "RegExpMatchesArray.h"
-#include "ButterflyInlines.h"
+#include "ButterflyInlineMethods.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/RegExpObject.cpp b/Source/JavaScriptCore/runtime/RegExpObject.cpp
index 00dd1ed74..35de40912 100644
--- a/Source/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpObject.cpp
@@ -21,8 +21,8 @@
#include "config.h"
#include "RegExpObject.h"
-#include "ButterflyInlines.h"
-#include "CopiedSpaceInlines.h"
+#include "ButterflyInlineMethods.h"
+#include "CopiedSpaceInlineMethods.h"
#include "Error.h"
#include "ExceptionHelpers.h"
#include "JSArray.h"
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp
index 93009d806..5aafe8bb3 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp
@@ -22,9 +22,9 @@
#include "config.h"
#include "StringPrototype.h"
-#include "ButterflyInlines.h"
+#include "ButterflyInlineMethods.h"
#include "CachedCall.h"
-#include "CopiedSpaceInlines.h"
+#include "CopiedSpaceInlineMethods.h"
#include "Error.h"
#include "Executable.h"
#include "JSGlobalObjectFunctions.h"
@@ -870,7 +870,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
return JSValue::encode(jsNull());
}
- return JSValue::encode(constructArray(exec, static_cast<ArrayAllocationProfile*>(0), list));
+ return JSValue::encode(constructArray(exec, list));
}
EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec)
@@ -973,7 +973,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
// 3. Let A be a new array created as if by the expression new Array()
// where Array is the standard built-in constructor with that name.
- JSArray* result = constructEmptyArray(exec, 0);
+ JSArray* result = constructEmptyArray(exec);
// 4. Let lengthA be 0.
unsigned resultLength = 0;
@@ -1388,10 +1388,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec)
return throwVMTypeError(exec);
String s = thisValue.toString(exec)->value(exec);
JSValue a0 = exec->argument(0);
- String color = a0.toWTFString(exec);
- color.replaceWithLiteral('"', "&quot;");
-
- return JSValue::encode(jsMakeNontrivialString(exec, "<font color=\"", color, "\">", s, "</font>"));
+ return JSValue::encode(jsMakeNontrivialString(exec, "<font color=\"", a0.toString(exec)->value(exec), "\">", s, "</font>"));
}
EncodedJSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec)
@@ -1436,10 +1433,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec)
return JSValue::encode(jsNontrivialString(exec, impl));
}
- String fontSize = a0.toWTFString(exec);
- fontSize.replaceWithLiteral('"', "&quot;");
-
- return JSValue::encode(jsMakeNontrivialString(exec, "<font size=\"", fontSize, "\">", s, "</font>"));
+ return JSValue::encode(jsMakeNontrivialString(exec, "<font size=\"", a0.toString(exec)->value(exec), "\">", s, "</font>"));
}
EncodedJSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec)
@@ -1449,10 +1443,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec)
return throwVMTypeError(exec);
String s = thisValue.toString(exec)->value(exec);
JSValue a0 = exec->argument(0);
- String anchor = a0.toWTFString(exec);
- anchor.replaceWithLiteral('"', "&quot;");
-
- return JSValue::encode(jsMakeNontrivialString(exec, "<a name=\"", anchor, "\">", s, "</a>"));
+ return JSValue::encode(jsMakeNontrivialString(exec, "<a name=\"", a0.toString(exec)->value(exec), "\">", s, "</a>"));
}
EncodedJSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec)
@@ -1462,8 +1453,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec)
return throwVMTypeError(exec);
String s = thisValue.toString(exec)->value(exec);
JSValue a0 = exec->argument(0);
- String linkText = a0.toWTFString(exec);
- linkText.replaceWithLiteral('"', "&quot;");
+ String linkText = a0.toString(exec)->value(exec);
unsigned linkTextSize = linkText.length();
unsigned stringSize = s.length();
diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp
index e930c022a..e733c7e23 100644
--- a/Source/JavaScriptCore/runtime/Structure.cpp
+++ b/Source/JavaScriptCore/runtime/Structure.cpp
@@ -543,13 +543,12 @@ Structure* Structure::nonPropertyTransition(JSGlobalData& globalData, Structure*
unsigned attributes = toAttributes(transitionKind);
IndexingType indexingType = newIndexingType(structure->indexingTypeIncludingHistory(), transitionKind);
- if (JSGlobalObject* globalObject = structure->m_globalObject.get()) {
- if (globalObject->isOriginalArrayStructure(structure)) {
- Structure* result = globalObject->originalArrayStructureForIndexingType(indexingType);
- if (result->indexingTypeIncludingHistory() == indexingType) {
- structure->notifyTransitionFromThisStructure();
- return result;
- }
+ JSGlobalObject* globalObject = structure->globalObject();
+ if (structure == globalObject->arrayStructure()) {
+ Structure* transition = globalObject->arrayStructureWithArrayStorage();
+ if (transition->indexingTypeIncludingHistory() == indexingType) {
+ structure->notifyTransitionFromThisStructure();
+ return transition;
}
}
diff --git a/Source/JavaScriptCore/runtime/StructureTransitionTable.h b/Source/JavaScriptCore/runtime/StructureTransitionTable.h
index 5291ed540..3ab7b2014 100644
--- a/Source/JavaScriptCore/runtime/StructureTransitionTable.h
+++ b/Source/JavaScriptCore/runtime/StructureTransitionTable.h
@@ -43,9 +43,6 @@ static const unsigned FirstInternalAttribute = 1 << 6; // Use for transitions th
// Support for attributes used to indicate transitions not related to properties.
// If any of these are used, the string portion of the key should be 0.
enum NonPropertyTransition {
- AllocateUndecided,
- AllocateInt32,
- AllocateDouble,
AllocateContiguous,
AllocateArrayStorage,
AllocateSlowPutArrayStorage,
@@ -61,23 +58,14 @@ inline unsigned toAttributes(NonPropertyTransition transition)
inline IndexingType newIndexingType(IndexingType oldType, NonPropertyTransition transition)
{
switch (transition) {
- case AllocateUndecided:
- ASSERT(!hasIndexedProperties(oldType));
- return oldType | UndecidedShape;
- case AllocateInt32:
- ASSERT(!hasIndexedProperties(oldType) || hasUndecided(oldType));
- return (oldType & ~IndexingShapeMask) | Int32Shape;
- case AllocateDouble:
- ASSERT(!hasIndexedProperties(oldType) || hasUndecided(oldType) || hasInt32(oldType));
- return (oldType & ~IndexingShapeMask) | DoubleShape;
case AllocateContiguous:
- ASSERT(!hasIndexedProperties(oldType) || hasUndecided(oldType) || hasInt32(oldType) || hasDouble(oldType));
- return (oldType & ~IndexingShapeMask) | ContiguousShape;
+ ASSERT(!hasIndexedProperties(oldType));
+ return oldType | ContiguousShape;
case AllocateArrayStorage:
- ASSERT(!hasIndexedProperties(oldType) || hasUndecided(oldType) || hasInt32(oldType) || hasDouble(oldType) || hasContiguous(oldType));
+ ASSERT(!hasIndexedProperties(oldType) || hasContiguous(oldType));
return (oldType & ~IndexingShapeMask) | ArrayStorageShape;
case AllocateSlowPutArrayStorage:
- ASSERT(!hasIndexedProperties(oldType) || hasUndecided(oldType) || hasInt32(oldType) || hasDouble(oldType) || hasContiguous(oldType) || hasContiguous(oldType));
+ ASSERT(!hasIndexedProperties(oldType) || hasContiguous(oldType));
return (oldType & ~IndexingShapeMask) | SlowPutArrayStorageShape;
case SwitchToSlowPutArrayStorage:
ASSERT(hasFastArrayStorage(oldType));