summaryrefslogtreecommitdiff
path: root/js/src/vm/SharedArrayObject.h
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /js/src/vm/SharedArrayObject.h
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloaduxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
Add m-esr52 at 52.6.0
Diffstat (limited to 'js/src/vm/SharedArrayObject.h')
-rw-r--r--js/src/vm/SharedArrayObject.h189
1 files changed, 189 insertions, 0 deletions
diff --git a/js/src/vm/SharedArrayObject.h b/js/src/vm/SharedArrayObject.h
new file mode 100644
index 0000000000..9aef6d74eb
--- /dev/null
+++ b/js/src/vm/SharedArrayObject.h
@@ -0,0 +1,189 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef vm_SharedArrayObject_h
+#define vm_SharedArrayObject_h
+
+#include "mozilla/Atomics.h"
+
+#include "jsapi.h"
+#include "jsobj.h"
+#include "jstypes.h"
+
+#include "gc/Barrier.h"
+#include "vm/ArrayBufferObject.h"
+
+typedef struct JSProperty JSProperty;
+
+namespace js {
+
+class FutexWaiter;
+
+/*
+ * SharedArrayRawBuffer
+ *
+ * A bookkeeping object always stored immediately before the raw buffer.
+ * The buffer itself is mmap()'d and refcounted.
+ * SharedArrayBufferObjects and AsmJS code may hold references.
+ *
+ * |<------ sizeof ------>|<- length ->|
+ *
+ * | waste | SharedArrayRawBuffer | data array | waste |
+ *
+ * Observe that if we want to map the data array on a specific address, such
+ * as absolute zero (bug 1056027), then the SharedArrayRawBuffer cannot be
+ * prefixed to the data array, it has to be a separate object, also in
+ * shared memory. (That would get rid of ~4KB of waste, as well.) Very little
+ * else would have to change throughout the engine, the SARB would point to
+ * the data array using a constant pointer, instead of computing its
+ * address.
+ */
+class SharedArrayRawBuffer
+{
+ private:
+ mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire> refcount_;
+ uint32_t length;
+ bool preparedForAsmJS;
+
+ // A list of structures representing tasks waiting on some
+ // location within this buffer.
+ FutexWaiter* waiters_;
+
+ protected:
+ SharedArrayRawBuffer(uint8_t* buffer, uint32_t length, bool preparedForAsmJS)
+ : refcount_(1),
+ length(length),
+ preparedForAsmJS(preparedForAsmJS),
+ waiters_(nullptr)
+ {
+ MOZ_ASSERT(buffer == dataPointerShared());
+ }
+
+ public:
+ static SharedArrayRawBuffer* New(JSContext* cx, uint32_t length);
+
+ // This may be called from multiple threads. The caller must take
+ // care of mutual exclusion.
+ FutexWaiter* waiters() const {
+ return waiters_;
+ }
+
+ // This may be called from multiple threads. The caller must take
+ // care of mutual exclusion.
+ void setWaiters(FutexWaiter* waiters) {
+ waiters_ = waiters;
+ }
+
+ SharedMem<uint8_t*> dataPointerShared() const {
+ uint8_t* ptr = reinterpret_cast<uint8_t*>(const_cast<SharedArrayRawBuffer*>(this));
+ return SharedMem<uint8_t*>::shared(ptr + sizeof(SharedArrayRawBuffer));
+ }
+
+ uint32_t byteLength() const {
+ return length;
+ }
+
+ bool isPreparedForAsmJS() const {
+ return preparedForAsmJS;
+ }
+
+ uint32_t refcount() const { return refcount_; }
+
+ void addReference();
+ void dropReference();
+};
+
+/*
+ * SharedArrayBufferObject
+ *
+ * When transferred to a WebWorker, the buffer is not detached on the
+ * parent side, and both child and parent reference the same buffer.
+ *
+ * The underlying memory is memory-mapped and reference counted
+ * (across workers and/or processes). The SharedArrayBuffer object
+ * has a finalizer that decrements the refcount, the last one to leave
+ * (globally) unmaps the memory. The sender ups the refcount before
+ * transmitting the memory to another worker.
+ *
+ * SharedArrayBufferObject (or really the underlying memory) /is
+ * racy/: more than one worker can access the memory at the same time.
+ *
+ * A TypedArrayObject (a view) references a SharedArrayBuffer
+ * and keeps it alive. The SharedArrayBuffer does /not/ reference its
+ * views.
+ */
+class SharedArrayBufferObject : public ArrayBufferObjectMaybeShared
+{
+ static bool byteLengthGetterImpl(JSContext* cx, const CallArgs& args);
+
+ public:
+ // RAWBUF_SLOT holds a pointer (as "private" data) to the
+ // SharedArrayRawBuffer object, which is manually managed storage.
+ static const uint8_t RAWBUF_SLOT = 0;
+
+ static const uint8_t RESERVED_SLOTS = 1;
+
+ static const Class class_;
+
+ static bool byteLengthGetter(JSContext* cx, unsigned argc, Value* vp);
+
+ static bool class_constructor(JSContext* cx, unsigned argc, Value* vp);
+
+ // Create a SharedArrayBufferObject with a new SharedArrayRawBuffer.
+ static SharedArrayBufferObject* New(JSContext* cx,
+ uint32_t length,
+ HandleObject proto = nullptr);
+
+ // Create a SharedArrayBufferObject using an existing SharedArrayRawBuffer.
+ static SharedArrayBufferObject* New(JSContext* cx,
+ SharedArrayRawBuffer* buffer,
+ HandleObject proto = nullptr);
+
+ static void Finalize(FreeOp* fop, JSObject* obj);
+
+ static void addSizeOfExcludingThis(JSObject* obj, mozilla::MallocSizeOf mallocSizeOf,
+ JS::ClassInfo* info);
+
+ static void copyData(Handle<SharedArrayBufferObject*> toBuffer,
+ Handle<SharedArrayBufferObject*> fromBuffer,
+ uint32_t fromIndex, uint32_t count);
+
+ SharedArrayRawBuffer* rawBufferObject() const;
+
+ // Invariant: This method does not cause GC and can be called
+ // without anchoring the object it is called on.
+ uintptr_t globalID() const {
+ // The buffer address is good enough as an ID provided the memory is not shared
+ // between processes or, if it is, it is mapped to the same address in every
+ // process. (At the moment, shared memory cannot be shared between processes.)
+ return dataPointerShared().asValue();
+ }
+
+ uint32_t byteLength() const {
+ return rawBufferObject()->byteLength();
+ }
+ bool isPreparedForAsmJS() const {
+ return rawBufferObject()->isPreparedForAsmJS();
+ }
+
+ SharedMem<uint8_t*> dataPointerShared() const {
+ return rawBufferObject()->dataPointerShared();
+ }
+
+private:
+ void acceptRawBuffer(SharedArrayRawBuffer* buffer);
+ void dropRawBuffer();
+};
+
+bool IsSharedArrayBuffer(HandleValue v);
+bool IsSharedArrayBuffer(HandleObject o);
+bool IsSharedArrayBuffer(JSObject* o);
+
+SharedArrayBufferObject& AsSharedArrayBuffer(HandleObject o);
+
+} // namespace js
+
+#endif // vm_SharedArrayObject_h