Import Cobalt 4.11837
diff --git a/src/third_party/mozjs/js/src/jit/Ion.cpp b/src/third_party/mozjs/js/src/jit/Ion.cpp
index 99f8854..c12df1b 100644
--- a/src/third_party/mozjs/js/src/jit/Ion.cpp
+++ b/src/third_party/mozjs/js/src/jit/Ion.cpp
@@ -69,7 +69,11 @@
#ifdef JS_THREADSAFE
static bool IonTLSInitialized = false;
+#if defined(STARBOARD)
+static PRTLSIndex IonTLSIndex;
+#else // defined(STARBOARD)
static unsigned IonTLSIndex;
+#endif // defined(STARBOARD)
static inline IonContext *
CurrentIonContext()
diff --git a/src/third_party/mozjs/js/src/jit/IonBuilder.cpp b/src/third_party/mozjs/js/src/jit/IonBuilder.cpp
index 00fd7a0..55b6818 100644
--- a/src/third_party/mozjs/js/src/jit/IonBuilder.cpp
+++ b/src/third_party/mozjs/js/src/jit/IonBuilder.cpp
@@ -25,7 +25,12 @@
#include "jstypedarrayinlines.h"
#ifdef JS_THREADSAFE
+#if defined(STARBOARD)
+#include "pr_starboard.h"
+#else
# include "prthread.h"
+#endif // defined(STARBOARD)
+
#endif
using namespace js;
diff --git a/src/third_party/mozjs/js/src/jsapi.cpp b/src/third_party/mozjs/js/src/jsapi.cpp
index 33b7991..85b9856 100644
--- a/src/third_party/mozjs/js/src/jsapi.cpp
+++ b/src/third_party/mozjs/js/src/jsapi.cpp
@@ -5134,7 +5134,7 @@
const int64_t kFileSize = info.size;
FileContents buffer(cx);
buffer.resize(kFileSize);
- if (SbFileRead(file, buffer.begin(), kFileSize) < 0) {
+ if (SbFileReadAll(file, buffer.begin(), kFileSize) < 0) {
return NULL;
}
JSScript *script = Compile(cx, obj, options, buffer.begin(),
@@ -5519,12 +5519,23 @@
JS::Evaluate(JSContext *cx, HandleObject obj, CompileOptions options,
const char *filename, jsval *rval)
{
+#if defined(STARBOARD)
+ starboard::ScopedFile file(filename, kSbFileOpenOnly | kSbFileRead, NULL,
+ NULL);
+ const int64_t kFileSize = file.GetSize();
+ FileContents buffer(cx);
+ buffer.resize(kFileSize);
+ if (file.ReadAll(buffer.begin(), kFileSize) < 0) {
+ return false;
+ }
+#else
FileContents buffer(cx);
{
AutoFile file;
if (!file.open(cx, filename) || !file.readAll(cx, buffer))
return false;
}
+#endif
options.setFileAndLine(filename, 1);
return Evaluate(cx, obj, options, buffer.begin(), buffer.length(), rval);
diff --git a/src/third_party/mozjs/js/src/jsgc.cpp b/src/third_party/mozjs/js/src/jsgc.cpp
index 5c2e730..78d3d57 100644
--- a/src/third_party/mozjs/js/src/jsgc.cpp
+++ b/src/third_party/mozjs/js/src/jsgc.cpp
@@ -81,6 +81,10 @@
# include <unistd.h>
#endif
+#if defined(STARBOARD)
+#include "starboard/system.h"
+#endif // defined(STARBOARD)
+
#if JS_TRACE_LOGGING
#include "TraceLogging.h"
#endif
@@ -2170,6 +2174,8 @@
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
ncpus = unsigned(sysinfo.dwNumberOfProcessors);
+#elif defined(STARBOARD)
+ ncpus = SbSystemGetNumberOfProcessors();
# else
long n = sysconf(_SC_NPROCESSORS_ONLN);
ncpus = (n > 0) ? unsigned(n) : 1;
diff --git a/src/third_party/mozjs/js/src/jslock.h b/src/third_party/mozjs/js/src/jslock.h
index b91e1f9..f27c300 100644
--- a/src/third_party/mozjs/js/src/jslock.h
+++ b/src/third_party/mozjs/js/src/jslock.h
@@ -11,6 +11,17 @@
#ifdef JS_THREADSAFE
+#if defined(STARBOARD)
+#include "starboard/atomic.h"
+
+#define JS_ATOMIC_INCREMENT(p) SbAtomicBarrier_Increment((SbAtomic32*)(p), 1)
+#define JS_ATOMIC_DECREMENT(p) SbAtomicBarrier_Increment((SbAtomic32*)(p), -1)
+#define JS_ATOMIC_ADD(p, v) \
+ SbAtomicBarrier_Increment((SbAtomic32*)(p), (SbAtomic32)(v))
+#define JS_ATOMIC_SET(p, v) \
+ SbAtomicNoBarrier_Exchange((SbAtomic32*)(p), (SbAtomic32)(v))
+
+#else // defined(STARBOARD)
# include "pratom.h"
# include "prlock.h"
# include "prcvar.h"
@@ -21,6 +32,7 @@
# define JS_ATOMIC_DECREMENT(p) PR_ATOMIC_DECREMENT((int32_t *)(p))
# define JS_ATOMIC_ADD(p,v) PR_ATOMIC_ADD((int32_t *)(p), (int32_t)(v))
# define JS_ATOMIC_SET(p,v) PR_ATOMIC_SET((int32_t *)(p), (int32_t)(v))
+#endif // defined(STARBOARD)
namespace js {
// Defined in jsgc.cpp.
diff --git a/src/third_party/mozjs/js/src/jsscript.h b/src/third_party/mozjs/js/src/jsscript.h
index 9b4c5c1..fea2c4e 100644
--- a/src/third_party/mozjs/js/src/jsscript.h
+++ b/src/third_party/mozjs/js/src/jsscript.h
@@ -19,6 +19,10 @@
#include "js/RootingAPI.h"
#include "vm/Shape.h"
+#if defined(STARBOARD) && defined(JS_THREADSAFE)
+#include "pr_starboard.h"
+#endif // defined(STARBOARD) && defined(JS_THREADSAFE)
+
namespace js {
namespace jit {
diff --git a/src/third_party/mozjs/js/src/jsworkers.cpp b/src/third_party/mozjs/js/src/jsworkers.cpp
index 57b16ea..cbe03b2 100644
--- a/src/third_party/mozjs/js/src/jsworkers.cpp
+++ b/src/third_party/mozjs/js/src/jsworkers.cpp
@@ -16,6 +16,10 @@
# include "jit/ExecutionModeInlines.h"
#endif
+#if defined(JS_THREADSAFE) && defined(STARBOARD)
+#include "pr_starboard.h"
+#endif // defined(JS_THREADSAFE) && defined(STARBOARD)
+
using namespace js;
using mozilla::DebugOnly;
diff --git a/src/third_party/mozjs/js/src/pr_starboard.cc b/src/third_party/mozjs/js/src/pr_starboard.cc
new file mode 100644
index 0000000..239153f
--- /dev/null
+++ b/src/third_party/mozjs/js/src/pr_starboard.cc
@@ -0,0 +1,281 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "pr_starboard.h"
+
+#include "starboard/condition_variable.h"
+#include "starboard/log.h"
+#include "starboard/memory.h"
+#include "starboard/mutex.h"
+#include "starboard/once.h"
+#include "starboard/queue.h"
+#include "starboard/thread.h"
+#include "starboard/time.h"
+#include "starboard/types.h"
+
+namespace {
+
+typedef starboard::Queue<bool> SetupSignalQueue;
+
+// Utility function to convert a PRInterval to signed 64 bit integer
+// microseconds.
+int64_t PR_IntervalToMicrosecondsInt64(PRIntervalTime ticks) {
+ uint32_t microseconds_as_uint32 = PR_IntervalToMicroseconds(ticks);
+ int64_t microseconds_as_int64 = static_cast<int64_t>(microseconds_as_uint32);
+ return microseconds_as_int64;
+}
+
+// Struct to bundle up arguments to be passed into SbThreadCreate.
+struct ThreadEntryPointWrapperContext {
+ ThreadEntryPointWrapperContext(void* pr_context,
+ PRThread* pr_thread,
+ PRThreadEntryPoint pr_entry_point,
+ SetupSignalQueue* setup_signal_queue)
+ : pr_context(pr_context),
+ pr_thread(pr_thread),
+ pr_entry_point(pr_entry_point),
+ setup_signal_queue(setup_signal_queue) {}
+ void* pr_context;
+ PRThread* pr_thread;
+ PRThreadEntryPoint pr_entry_point;
+ SetupSignalQueue* setup_signal_queue;
+};
+
+// The thread local key that corresponds to where local PRThread* data is held.
+SbThreadLocalKey g_pr_thread_local_key = kSbThreadLocalKeyInvalid;
+// The SbOnceControlStructure to to ensure that the local key is only created
+// once.
+SbOnceControl g_pr_thread_key_once_control = SB_ONCE_INITIALIZER;
+
+void PrThreadDtor(void* value) {
+ PRThread* pr_thread = reinterpret_cast<PRThread*>(value);
+ delete pr_thread;
+}
+
+void InitPrThreadKey() {
+ g_pr_thread_local_key = SbThreadCreateLocalKey(PrThreadDtor);
+}
+
+SbThreadLocalKey GetPrThreadKey() {
+ SB_CHECK(SbOnce(&g_pr_thread_key_once_control, InitPrThreadKey));
+ return g_pr_thread_local_key;
+}
+
+void* ThreadEntryPointWrapper(void* context_as_void_pointer) {
+ ThreadEntryPointWrapperContext* context =
+ reinterpret_cast<ThreadEntryPointWrapperContext*>(
+ context_as_void_pointer);
+ void* pr_context = context->pr_context;
+ PRThreadEntryPoint pr_entry_point = context->pr_entry_point;
+ PRThread* pr_thread = context->pr_thread;
+ SetupSignalQueue* setup_signal_queue = context->setup_signal_queue;
+
+ delete context;
+
+ pr_thread->sb_thread = SbThreadGetCurrent();
+ SbThreadLocalKey key = GetPrThreadKey();
+ SB_CHECK(SbThreadIsValidLocalKey(key));
+ SbThreadSetLocalValue(key, pr_thread);
+
+ setup_signal_queue->Put(true);
+ pr_entry_point(pr_context);
+
+ return NULL;
+}
+
+} // namespace
+
+PRLock* PR_NewLock() {
+ PRLock* lock = new PRLock();
+ if (!SbMutexCreate(lock)) {
+ delete lock;
+ return NULL;
+ }
+ return lock;
+}
+
+void PR_DestroyLock(PRLock* lock) {
+ SB_DCHECK(lock);
+ SbMutexDestroy(lock);
+ delete lock;
+}
+
+PRCondVar* PR_NewCondVar(PRLock* lock) {
+ SB_DCHECK(lock);
+ PRCondVar* cvar = new PRCondVar();
+ if (!SbConditionVariableCreate(&cvar->sb_condition_variable, lock)) {
+ delete cvar;
+ return NULL;
+ }
+ cvar->lock = lock;
+ return cvar;
+}
+
+void PR_DestroyCondVar(PRCondVar* cvar) {
+ SbConditionVariableDestroy(&cvar->sb_condition_variable);
+ delete cvar;
+}
+
+PRStatus PR_WaitCondVar(PRCondVar* cvar, PRIntervalTime timeout) {
+ SbConditionVariableResult result;
+ if (timeout == PR_INTERVAL_NO_WAIT) {
+ result = SbConditionVariableWaitTimed(&cvar->sb_condition_variable,
+ cvar->lock, 0);
+ } else if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+ result = SbConditionVariableWait(&cvar->sb_condition_variable, cvar->lock);
+ } else {
+ int64_t microseconds = PR_IntervalToMicrosecondsInt64(timeout);
+ result = SbConditionVariableWaitTimed(&cvar->sb_condition_variable,
+ cvar->lock, microseconds);
+ }
+ return pr_starboard::ToPRStatus(result != kSbConditionVariableFailed);
+}
+
+PRThread* PR_GetCurrentThread() {
+ SbThreadLocalKey key = GetPrThreadKey();
+ SB_CHECK(SbThreadIsValidLocalKey(key));
+
+ PRThread* value = static_cast<PRThread*>(SbThreadGetLocalValue(key));
+ // We could potentially be a thread that was not created through
+ // PR_CreateThread. In this case, we must allocate a PRThread and do the
+ // setup that would normally have been done in PR_CreateThread.
+ if (!value) {
+ PRThread* pr_thread = new PRThread(SbThreadGetCurrent());
+ SbThreadSetLocalValue(key, pr_thread);
+ value = pr_thread;
+ }
+
+ return value;
+}
+
+uint32_t PR_snprintf(char* out, uint32_t outlen, const char* fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ uint32_t ret = PR_vsnprintf(out, outlen, fmt, args);
+ va_end(args);
+ return ret;
+}
+
+PRThread* PR_CreateThread(PRThreadType type,
+ PRThreadEntryPoint start,
+ void* arg,
+ PRThreadPriority priority,
+ PRThreadScope scope,
+ PRThreadState state,
+ PRUint32 stackSize) {
+ int64_t sb_stack_size = static_cast<int64_t>(stackSize);
+
+ SbThreadPriority sb_priority;
+ switch (priority) {
+ case PR_PRIORITY_LOW:
+ sb_priority = kSbThreadPriorityLow;
+ break;
+ case PR_PRIORITY_NORMAL:
+ sb_priority = kSbThreadPriorityNormal;
+ break;
+ case PR_PRIORITY_HIGH:
+ sb_priority = kSbThreadPriorityHigh;
+ break;
+ case PR_PRIORITY_LAST:
+ sb_priority = kSbThreadPriorityHighest;
+ break;
+ default:
+ sb_priority = kSbThreadNoPriority;
+ }
+
+ SbThreadAffinity sb_affinity = kSbThreadNoAffinity;
+
+ SB_DCHECK(state == PR_JOINABLE_THREAD || state == PR_UNJOINABLE_THREAD);
+ bool sb_joinable = (state == PR_JOINABLE_THREAD);
+
+ // This heap allocated PRThread object will have a pointer to it stored in
+ // the newly created child thread's thread local storage. Once the newly
+ // created child thread finishes, it will be freed in the destructor
+ // associated with it through thread local storage.
+ PRThread* pr_thread = new PRThread(kSbThreadInvalid);
+
+ // Utility queue for the ThreadEntryWrapper to signal us once it's done
+ // running its initial setup and we can safely exit.
+ SetupSignalQueue setup_signal_queue;
+
+ // This heap allocated context object is freed after
+ // ThreadEntryPointWrapper's initial setup is complete, right before the
+ // nspr level entry point is run.
+ ThreadEntryPointWrapperContext* context = new ThreadEntryPointWrapperContext(
+ arg, pr_thread, start, &setup_signal_queue);
+
+ // Note that pr_thread->sb_thread will be set to the correct value in the
+ // setup section of ThreadEntryPointWrapper. It is done there rather than
+ // here to account for the unlikely but possible case in which we enter the
+ // newly created child thread, and then the child thread passes references
+ // to itself off into its potential children or co-threads that interact
+ // with it before we can copy what SbThreadCreate returns into
+ // pr_thread->sb_thread from this current thread.
+ SbThreadCreate(sb_stack_size, sb_priority, sb_affinity, sb_joinable, NULL,
+ ThreadEntryPointWrapper, context);
+
+ // Now we must wait for the setup section of ThreadEntryPointWrapper to run
+ // and initialize pr_thread (both the struct itself and the corresponding
+ // new thread's private data) before we can safely return. We expect to
+ // receive true rather than false by convention.
+ bool setup_signal = setup_signal_queue.Get();
+ SB_DCHECK(setup_signal);
+
+ return pr_thread;
+}
+
+PRStatus PR_CallOnceWithArg(PRCallOnceType* once,
+ PRCallOnceWithArgFN func,
+ void* arg) {
+ SB_NOTREACHED() << "Not implemented";
+ return PR_FAILURE;
+}
+
+PRStatus PR_NewThreadPrivateIndex(PRTLSIndex* newIndex,
+ PRThreadPrivateDTOR destructor) {
+ SbThreadLocalKey key = SbThreadCreateLocalKey(destructor);
+ if (!SbThreadIsValidLocalKey(key)) {
+ return pr_starboard::ToPRStatus(false);
+ }
+ *newIndex = key;
+ return pr_starboard::ToPRStatus(true);
+}
+
+PRIntervalTime PR_MillisecondsToInterval(PRUint32 milli) {
+ PRUint64 tock = static_cast<PRUint64>(milli);
+ PRUint64 msecPerSec = static_cast<PRInt64>(PR_MSEC_PER_SEC);
+ PRUint64 rounding = static_cast<PRInt64>(PR_MSEC_PER_SEC >> 1);
+ PRUint64 tps = static_cast<PRInt64>(PR_TicksPerSecond());
+
+ tock *= tps;
+ tock += rounding;
+ tock /= msecPerSec;
+
+ PRUint64 ticks = static_cast<PRUint64>(tock);
+ return ticks;
+}
+
+PRUint32 PR_IntervalToMicroseconds(PRIntervalTime ticks) {
+ PRUint64 tock = static_cast<PRInt64>(ticks);
+ PRUint64 usecPerSec = static_cast<PRInt64>(PR_USEC_PER_SEC);
+ PRUint64 tps = static_cast<PRInt64>(PR_TicksPerSecond());
+ PRUint64 rounding = static_cast<PRUint64>(tps) >> 1;
+
+ tock *= usecPerSec;
+ tock += rounding;
+ tock /= tps;
+
+ PRUint32 micro = static_cast<PRUint32>(tock);
+ return micro;
+}
diff --git a/src/third_party/mozjs/js/src/pr_starboard.h b/src/third_party/mozjs/js/src/pr_starboard.h
new file mode 100644
index 0000000..72ff257
--- /dev/null
+++ b/src/third_party/mozjs/js/src/pr_starboard.h
@@ -0,0 +1,185 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This header defines the interface for the starboard based implementation of
+// the subset of nspr that spider monkey 24 depends on. It should directly
+// match the nspr api, with the exception that accessing thread local data
+// should use PRTLSIndex, rather than PRUintn.
+
+#ifndef PR_STARBOARD_H_
+#define PR_STARBOARD_H_
+
+#include "starboard/condition_variable.h"
+#include "starboard/log.h"
+#include "starboard/memory.h"
+#include "starboard/mutex.h"
+#include "starboard/string.h"
+#include "starboard/thread.h"
+#include "starboard/types.h"
+
+#define PR_CALLBACK
+
+#define PR_MSEC_PER_SEC 1000L
+#define PR_USEC_PER_SEC 1000000L
+#define PR_NSEC_PER_SEC 1000000000L
+#define PR_USEC_PER_MSEC 1000L
+#define PR_NSEC_PER_MSEC 1000000L
+
+typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus;
+
+namespace pr_starboard {
+
+// Utility function to map true to PR_SUCCESS and false to PR_FAILURE.
+static inline PRStatus ToPRStatus(bool result) {
+ return result ? PR_SUCCESS : PR_FAILURE;
+}
+
+} // namespace pr_starboard
+
+typedef enum PRThreadPriority {
+ PR_PRIORITY_FIRST = 0,
+ PR_PRIORITY_LOW = 0,
+ PR_PRIORITY_NORMAL = 1,
+ PR_PRIORITY_HIGH = 2,
+ PR_PRIORITY_URGENT = 3,
+ PR_PRIORITY_LAST = 3
+} PRThreadPriority;
+
+typedef enum PRThreadScope {
+ PR_LOCAL_THREAD,
+ PR_GLOBAL_THREAD,
+ PR_GLOBAL_BOUND_THREAD
+} PRThreadScope;
+
+typedef enum PRThreadState {
+ PR_JOINABLE_THREAD,
+ PR_UNJOINABLE_THREAD
+} PRThreadState;
+
+typedef enum PRThreadType { PR_USER_THREAD, PR_SYSTEM_THREAD } PRThreadType;
+
+typedef SbThreadLocalKey PRTLSIndex;
+typedef uint32_t PRIntervalTime;
+
+typedef int32_t PRInt32;
+typedef uint32_t PRUint32;
+
+typedef int64_t PRInt64;
+typedef uint64_t PRUint64;
+
+typedef void(PR_CALLBACK* PRThreadPrivateDTOR)(void* priv);
+
+struct PRThread {
+ PRThread(SbThread sb_thread) : sb_thread(sb_thread) {}
+ SbThread sb_thread;
+};
+
+typedef SbMutex PRLock;
+
+#define PR_INTERVAL_NO_WAIT 0UL
+#define PR_INTERVAL_NO_TIMEOUT 0xffffffffUL
+
+struct PRCondVar {
+ SbConditionVariable sb_condition_variable;
+ SbMutex* lock;
+};
+
+PRLock* PR_NewLock();
+
+static inline void PR_Lock(PRLock* lock) {
+ SbMutexAcquire(lock);
+}
+
+static inline void PR_Unlock(PRLock* lock) {
+ SbMutexRelease(lock);
+}
+
+void PR_DestroyLock(PRLock* lock);
+
+PRCondVar* PR_NewCondVar(PRLock* lock);
+
+void PR_DestroyCondVar(PRCondVar* cvar);
+
+PRStatus PR_WaitCondVar(PRCondVar* cvar, PRIntervalTime timeout);
+
+static inline PRStatus PR_NotifyCondVar(PRCondVar* cvar) {
+ return pr_starboard::ToPRStatus(
+ SbConditionVariableSignal(&cvar->sb_condition_variable));
+}
+
+static inline PRStatus PR_NotifyAllCondVar(PRCondVar* cvar) {
+ return pr_starboard::ToPRStatus(
+ SbConditionVariableBroadcast(&cvar->sb_condition_variable));
+}
+
+typedef void (*PRThreadEntryPoint)(void*);
+
+PRThread* PR_CreateThread(PRThreadType type,
+ PRThreadEntryPoint start,
+ void* arg,
+ PRThreadPriority priority,
+ PRThreadScope scope,
+ PRThreadState state,
+ PRUint32 stackSize);
+
+static inline PRStatus PR_JoinThread(PRThread* pr_thread) {
+ SB_DCHECK(pr_thread);
+ SB_DCHECK(SbThreadIsValid(pr_thread->sb_thread));
+ return pr_starboard::ToPRStatus(SbThreadJoin(pr_thread->sb_thread, NULL));
+}
+
+PRThread* PR_GetCurrentThread();
+
+void PR_DetachThread();
+
+PRStatus PR_NewThreadPrivateIndex(PRTLSIndex* newIndex,
+ PRThreadPrivateDTOR destructor);
+
+static inline PRStatus PR_SetThreadPrivate(PRTLSIndex index, void* priv) {
+ return pr_starboard::ToPRStatus(SbThreadSetLocalValue(index, priv));
+}
+
+static inline void* PR_GetThreadPrivate(PRTLSIndex index) {
+ return SbThreadGetLocalValue(index);
+}
+
+static inline void PR_SetCurrentThreadName(const char* name) {
+ SbThreadSetName(name);
+}
+
+static inline PRUint32 PR_vsnprintf(char* out,
+ PRUint32 outlen,
+ const char* fmt,
+ va_list ap) {
+ return static_cast<PRUint32>(SbStringFormat(out, outlen, fmt, ap));
+}
+
+PRUint32 PR_snprintf(char* out, PRUint32 outlen, const char* fmt, ...);
+
+PRIntervalTime PR_MillisecondsToInterval(PRUint32 milli);
+
+PRUint32 PR_IntervalToMicroseconds(PRIntervalTime ticks);
+
+struct PRCallOnceType {};
+typedef PRStatus(PR_CALLBACK* PRCallOnceWithArgFN)(void* arg);
+
+PRStatus PR_CallOnceWithArg(PRCallOnceType* once,
+ PRCallOnceWithArgFN func,
+ void* arg);
+
+static inline PRUint32 PR_TicksPerSecond() {
+ return 1000;
+}
+
+#endif // #ifndef PR_STARBOARD_H_
diff --git a/src/third_party/mozjs/js/src/shell/js.cpp b/src/third_party/mozjs/js/src/shell/js.cpp
index 4af5e8d..03d0010 100644
--- a/src/third_party/mozjs/js/src/shell/js.cpp
+++ b/src/third_party/mozjs/js/src/shell/js.cpp
@@ -92,6 +92,7 @@
#endif
#include "starboard/client_porting/wrap_main/wrap_main.h"
+#include "starboard/memory.h"
using namespace js;
using namespace js::cli;
@@ -108,6 +109,14 @@
size_t gStackChunkSize = 8192;
+#if defined(STARBOARD)
+size_t CalculateStackQuota() {
+ void* stack_high;
+ void* stack_low;
+ SbMemoryGetStackBounds(&stack_high, &stack_low);
+ return 3 * (reinterpret_cast<intptr_t>(stack_high) - reinterpret_cast<intptr_t>(stack_low)) / 4;
+}
+#else
/*
* Note: This limit should match the stack limit set by the browser in
* js/xpconnect/src/XPCJSRuntime.cpp
@@ -117,9 +126,14 @@
#else
size_t gMaxStackSize = 128 * sizeof(size_t) * 1024;
#endif
+#endif
#ifdef JS_THREADSAFE
+#if defined(STARBOARD)
+static PRTLSIndex gStackBaseThreadIndex;
+#else
static unsigned gStackBaseThreadIndex;
+#endif // defined(STARBOARD)
#else
static uintptr_t gStackBase;
#endif
@@ -5422,7 +5436,12 @@
JS_SetTrustedPrincipals(rt, &shellTrustedPrincipals);
JS_SetSecurityCallbacks(rt, &securityCallbacks);
+#if defined(STARBOARD)
+ // This sets the quota to 3/4 the stack size.
+ JS_SetNativeStackQuota(rt, CalculateStackQuota());
+#else
JS_SetNativeStackQuota(rt, gMaxStackSize);
+#endif
if (!InitWatchdog(rt))
return 1;
diff --git a/src/third_party/mozjs/js/src/vm/ForkJoin.cpp b/src/third_party/mozjs/js/src/vm/ForkJoin.cpp
index d0216e6..1f21799 100644
--- a/src/third_party/mozjs/js/src/vm/ForkJoin.cpp
+++ b/src/third_party/mozjs/js/src/vm/ForkJoin.cpp
@@ -7,8 +7,13 @@
#include "jscntxt.h"
#ifdef JS_THREADSAFE
+#if defined(STARBOARD)
+#include "pr_starboard.h"
+#else // defined(STARBOARD)
# include "prthread.h"
# include "prprf.h"
+#endif // defined(STARBOARD)
+
#endif
#include "vm/ForkJoin.h"
@@ -208,7 +213,11 @@
NumForkJoinModes
};
+#if defined(STARBOARD)
+PRTLSIndex ForkJoinSlice::ThreadPrivateIndex;
+#else // defined(STARBOARD)
unsigned ForkJoinSlice::ThreadPrivateIndex;
+#endif // defined(STARBOARD)
bool ForkJoinSlice::TLSInitialized;
class ParallelDo
diff --git a/src/third_party/mozjs/js/src/vm/ForkJoin.h b/src/third_party/mozjs/js/src/vm/ForkJoin.h
index b961548..aa86021 100644
--- a/src/third_party/mozjs/js/src/vm/ForkJoin.h
+++ b/src/third_party/mozjs/js/src/vm/ForkJoin.h
@@ -360,7 +360,11 @@
#if defined(JS_THREADSAFE) && defined(JS_ION)
// Initialized by InitializeTLS()
+#if defined(STARBOARD)
+ static PRTLSIndex ThreadPrivateIndex;
+#else // defined(STARBOARD)
static unsigned ThreadPrivateIndex;
+#endif // defined(STARBOARD)
static bool TLSInitialized;
#endif
diff --git a/src/third_party/mozjs/js/src/vm/Monitor.h b/src/third_party/mozjs/js/src/vm/Monitor.h
index 9aaa504..0da5116 100644
--- a/src/third_party/mozjs/js/src/vm/Monitor.h
+++ b/src/third_party/mozjs/js/src/vm/Monitor.h
@@ -9,6 +9,10 @@
#include "jslock.h"
+#if defined(STARBOARD) && defined(JS_THREADSAFE)
+#include "pr_starboard.h"
+#endif // defined(STARBOARD) && defined(JS_THREADSAFE)
+
namespace js {
// A base class used for types intended to be used in a parallel
diff --git a/src/third_party/mozjs/js/src/vm/ThreadPool.cpp b/src/third_party/mozjs/js/src/vm/ThreadPool.cpp
index 754ad50..af88bbc 100644
--- a/src/third_party/mozjs/js/src/vm/ThreadPool.cpp
+++ b/src/third_party/mozjs/js/src/vm/ThreadPool.cpp
@@ -11,7 +11,9 @@
#include "vm/ThreadPool.h"
#ifdef JS_THREADSAFE
+#if !defined(STARBOARD)
# include "prthread.h"
+#endif // !defined(STARBOARD)
#endif
using namespace js;
@@ -207,8 +209,10 @@
numWorkers_ = 0;
# ifdef DEBUG
+#if !defined(STARBOARD)
if (char *jsthreads = getenv("JS_THREADPOOL_SIZE"))
numWorkers_ = strtol(jsthreads, NULL, 10);
+#endif // !defined(STARBOARD)
# endif
#endif
diff --git a/src/third_party/mozjs/js/src/vm/ThreadPool.h b/src/third_party/mozjs/js/src/vm/ThreadPool.h
index 5999341..1b40ae6 100644
--- a/src/third_party/mozjs/js/src/vm/ThreadPool.h
+++ b/src/third_party/mozjs/js/src/vm/ThreadPool.h
@@ -13,9 +13,13 @@
#include "jsalloc.h"
#ifdef JS_THREADSAFE
+#if defined(STARBOARD)
+#include "pr_starboard.h"
+#else // defined(STARBOARD)
# include "prtypes.h"
# include "prlock.h"
# include "prcvar.h"
+#endif // defined(STARBOARD)
#endif
struct JSContext;
diff --git a/src/third_party/mozjs/mozjs.gyp b/src/third_party/mozjs/mozjs.gyp
index b0c4497..bede0e6 100644
--- a/src/third_party/mozjs/mozjs.gyp
+++ b/src/third_party/mozjs/mozjs.gyp
@@ -34,6 +34,10 @@
'JS_USE_CUSTOM_ALLOCATOR',
# Do not export symbols that are declare with JS_PUBLIC_[API|DATA].
'STATIC_JS_API',
+ # Option that enables support for running multiple threads of JavaScript
+ # code concurrently as long as no objects or strings are shared between
+ # them.
+ 'JS_THREADSAFE',
],
'include_dirs': [
'cobalt_config/include',
@@ -368,7 +372,7 @@
# Host tool used to generate a header file that defines a huge switch
# statement for JavaScript keywords.
'target_name': 'mozjs_keyword_header_gen',
- 'type': '<(final_executable_type)',
+ 'type': 'executable',
'toolsets': ['host'],
'sources': [
'js/src/jskwgen.cpp',
@@ -378,7 +382,7 @@
{
# Host tool used to generate a header file that defines opcode lengths.
'target_name': 'mozjs_opcode_length_header_gen',
- 'type': '<(final_executable_type)',
+ 'type': 'executable',
'toolsets': ['host'],
'sources': [
'js/src/jsoplengen.cpp',
diff --git a/src/third_party/mozjs/mozjs.gypi b/src/third_party/mozjs/mozjs.gypi
index 6b85ee0..6e45b6f 100644
--- a/src/third_party/mozjs/mozjs.gypi
+++ b/src/third_party/mozjs/mozjs.gypi
@@ -85,6 +85,7 @@
'js/src/memory_allocator_reporter.cpp',
'js/src/perf/jsperf.cpp',
'js/src/perf/pm_stub.cpp',
+ 'js/src/pr_starboard.cc',
'js/src/prmjtime.cpp',
'js/src/vm/ArgumentsObject.cpp',
'js/src/vm/CharacterEncoding.cpp',