From 4515fb5c4f4f00400d533c75bd4d483b7b9296e9 Mon Sep 17 00:00:00 2001 From: "jochen@chromium.org" Date: Wed, 20 Nov 2013 10:59:13 +0000 Subject: [PATCH] Make it possible to add more than one piece of embedder data to isolates This will allow for using gin and blink bindings in the same process BUG=317398 R=svenpanne@chromium.org, dcarney@chromium.org LOG=y Review URL: https://codereview.chromium.org/77913003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17907 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 62 ++++++++++++++++++++++++++++++++++------- src/d8.cc | 6 ++-- src/isolate.cc | 1 - src/isolate.h | 12 ++++++-- test/cctest/test-api.cc | 32 ++++++++++++++------- 5 files changed, 86 insertions(+), 27 deletions(-) diff --git a/include/v8.h b/include/v8.h index 2f8af2726..fc94f86dc 100644 --- a/include/v8.h +++ b/include/v8.h @@ -4059,16 +4059,36 @@ class V8_EXPORT Isolate { void Dispose(); /** - * Associate embedder-specific data with the isolate + * Associate embedder-specific data with the isolate. This legacy method + * puts the data in the 0th slot. It will be deprecated soon. */ V8_INLINE void SetData(void* data); /** - * Retrieve embedder-specific data from the isolate. + * Associate embedder-specific data with the isolate. |slot| has to be + * between 0 and GetNumberOfDataSlots() - 1. + */ + V8_INLINE void SetData(uint32_t slot, void* data); + + /** + * Retrieve embedder-specific data from the isolate. This legacy method + * retrieves the data from slot 0. It will be deprecated soon. * Returns NULL if SetData has never been called. */ V8_INLINE void* GetData(); + /** + * Retrieve embedder-specific data from the isolate. + * Returns NULL if SetData has never been called for the given |slot|. + */ + V8_INLINE void* GetData(uint32_t slot); + + /** + * Returns the maximum number of available embedder data slots. Valid slots + * are in the range of 0 - GetNumberOfDataSlots() - 1. + */ + V8_INLINE static uint32_t GetNumberOfDataSlots(); + /** * Get statistics about the heap memory usage. */ @@ -5454,7 +5474,7 @@ class Internals { static const int kExternalAsciiRepresentationTag = 0x06; static const int kIsolateEmbedderDataOffset = 1 * kApiPointerSize; - static const int kIsolateRootsOffset = 3 * kApiPointerSize; + static const int kIsolateRootsOffset = 6 * kApiPointerSize; static const int kUndefinedValueRootIndex = 5; static const int kNullValueRootIndex = 7; static const int kTrueValueRootIndex = 8; @@ -5478,6 +5498,8 @@ class Internals { static const int kUndefinedOddballKind = 5; static const int kNullOddballKind = 3; + static const uint32_t kNumIsolateDataSlots = 4; + V8_EXPORT static void CheckInitializedImpl(v8::Isolate* isolate); V8_INLINE static void CheckInitialized(v8::Isolate* isolate) { #ifdef V8_ENABLE_CHECKS @@ -5541,15 +5563,17 @@ class Internals { *addr = static_cast((*addr & ~kNodeStateMask) | value); } - V8_INLINE static void SetEmbedderData(v8::Isolate* isolate, void* data) { - uint8_t* addr = reinterpret_cast(isolate) + - kIsolateEmbedderDataOffset; + V8_INLINE static void SetEmbedderData(v8::Isolate *isolate, + uint32_t slot, + void *data) { + uint8_t *addr = reinterpret_cast(isolate) + + kIsolateEmbedderDataOffset + slot * kApiPointerSize; *reinterpret_cast(addr) = data; } - V8_INLINE static void* GetEmbedderData(v8::Isolate* isolate) { + V8_INLINE static void* GetEmbedderData(v8::Isolate* isolate, uint32_t slot) { uint8_t* addr = reinterpret_cast(isolate) + - kIsolateEmbedderDataOffset; + kIsolateEmbedderDataOffset + slot * kApiPointerSize; return *reinterpret_cast(addr); } @@ -6475,13 +6499,31 @@ Handle False(Isolate* isolate) { void Isolate::SetData(void* data) { typedef internal::Internals I; - I::SetEmbedderData(this, data); + I::SetEmbedderData(this, 0, data); } void* Isolate::GetData() { typedef internal::Internals I; - return I::GetEmbedderData(this); + return I::GetEmbedderData(this, 0); +} + + +void Isolate::SetData(uint32_t slot, void* data) { + typedef internal::Internals I; + I::SetEmbedderData(this, slot, data); +} + + +void* Isolate::GetData(uint32_t slot) { + typedef internal::Internals I; + return I::GetEmbedderData(this, slot); +} + + +uint32_t Isolate::GetNumberOfDataSlots() { + typedef internal::Internals I; + return I::kNumIsolateDataSlots; } diff --git a/src/d8.cc b/src/d8.cc index 339cc327b..9dd8e9171 100644 --- a/src/d8.cc +++ b/src/d8.cc @@ -92,15 +92,15 @@ class PerIsolateData { public: explicit PerIsolateData(Isolate* isolate) : isolate_(isolate), realms_(NULL) { HandleScope scope(isolate); - isolate->SetData(this); + isolate->SetData(0, this); } ~PerIsolateData() { - isolate_->SetData(NULL); // Not really needed, just to be sure... + isolate_->SetData(0, NULL); // Not really needed, just to be sure... } inline static PerIsolateData* Get(Isolate* isolate) { - return reinterpret_cast(isolate->GetData()); + return reinterpret_cast(isolate->GetData(0)); } class RealmScope { diff --git a/src/isolate.cc b/src/isolate.cc index 700ca87c7..7360cd5fe 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -1720,7 +1720,6 @@ void Isolate::ThreadDataTable::RemoveAllThreads(Isolate* isolate) { Isolate::Isolate() : state_(UNINITIALIZED), - embedder_data_(NULL), entry_stack_(NULL), stack_trace_nesting_level_(0), incomplete_message_(NULL), diff --git a/src/isolate.h b/src/isolate.h index 1d45de97b..440c98319 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -1050,8 +1050,14 @@ class Isolate { thread_local_top_.current_vm_state_ = state; } - void SetData(void* data) { embedder_data_ = data; } - void* GetData() { return embedder_data_; } + void SetData(uint32_t slot, void* data) { + ASSERT(slot < Internals::kNumIsolateDataSlots); + embedder_data_[slot] = data; + } + void* GetData(uint32_t slot) { + ASSERT(slot < Internals::kNumIsolateDataSlots); + return embedder_data_[slot]; + } LookupResult* top_lookup_result() { return thread_local_top_.top_lookup_result_; @@ -1165,7 +1171,7 @@ class Isolate { // with v8::internal::Internals (in include/v8.h) constants. This is also // verified in Isolate::Init() using runtime checks. State state_; // Will be padded to kApiPointerSize. - void* embedder_data_; + void* embedder_data_[Internals::kNumIsolateDataSlots]; Heap heap_; // The per-process lock should be acquired before the ThreadDataTable is diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 6a75cd72d..63e806d36 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -19937,16 +19937,28 @@ UNINITIALIZED_TEST(IsolateEmbedderData) { v8::Isolate* isolate = v8::Isolate::New(); isolate->Enter(); i::Isolate* i_isolate = reinterpret_cast(isolate); - CHECK_EQ(NULL, isolate->GetData()); - CHECK_EQ(NULL, i_isolate->GetData()); - static void* data1 = reinterpret_cast(0xacce55ed); - isolate->SetData(data1); - CHECK_EQ(data1, isolate->GetData()); - CHECK_EQ(data1, i_isolate->GetData()); - static void* data2 = reinterpret_cast(0xdecea5ed); - i_isolate->SetData(data2); - CHECK_EQ(data2, isolate->GetData()); - CHECK_EQ(data2, i_isolate->GetData()); + for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) { + CHECK_EQ(NULL, isolate->GetData(slot)); + CHECK_EQ(NULL, i_isolate->GetData(slot)); + } + for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) { + void* data = reinterpret_cast(0xacce55ed + slot); + isolate->SetData(slot, data); + } + for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) { + void* data = reinterpret_cast(0xacce55ed + slot); + CHECK_EQ(data, isolate->GetData(slot)); + CHECK_EQ(data, i_isolate->GetData(slot)); + } + for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) { + void* data = reinterpret_cast(0xdecea5ed + slot); + isolate->SetData(slot, data); + } + for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) { + void* data = reinterpret_cast(0xdecea5ed + slot); + CHECK_EQ(data, isolate->GetData(slot)); + CHECK_EQ(data, i_isolate->GetData(slot)); + } isolate->Exit(); isolate->Dispose(); } -- 2.34.1