summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/runtime
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-05-11 18:35:50 +0100
committerBen Murdoch <benm@google.com>2010-05-14 10:23:05 +0100
commit21939df44de1705786c545cd1bf519d47250322d (patch)
treeef56c310f5c0cdc379c2abb2e212308a3281ce20 /JavaScriptCore/runtime
parent4ff1d8891d520763f17675827154340c7c740f90 (diff)
downloadexternal_webkit-21939df44de1705786c545cd1bf519d47250322d.zip
external_webkit-21939df44de1705786c545cd1bf519d47250322d.tar.gz
external_webkit-21939df44de1705786c545cd1bf519d47250322d.tar.bz2
Merge Webkit at r58956: Initial merge by Git.
Change-Id: I1d9fb60ea2c3f2ddc04c17a871acdb39353be228
Diffstat (limited to 'JavaScriptCore/runtime')
-rw-r--r--JavaScriptCore/runtime/ArrayPrototype.cpp19
-rw-r--r--JavaScriptCore/runtime/CachedTranscendentalFunction.h103
-rw-r--r--JavaScriptCore/runtime/Collector.cpp26
-rw-r--r--JavaScriptCore/runtime/Executable.h7
-rw-r--r--JavaScriptCore/runtime/JSActivation.h1
-rw-r--r--JavaScriptCore/runtime/JSFunction.cpp19
-rw-r--r--JavaScriptCore/runtime/JSFunction.h2
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.cpp19
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.h26
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.cpp4
-rw-r--r--JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp3
-rw-r--r--JavaScriptCore/runtime/JSImmediate.h4
-rw-r--r--JavaScriptCore/runtime/JSLock.cpp8
-rw-r--r--JavaScriptCore/runtime/JSString.h2
-rw-r--r--JavaScriptCore/runtime/JSValue.h14
-rw-r--r--JavaScriptCore/runtime/Lookup.cpp14
-rw-r--r--JavaScriptCore/runtime/Lookup.h19
-rw-r--r--JavaScriptCore/runtime/MathObject.cpp2
-rw-r--r--JavaScriptCore/runtime/SmallStrings.h4
-rw-r--r--JavaScriptCore/runtime/StringConstructor.cpp5
-rw-r--r--JavaScriptCore/runtime/Structure.cpp4
-rw-r--r--JavaScriptCore/runtime/UString.cpp9
-rw-r--r--JavaScriptCore/runtime/WeakGCPtr.h11
23 files changed, 268 insertions, 57 deletions
diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp
index bd14e64..4c4eb48 100644
--- a/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -268,7 +268,24 @@ JSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue thi
separator = args.at(0).toString(exec);
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
- for (unsigned k = 0; k < length; k++) {
+ unsigned k = 0;
+ if (isJSArray(&exec->globalData(), thisObj)) {
+ JSArray* array = asArray(thisObj);
+ for (; k < length; k++) {
+ if (!array->canGetIndex(k))
+ break;
+ if (k >= 1) {
+ if (separator.isNull())
+ strBuffer.append(',');
+ else
+ strBuffer.append(separator);
+ }
+ JSValue element = array->getIndex(k);
+ if (!element.isUndefinedOrNull())
+ strBuffer.append(element.toString(exec));
+ }
+ }
+ for (; k < length; k++) {
if (k >= 1) {
if (separator.isNull())
strBuffer.append(',');
diff --git a/JavaScriptCore/runtime/CachedTranscendentalFunction.h b/JavaScriptCore/runtime/CachedTranscendentalFunction.h
new file mode 100644
index 0000000..04f7f62
--- /dev/null
+++ b/JavaScriptCore/runtime/CachedTranscendentalFunction.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CachedTranscendentalFunction_h
+#define CachedTranscendentalFunction_h
+
+#include "JSValue.h"
+
+namespace JSC {
+
+extern const double NaN;
+
+typedef double (*TranscendentalFunctionPtr)(double);
+
+// CachedTranscendentalFunction provides a generic mechanism to cache results
+// for pure functions with the signature "double func(double)", and where NaN
+// maps to NaN.
+template<TranscendentalFunctionPtr orignalFunction>
+class CachedTranscendentalFunction {
+ struct CacheEntry {
+ double operand;
+ double result;
+ };
+
+public:
+ CachedTranscendentalFunction()
+ : m_cache(0)
+ {
+ }
+
+ ~CachedTranscendentalFunction()
+ {
+ if (m_cache)
+ fastFree(m_cache);
+ }
+
+ JSValue operator() (ExecState* exec, double operand)
+ {
+ if (UNLIKELY(!m_cache))
+ initialize();
+ CacheEntry* entry = &m_cache[hash(operand)];
+
+ if (entry->operand == operand)
+ return jsDoubleNumber(exec, entry->result);
+ double result = orignalFunction(operand);
+ entry->operand = operand;
+ entry->result = result;
+ return jsDoubleNumber(exec, result);
+ }
+
+private:
+ void initialize()
+ {
+ // Lazily allocate the table, populate with NaN->NaN mapping.
+ m_cache = static_cast<CacheEntry*>(fastMalloc(s_cacheSize * sizeof(CacheEntry)));
+ for (unsigned x = 0; x < s_cacheSize; ++x) {
+ m_cache[x].operand = NaN;
+ m_cache[x].result = NaN;
+ }
+ }
+
+ static unsigned hash(double d)
+ {
+ union doubleAndUInt64 {
+ double d;
+ uint32_t is[2];
+ } u;
+ u.d = d;
+
+ unsigned x = u.is[0] ^ u.is[1];
+ x = (x >> 20) ^ (x >> 8);
+ return x & (s_cacheSize - 1);
+ }
+
+ static const unsigned s_cacheSize = 0x1000;
+ CacheEntry* m_cache;
+};
+
+}
+
+#endif // CachedTranscendentalFunction_h
diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp
index 9b72755..05f2bb5 100644
--- a/JavaScriptCore/runtime/Collector.cpp
+++ b/JavaScriptCore/runtime/Collector.cpp
@@ -449,7 +449,7 @@ void Heap::shrinkBlocks(size_t neededBlocks)
}
#if OS(WINCE)
-void* g_stackBase = 0;
+JS_EXPORTDATA void* g_stackBase = 0;
inline bool isPageWritable(void* page)
{
@@ -558,6 +558,8 @@ static inline void* currentThreadStackBase()
PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb());
return reinterpret_cast<void*>(pTib->StackBase);
#elif OS(QNX)
+ AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
+ MutexLocker locker(mutex);
return currentThreadStackBaseQNX();
#elif OS(SOLARIS)
stack_t s;
@@ -569,19 +571,17 @@ static inline void* currentThreadStackBase()
pthread_stackseg_np(thread, &stack);
return stack.ss_sp;
#elif OS(SYMBIAN)
- static void* stackBase = 0;
- if (stackBase == 0) {
- TThreadStackInfo info;
- RThread thread;
- thread.StackInfo(info);
- stackBase = (void*)info.iBase;
- }
- return (void*)stackBase;
+ TThreadStackInfo info;
+ RThread thread;
+ thread.StackInfo(info);
+ return (void*)info.iBase;
#elif OS(HAIKU)
thread_info threadInfo;
get_thread_info(find_thread(NULL), &threadInfo);
return threadInfo.stack_end;
#elif OS(UNIX)
+ AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
+ MutexLocker locker(mutex);
static void* stackBase = 0;
static size_t stackSize = 0;
static pthread_t stackThread;
@@ -604,6 +604,8 @@ static inline void* currentThreadStackBase()
}
return static_cast<char*>(stackBase) + stackSize;
#elif OS(WINCE)
+ AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
+ MutexLocker locker(mutex);
if (g_stackBase)
return g_stackBase;
else {
@@ -972,7 +974,7 @@ void Heap::markStackObjectsConservatively(MarkStack& markStack)
void Heap::protect(JSValue k)
{
ASSERT(k);
- ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
+ ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance());
if (!k.isCell())
return;
@@ -983,7 +985,7 @@ void Heap::protect(JSValue k)
bool Heap::unprotect(JSValue k)
{
ASSERT(k);
- ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
+ ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance());
if (!k.isCell())
return false;
@@ -1064,7 +1066,7 @@ void Heap::sweep()
void Heap::markRoots()
{
#ifndef NDEBUG
- if (m_globalData->isSharedInstance) {
+ if (m_globalData->isSharedInstance()) {
ASSERT(JSLock::lockCount() > 0);
ASSERT(JSLock::currentThreadIsHoldingLock());
}
diff --git a/JavaScriptCore/runtime/Executable.h b/JavaScriptCore/runtime/Executable.h
index f74abe9..ac691e4 100644
--- a/JavaScriptCore/runtime/Executable.h
+++ b/JavaScriptCore/runtime/Executable.h
@@ -85,7 +85,12 @@ namespace JSC {
NativeExecutable(ExecState* exec)
: ExecutableBase(NUM_PARAMETERS_IS_HOST)
{
- m_jitCode = JITCode(JITCode::HostFunction(exec->globalData().jitStubs.ctiNativeCallThunk()));
+ m_jitCode = exec->globalData().jitStubs.ctiNativeCallThunk()->m_jitCode;
+ }
+ NativeExecutable(JITCode thunk)
+ : ExecutableBase(NUM_PARAMETERS_IS_HOST)
+ {
+ m_jitCode = thunk;
}
~NativeExecutable();
diff --git a/JavaScriptCore/runtime/JSActivation.h b/JavaScriptCore/runtime/JSActivation.h
index 91c960c..ece8753 100644
--- a/JavaScriptCore/runtime/JSActivation.h
+++ b/JavaScriptCore/runtime/JSActivation.h
@@ -31,7 +31,6 @@
#include "CodeBlock.h"
#include "JSVariableObject.h"
-#include "RegisterFile.h"
#include "SymbolTable.h"
#include "Nodes.h"
diff --git a/JavaScriptCore/runtime/JSFunction.cpp b/JavaScriptCore/runtime/JSFunction.cpp
index cba6795..5b73642 100644
--- a/JavaScriptCore/runtime/JSFunction.cpp
+++ b/JavaScriptCore/runtime/JSFunction.cpp
@@ -56,10 +56,27 @@ JSFunction::JSFunction(NonNullPassRefPtr<Structure> structure)
{
}
+JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeExecutable* thunk, NativeFunction func)
+ : Base(&exec->globalData(), structure, name)
+#if ENABLE(JIT)
+ , m_executable(thunk)
+#endif
+{
+#if ENABLE(JIT)
+ setNativeFunction(func);
+ putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum);
+#else
+ UNUSED_PARAM(thunk);
+ UNUSED_PARAM(length);
+ UNUSED_PARAM(func);
+ ASSERT_NOT_REACHED();
+#endif
+}
+
JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func)
: Base(&exec->globalData(), structure, name)
#if ENABLE(JIT)
- , m_executable(adoptRef(new NativeExecutable(exec)))
+ , m_executable(exec->globalData().jitStubs.ctiNativeCallThunk())
#endif
{
#if ENABLE(JIT)
diff --git a/JavaScriptCore/runtime/JSFunction.h b/JavaScriptCore/runtime/JSFunction.h
index afa24a8..301b908 100644
--- a/JavaScriptCore/runtime/JSFunction.h
+++ b/JavaScriptCore/runtime/JSFunction.h
@@ -33,6 +33,7 @@ namespace JSC {
class FunctionPrototype;
class JSActivation;
class JSGlobalObject;
+ class NativeExecutable;
class JSFunction : public InternalFunction {
friend class JIT;
@@ -42,6 +43,7 @@ namespace JSC {
public:
JSFunction(ExecState*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
+ JSFunction(ExecState*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeExecutable*, NativeFunction);
JSFunction(ExecState*, NonNullPassRefPtr<FunctionExecutable>, ScopeChainNode*);
virtual ~JSFunction();
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
index 2948d1c..12fa2be 100644
--- a/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -103,8 +103,8 @@ void JSGlobalData::storeVPtrs()
jsFunction->~JSCell();
}
-JSGlobalData::JSGlobalData(bool isShared, ThreadStackType threadStackType)
- : isSharedInstance(isShared)
+JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType threadStackType)
+ : globalDataType(globalDataType)
, clientData(0)
, arrayTable(fastNew<HashTable>(JSC::arrayTable))
, dateTable(fastNew<HashTable>(JSC::dateTable))
@@ -128,7 +128,7 @@ JSGlobalData::JSGlobalData(bool isShared, ThreadStackType threadStackType)
#if USE(JSVALUE32)
, numberStructure(JSNumberCell::createStructure(jsNull()))
#endif
- , identifierTable(createIdentifierTable())
+ , identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable())
, propertyNames(new CommonIdentifiers(this))
, emptyList(new MarkedArgumentBuffer)
, lexer(new Lexer(this))
@@ -192,21 +192,20 @@ JSGlobalData::~JSGlobalData()
delete emptyList;
delete propertyNames;
- deleteIdentifierTable(identifierTable);
+ if (globalDataType != Default)
+ deleteIdentifierTable(identifierTable);
delete clientData;
}
-PassRefPtr<JSGlobalData> JSGlobalData::createNonDefault(ThreadStackType type)
+PassRefPtr<JSGlobalData> JSGlobalData::createContextGroup(ThreadStackType type)
{
- return adoptRef(new JSGlobalData(false, type));
+ return adoptRef(new JSGlobalData(APIContextGroup, type));
}
PassRefPtr<JSGlobalData> JSGlobalData::create(ThreadStackType type)
{
- JSGlobalData* globalData = new JSGlobalData(false, type);
- wtfThreadData().initializeIdentifierTable(globalData->identifierTable);
- return adoptRef(globalData);
+ return adoptRef(new JSGlobalData(Default, type));
}
PassRefPtr<JSGlobalData> JSGlobalData::createLeaked(ThreadStackType type)
@@ -226,7 +225,7 @@ JSGlobalData& JSGlobalData::sharedInstance()
{
JSGlobalData*& instance = sharedInstanceInternal();
if (!instance) {
- instance = new JSGlobalData(true, ThreadStackTypeSmall);
+ instance = new JSGlobalData(APIShared, ThreadStackTypeSmall);
#if ENABLE(JSC_MULTIPLE_THREADS)
instance->makeUsableFromMultipleThreads();
#endif
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index a90bf2c..711e148 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -29,6 +29,7 @@
#ifndef JSGlobalData_h
#define JSGlobalData_h
+#include "CachedTranscendentalFunction.h"
#include "Collector.h"
#include "DateInstanceCache.h"
#include "ExecutableAllocator.h"
@@ -91,16 +92,27 @@ namespace JSC {
class JSGlobalData : public RefCounted<JSGlobalData> {
public:
+ // WebCore has a one-to-one mapping of threads to JSGlobalDatas;
+ // either create() or createLeaked() should only be called once
+ // on a thread, this is the 'default' JSGlobalData (it uses the
+ // thread's default string uniquing table from wtfThreadData).
+ // API contexts created using the new context group aware interface
+ // create APIContextGroup objects which require less locking of JSC
+ // than the old singleton APIShared JSGlobalData created for use by
+ // the original API.
+ enum GlobalDataType { Default, APIContextGroup, APIShared };
+
struct ClientData {
virtual ~ClientData() = 0;
};
+ bool isSharedInstance() { return globalDataType == APIShared; }
static bool sharedInstanceExists();
static JSGlobalData& sharedInstance();
static PassRefPtr<JSGlobalData> create(ThreadStackType);
static PassRefPtr<JSGlobalData> createLeaked(ThreadStackType);
- static PassRefPtr<JSGlobalData> createNonDefault(ThreadStackType);
+ static PassRefPtr<JSGlobalData> createContextGroup(ThreadStackType);
~JSGlobalData();
#if ENABLE(JSC_MULTIPLE_THREADS)
@@ -108,7 +120,7 @@ namespace JSC {
void makeUsableFromMultipleThreads() { heap.makeUsableFromMultipleThreads(); }
#endif
- bool isSharedInstance;
+ GlobalDataType globalDataType;
ClientData* clientData;
const HashTable* arrayTable;
@@ -158,6 +170,10 @@ namespace JSC {
Interpreter* interpreter;
#if ENABLE(JIT)
JITThunks jitStubs;
+ NativeExecutable* getThunk(ThunkGenerator generator)
+ {
+ return jitStubs.specializedThunk(this, generator);
+ }
#endif
TimeoutChecker timeoutChecker;
Terminator terminator;
@@ -197,17 +213,19 @@ namespace JSC {
ThreadIdentifier exclusiveThread;
#endif
+ CachedTranscendentalFunction<sin> cachedSin;
+
void resetDateCache();
void startSampling();
void stopSampling();
void dumpSampleData(ExecState* exec);
private:
- JSGlobalData(bool isShared, ThreadStackType);
+ JSGlobalData(GlobalDataType, ThreadStackType);
static JSGlobalData*& sharedInstanceInternal();
void createNativeThunk();
};
-
+
} // namespace JSC
#endif // JSGlobalData_h
diff --git a/JavaScriptCore/runtime/JSGlobalObject.cpp b/JavaScriptCore/runtime/JSGlobalObject.cpp
index 86690bd..7568ffd 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -117,10 +117,8 @@ JSGlobalObject::~JSGlobalObject()
(*it)->clearGlobalObject();
RegisterFile& registerFile = globalData()->interpreter->registerFile();
- if (registerFile.globalObject() == this) {
- registerFile.setGlobalObject(0);
+ if (registerFile.clearGlobalObject(this))
registerFile.setNumGlobals(0);
- }
d()->destructor(d());
}
diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index 5b6369a..5da5194 100644
--- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -241,6 +241,7 @@ static double parseInt(const UString& s, int radix)
}
if (number >= mantissaOverflowLowerBound) {
+ // FIXME: It is incorrect to use UString::ascii() here because it's not thread-safe.
if (radix == 10)
number = WTF::strtod(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), 0);
else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
@@ -269,6 +270,8 @@ static double parseFloat(const UString& s)
if (length - p >= 2 && data[p] == '0' && (data[p + 1] == 'x' || data[p + 1] == 'X'))
return 0;
+ // FIXME: UString::toDouble will ignore leading ASCII spaces, but we need to ignore
+ // other StrWhiteSpaceChar values as well.
return s.toDouble(true /*tolerant*/, false /* NaN for empty string */);
}
diff --git a/JavaScriptCore/runtime/JSImmediate.h b/JavaScriptCore/runtime/JSImmediate.h
index 0f54f60..9127b6a 100644
--- a/JavaScriptCore/runtime/JSImmediate.h
+++ b/JavaScriptCore/runtime/JSImmediate.h
@@ -136,6 +136,8 @@ namespace JSC {
friend class JIT;
friend class JSValue;
friend class JSFastMath;
+ friend class JSInterfaceJIT;
+ friend class SpecializedThunkJIT;
friend JSValue jsNumber(ExecState* exec, double d);
friend JSValue jsNumber(ExecState*, char i);
friend JSValue jsNumber(ExecState*, unsigned char i);
@@ -164,7 +166,7 @@ namespace JSC {
// This value is 2^48, used to encode doubles such that the encoded value will begin
// with a 16-bit pattern within the range 0x0001..0xFFFE.
static const intptr_t DoubleEncodeOffset = 0x1000000000000ll;
-#else
+#elif USE(JSVALUE32)
static const intptr_t TagTypeNumber = 0x1; // bottom bit set indicates integer, this dominates the following bit
#endif
static const intptr_t TagBitTypeOther = 0x2; // second bit set indicates immediate other than an integer
diff --git a/JavaScriptCore/runtime/JSLock.cpp b/JavaScriptCore/runtime/JSLock.cpp
index 8f056c8..a1cffbd 100644
--- a/JavaScriptCore/runtime/JSLock.cpp
+++ b/JavaScriptCore/runtime/JSLock.cpp
@@ -60,7 +60,7 @@ static void setLockCount(intptr_t count)
}
JSLock::JSLock(ExecState* exec)
- : m_lockBehavior(exec->globalData().isSharedInstance ? LockForReal : SilenceAssertionsOnly)
+ : m_lockBehavior(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly)
{
lock(m_lockBehavior);
}
@@ -105,12 +105,12 @@ void JSLock::unlock(JSLockBehavior lockBehavior)
void JSLock::lock(ExecState* exec)
{
- lock(exec->globalData().isSharedInstance ? LockForReal : SilenceAssertionsOnly);
+ lock(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly);
}
void JSLock::unlock(ExecState* exec)
{
- unlock(exec->globalData().isSharedInstance ? LockForReal : SilenceAssertionsOnly);
+ unlock(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly);
}
bool JSLock::currentThreadIsHoldingLock()
@@ -162,7 +162,7 @@ bool JSLock::currentThreadIsHoldingLock()
static unsigned lockDropDepth = 0;
JSLock::DropAllLocks::DropAllLocks(ExecState* exec)
- : m_lockBehavior(exec->globalData().isSharedInstance ? LockForReal : SilenceAssertionsOnly)
+ : m_lockBehavior(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly)
{
pthread_once(&createJSLockCountOnce, createJSLockCount);
diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h
index b1dccfa..85d3c8e 100644
--- a/JavaScriptCore/runtime/JSString.h
+++ b/JavaScriptCore/runtime/JSString.h
@@ -66,6 +66,8 @@ namespace JSC {
public:
friend class JIT;
friend class JSGlobalData;
+ friend class SpecializedThunkJIT;
+ friend struct ThunkHelpers;
class RopeBuilder {
public:
diff --git a/JavaScriptCore/runtime/JSValue.h b/JavaScriptCore/runtime/JSValue.h
index b37adc0..bcf82ee 100644
--- a/JavaScriptCore/runtime/JSValue.h
+++ b/JavaScriptCore/runtime/JSValue.h
@@ -66,6 +66,8 @@ namespace JSC {
friend class JIT;
friend class JITStubs;
friend class JITStubCall;
+ friend class JSInterfaceJIT;
+ friend class SpecializedThunkJIT;
public:
static EncodedJSValue encode(JSValue value);
@@ -214,6 +216,10 @@ namespace JSC {
JSObject* toObjectSlowCase(ExecState*) const;
JSObject* toThisObjectSlowCase(ExecState*) const;
+ JSObject* synthesizePrototype(ExecState*) const;
+ JSObject* synthesizeObject(ExecState*) const;
+
+#if USE(JSVALUE32_64)
enum { Int32Tag = 0xffffffff };
enum { CellTag = 0xfffffffe };
enum { TrueTag = 0xfffffffd };
@@ -222,16 +228,12 @@ namespace JSC {
enum { UndefinedTag = 0xfffffffa };
enum { EmptyValueTag = 0xfffffff9 };
enum { DeletedValueTag = 0xfffffff8 };
-
+
enum { LowestTag = DeletedValueTag };
-
+
uint32_t tag() const;
int32_t payload() const;
- JSObject* synthesizePrototype(ExecState*) const;
- JSObject* synthesizeObject(ExecState*) const;
-
-#if USE(JSVALUE32_64)
union {
EncodedJSValue asEncodedJSValue;
double asDouble;
diff --git a/JavaScriptCore/runtime/Lookup.cpp b/JavaScriptCore/runtime/Lookup.cpp
index 4e9e086..0042e4d 100644
--- a/JavaScriptCore/runtime/Lookup.cpp
+++ b/JavaScriptCore/runtime/Lookup.cpp
@@ -46,7 +46,11 @@ void HashTable::createTable(JSGlobalData* globalData) const
entry = entry->next();
}
- entry->initialize(identifier, values[i].attributes, values[i].value1, values[i].value2);
+ entry->initialize(identifier, values[i].attributes, values[i].value1, values[i].value2
+#if ENABLE(JIT)
+ , values[i].generator
+#endif
+ );
}
table = entries;
}
@@ -70,7 +74,13 @@ void setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject*
JSValue* location = thisObj->getDirectLocation(propertyName);
if (!location) {
- InternalFunction* function = new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), entry->functionLength(), propertyName, entry->function());
+ InternalFunction* function;
+#if ENABLE(JIT)
+ if (entry->generator())
+ function = new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), entry->functionLength(), propertyName, exec->globalData().getThunk(entry->generator()), entry->function());
+ else
+#endif
+ function = new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), entry->functionLength(), propertyName, entry->function());
thisObj->putDirectFunction(propertyName, function, entry->attributes());
location = thisObj->getDirectLocation(propertyName);
diff --git a/JavaScriptCore/runtime/Lookup.h b/JavaScriptCore/runtime/Lookup.h
index 995aeee..dd36400 100644
--- a/JavaScriptCore/runtime/Lookup.h
+++ b/JavaScriptCore/runtime/Lookup.h
@@ -37,13 +37,15 @@
#endif
namespace JSC {
-
// Hash table generated by the create_hash_table script.
struct HashTableValue {
const char* key; // property name
unsigned char attributes; // JSObject attributes
intptr_t value1;
intptr_t value2;
+#if ENABLE(JIT)
+ ThunkGenerator generator;
+#endif
};
// FIXME: There is no reason this get function can't be simpler.
@@ -53,12 +55,19 @@ namespace JSC {
class HashEntry : public FastAllocBase {
public:
- void initialize(UString::Rep* key, unsigned char attributes, intptr_t v1, intptr_t v2)
+ void initialize(UString::Rep* key, unsigned char attributes, intptr_t v1, intptr_t v2
+#if ENABLE(JIT)
+ , ThunkGenerator generator = 0
+#endif
+ )
{
m_key = key;
m_attributes = attributes;
m_u.store.value1 = v1;
m_u.store.value2 = v2;
+#if ENABLE(JIT)
+ m_u.function.generator = generator;
+#endif
m_next = 0;
}
@@ -67,6 +76,9 @@ namespace JSC {
unsigned char attributes() const { return m_attributes; }
+#if ENABLE(JIT)
+ ThunkGenerator generator() const { ASSERT(m_attributes & Function); return m_u.function.generator; }
+#endif
NativeFunction function() const { ASSERT(m_attributes & Function); return m_u.function.functionValue; }
unsigned char functionLength() const { ASSERT(m_attributes & Function); return static_cast<unsigned char>(m_u.function.length); }
@@ -90,6 +102,9 @@ namespace JSC {
struct {
NativeFunction functionValue;
intptr_t length; // number of arguments for function
+#if ENABLE(JIT)
+ ThunkGenerator generator;
+#endif
} function;
struct {
GetFunction get;
diff --git a/JavaScriptCore/runtime/MathObject.cpp b/JavaScriptCore/runtime/MathObject.cpp
index 16d32a0..1e28dfa 100644
--- a/JavaScriptCore/runtime/MathObject.cpp
+++ b/JavaScriptCore/runtime/MathObject.cpp
@@ -223,7 +223,7 @@ JSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec, JSObject*, JSValue, co
JSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsDoubleNumber(exec, sin(args.at(0).toNumber(exec)));
+ return exec->globalData().cachedSin(exec, args.at(0).toNumber(exec));
}
JSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValue, const ArgList& args)
diff --git a/JavaScriptCore/runtime/SmallStrings.h b/JavaScriptCore/runtime/SmallStrings.h
index cc11d0a..bc337c9 100644
--- a/JavaScriptCore/runtime/SmallStrings.h
+++ b/JavaScriptCore/runtime/SmallStrings.h
@@ -60,7 +60,9 @@ namespace JSC {
void clear();
unsigned count() const;
-
+#if ENABLE(JIT)
+ JSString** singleCharacterStrings() { return m_singleCharacterStrings; }
+#endif
private:
void createEmptyString(JSGlobalData*);
void createSingleCharacterString(JSGlobalData*, unsigned char);
diff --git a/JavaScriptCore/runtime/StringConstructor.cpp b/JavaScriptCore/runtime/StringConstructor.cpp
index c7b62bf..42f98c3 100644
--- a/JavaScriptCore/runtime/StringConstructor.cpp
+++ b/JavaScriptCore/runtime/StringConstructor.cpp
@@ -54,8 +54,11 @@ StringConstructor::StringConstructor(ExecState* exec, NonNullPassRefPtr<Structur
putDirectWithoutTransition(exec->propertyNames().prototype, stringPrototype, ReadOnly | DontEnum | DontDelete);
// ECMA 15.5.3.2 fromCharCode()
+#if ENABLE(JIT)
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().fromCharCode, exec->globalData().getThunk(fromCharCodeThunkGenerator), stringFromCharCode), DontEnum);
+#else
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().fromCharCode, stringFromCharCode), DontEnum);
-
+#endif
// no. of arguments for constructor
putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
}
diff --git a/JavaScriptCore/runtime/Structure.cpp b/JavaScriptCore/runtime/Structure.cpp
index 6f23c7d..6d13f4b 100644
--- a/JavaScriptCore/runtime/Structure.cpp
+++ b/JavaScriptCore/runtime/Structure.cpp
@@ -168,14 +168,14 @@ inline void Structure::transitionTableAdd(const StructureTransitionTableHash::Ke
if (!specificValue) {
TransitionTable::iterator find = transitionTable()->find(key);
if (find == transitionTable()->end())
- transitionTable()->add(key, Transition(structure, 0));
+ transitionTable()->add(key, Transition(structure, static_cast<Structure*>(0)));
else
find->second.first = structure;
} else {
// If we're adding a transition to a specific value, then there cannot be
// an existing transition
ASSERT(!transitionTable()->contains(key));
- transitionTable()->add(key, Transition(0, structure));
+ transitionTable()->add(key, Transition(static_cast<Structure*>(0), structure));
}
}
diff --git a/JavaScriptCore/runtime/UString.cpp b/JavaScriptCore/runtime/UString.cpp
index ce91040..6b16274 100644
--- a/JavaScriptCore/runtime/UString.cpp
+++ b/JavaScriptCore/runtime/UString.cpp
@@ -254,7 +254,15 @@ double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) co
return NaN;
}
+ // FIXME: If tolerateTrailingJunk is true, then we want to tolerate junk
+ // after the number, even if it contains invalid UTF-16 sequences. So we
+ // shouldn't use the UTF8String function, which returns null when it
+ // encounters invalid UTF-16. Further, we have no need to convert the
+ // non-ASCII characters to UTF-8, so the UTF8String does quite a bit of
+ // unnecessary work.
CString s = UTF8String();
+ if (s.isNull())
+ return NaN;
const char* c = s.data();
// skip leading white space
@@ -318,6 +326,7 @@ double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) co
while (isASCIISpace(*c))
c++;
// don't allow anything after - unless tolerant=true
+ // FIXME: If string contains a U+0000 character, then this check is incorrect.
if (!tolerateTrailingJunk && *c != '\0')
d = NaN;
diff --git a/JavaScriptCore/runtime/WeakGCPtr.h b/JavaScriptCore/runtime/WeakGCPtr.h
index 5f58374..9dce858 100644
--- a/JavaScriptCore/runtime/WeakGCPtr.h
+++ b/JavaScriptCore/runtime/WeakGCPtr.h
@@ -44,10 +44,13 @@ public:
return m_ptr;
}
- void clear(JSCell* ptr)
+ bool clear(JSCell* ptr)
{
- if (ptr == m_ptr)
+ if (ptr == m_ptr) {
m_ptr = 0;
+ return true;
+ }
+ return false;
}
T& operator*() const { return *get(); }
@@ -72,8 +75,8 @@ public:
private:
void assign(T* ptr)
{
- if (ptr)
- Heap::markCell(ptr);
+ ASSERT(ptr);
+ Heap::markCell(ptr);
m_ptr = ptr;
}