diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /js/src/vm/SharedArrayObject.h | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | uxp-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.h | 189 |
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 |