diff options
author | Anna Henningsen <anna@addaleax.net> | 2019-11-08 20:40:46 +0200 |
---|---|---|
committer | Daniel Bevenius <daniel.bevenius@gmail.com> | 2019-11-12 06:29:23 +0100 |
commit | e66a2acc4cb9fc09fc32d1833b89ae56468a0931 (patch) | |
tree | 2db9ffe469a2c662eda46cef848a17d39b8a3787 /src | |
parent | f8c069f5b88a25304ee2fc638c51464b4df196dd (diff) | |
download | android-node-v8-e66a2acc4cb9fc09fc32d1833b89ae56468a0931.tar.gz android-node-v8-e66a2acc4cb9fc09fc32d1833b89ae56468a0931.tar.bz2 android-node-v8-e66a2acc4cb9fc09fc32d1833b89ae56468a0931.zip |
src: migrate off ArrayBuffer::GetContents
V8 deprecates `GetContents()` in favour of `GetBackingStore()`.
Update our code to reflect that.
V8 also deprecates `Externalize()` and `IsExternal()`; we should
be able to remove all usage of this once V8 8.0 is there.
PR-URL: https://github.com/nodejs/node/pull/30339
Refs: https://github.com/v8/v8/commit/bfe3d6bce734e596e312465e207bcfd55a59fe34
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: David Carlier <devnexen@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/aliased_buffer.h | 4 | ||||
-rw-r--r-- | src/js_native_api_v8.cc | 31 | ||||
-rw-r--r-- | src/node_buffer.cc | 13 | ||||
-rw-r--r-- | src/node_contextify.cc | 8 | ||||
-rw-r--r-- | src/node_messaging.cc | 21 | ||||
-rw-r--r-- | src/node_os.cc | 2 | ||||
-rw-r--r-- | src/node_process_methods.cc | 10 | ||||
-rw-r--r-- | src/node_worker.cc | 4 | ||||
-rw-r--r-- | src/node_zlib.cc | 3 | ||||
-rw-r--r-- | src/util-inl.h | 2 | ||||
-rw-r--r-- | src/util.h | 5 |
11 files changed, 63 insertions, 40 deletions
diff --git a/src/aliased_buffer.h b/src/aliased_buffer.h index 5083ae9a1f..b083fb68e6 100644 --- a/src/aliased_buffer.h +++ b/src/aliased_buffer.h @@ -42,7 +42,7 @@ class AliasedBufferBase { // allocate v8 ArrayBuffer v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New( isolate_, size_in_bytes); - buffer_ = static_cast<NativeT*>(ab->GetContents().Data()); + buffer_ = static_cast<NativeT*>(ab->GetBackingStore()->Data()); // allocate v8 TypedArray v8::Local<V8T> js_array = V8T::New(ab, byte_offset_, count); @@ -228,7 +228,7 @@ class AliasedBufferBase { isolate_, new_size_in_bytes); // allocate new native buffer - NativeT* new_buffer = static_cast<NativeT*>(ab->GetContents().Data()); + NativeT* new_buffer = static_cast<NativeT*>(ab->GetBackingStore()->Data()); // copy old content memcpy(new_buffer, buffer_, old_size_in_bytes); diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc index 1f5b6c012f..ef1edb92ee 100644 --- a/src/js_native_api_v8.cc +++ b/src/js_native_api_v8.cc @@ -2562,7 +2562,7 @@ napi_status napi_create_arraybuffer(napi_env env, // Optionally return a pointer to the buffer's data, to avoid another call to // retrieve it. if (data != nullptr) { - *data = buffer->GetContents().Data(); + *data = buffer->GetBackingStore()->Data(); } *result = v8impl::JsValueFromV8LocalValue(buffer); @@ -2608,15 +2608,15 @@ napi_status napi_get_arraybuffer_info(napi_env env, v8::Local<v8::Value> value = v8impl::V8LocalValueFromJsValue(arraybuffer); RETURN_STATUS_IF_FALSE(env, value->IsArrayBuffer(), napi_invalid_arg); - v8::ArrayBuffer::Contents contents = - value.As<v8::ArrayBuffer>()->GetContents(); + std::shared_ptr<v8::BackingStore> backing_store = + value.As<v8::ArrayBuffer>()->GetBackingStore(); if (data != nullptr) { - *data = contents.Data(); + *data = backing_store->Data(); } if (byte_length != nullptr) { - *byte_length = contents.ByteLength(); + *byte_length = backing_store->ByteLength(); } return napi_clear_last_error(env); @@ -2747,9 +2747,15 @@ napi_status napi_get_typedarray_info(napi_env env, *length = array->Length(); } - v8::Local<v8::ArrayBuffer> buffer = array->Buffer(); + v8::Local<v8::ArrayBuffer> buffer; + if (data != nullptr || arraybuffer != nullptr) { + // Calling Buffer() may have the side effect of allocating the buffer, + // so only do this when it’s needed. + buffer = array->Buffer(); + } + if (data != nullptr) { - *data = static_cast<uint8_t*>(buffer->GetContents().Data()) + + *data = static_cast<uint8_t*>(buffer->GetBackingStore()->Data()) + array->ByteOffset(); } @@ -2821,9 +2827,15 @@ napi_status napi_get_dataview_info(napi_env env, *byte_length = array->ByteLength(); } - v8::Local<v8::ArrayBuffer> buffer = array->Buffer(); + v8::Local<v8::ArrayBuffer> buffer; + if (data != nullptr || arraybuffer != nullptr) { + // Calling Buffer() may have the side effect of allocating the buffer, + // so only do this when it’s needed. + buffer = array->Buffer(); + } + if (data != nullptr) { - *data = static_cast<uint8_t*>(buffer->GetContents().Data()) + + *data = static_cast<uint8_t*>(buffer->GetBackingStore()->Data()) + array->ByteOffset(); } @@ -3015,6 +3027,7 @@ napi_status napi_detach_arraybuffer(napi_env env, napi_value arraybuffer) { env, value->IsArrayBuffer(), napi_arraybuffer_expected); v8::Local<v8::ArrayBuffer> it = value.As<v8::ArrayBuffer>(); + // TODO(addaleax): Remove the first condition once we have V8 8.0. RETURN_STATUS_IF_FALSE( env, it->IsExternal(), napi_detachable_arraybuffer_expected); RETURN_STATUS_IF_FALSE( diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 3aa1ea2535..2dbdd61923 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -192,16 +192,13 @@ bool HasInstance(Local<Object> obj) { char* Data(Local<Value> val) { CHECK(val->IsArrayBufferView()); Local<ArrayBufferView> ui = val.As<ArrayBufferView>(); - ArrayBuffer::Contents ab_c = ui->Buffer()->GetContents(); - return static_cast<char*>(ab_c.Data()) + ui->ByteOffset(); + return static_cast<char*>(ui->Buffer()->GetBackingStore()->Data()) + + ui->ByteOffset(); } char* Data(Local<Object> obj) { - CHECK(obj->IsArrayBufferView()); - Local<ArrayBufferView> ui = obj.As<ArrayBufferView>(); - ArrayBuffer::Contents ab_c = ui->Buffer()->GetContents(); - return static_cast<char*>(ab_c.Data()) + ui->ByteOffset(); + return Data(obj.As<Value>()); } @@ -1060,13 +1057,13 @@ static void EncodeInto(const FunctionCallbackInfo<Value>& args) { Local<Uint8Array> dest = args[1].As<Uint8Array>(); Local<ArrayBuffer> buf = dest->Buffer(); char* write_result = - static_cast<char*>(buf->GetContents().Data()) + dest->ByteOffset(); + static_cast<char*>(buf->GetBackingStore()->Data()) + dest->ByteOffset(); size_t dest_length = dest->ByteLength(); // results = [ read, written ] Local<Uint32Array> result_arr = args[2].As<Uint32Array>(); uint32_t* results = reinterpret_cast<uint32_t*>( - static_cast<char*>(result_arr->Buffer()->GetContents().Data()) + + static_cast<char*>(result_arr->Buffer()->GetBackingStore()->Data()) + result_arr->ByteOffset()); int nchars; diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 2d30e0b803..46a1d7c8ef 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -697,8 +697,8 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) { ScriptCompiler::CachedData* cached_data = nullptr; if (!cached_data_buf.IsEmpty()) { - ArrayBuffer::Contents contents = cached_data_buf->Buffer()->GetContents(); - uint8_t* data = static_cast<uint8_t*>(contents.Data()); + uint8_t* data = static_cast<uint8_t*>( + cached_data_buf->Buffer()->GetBackingStore()->Data()); cached_data = new ScriptCompiler::CachedData( data + cached_data_buf->ByteOffset(), cached_data_buf->ByteLength()); } @@ -1044,8 +1044,8 @@ void ContextifyContext::CompileFunction( // Read cache from cached data buffer ScriptCompiler::CachedData* cached_data = nullptr; if (!cached_data_buf.IsEmpty()) { - ArrayBuffer::Contents contents = cached_data_buf->Buffer()->GetContents(); - uint8_t* data = static_cast<uint8_t*>(contents.Data()); + uint8_t* data = static_cast<uint8_t*>( + cached_data_buf->Buffer()->GetBackingStore()->Data()); cached_data = new ScriptCompiler::CachedData( data + cached_data_buf->ByteOffset(), cached_data_buf->ByteLength()); } diff --git a/src/node_messaging.cc b/src/node_messaging.cc index 6645ca025b..c54958a4cf 100644 --- a/src/node_messaging.cc +++ b/src/node_messaging.cc @@ -298,12 +298,19 @@ Maybe<bool> Message::Serialize(Environment* env, // Currently, we support ArrayBuffers and MessagePorts. if (entry->IsArrayBuffer()) { Local<ArrayBuffer> ab = entry.As<ArrayBuffer>(); - // If we cannot render the ArrayBuffer unusable in this Isolate and - // take ownership of its memory, copying the buffer will have to do. - if (!ab->IsDetachable() || ab->IsExternal() || - !env->isolate_data()->uses_node_allocator()) { + // If we cannot render the ArrayBuffer unusable in this Isolate, + // copying the buffer will have to do. + // Note that we can currently transfer ArrayBuffers even if they were + // not allocated by Node’s ArrayBufferAllocator in the first place, + // because we pass the underlying v8::BackingStore around rather than + // raw data *and* an Isolate with a non-default ArrayBuffer allocator + // is always going to outlive any Workers it creates, and so will its + // allocator along with it. + // TODO(addaleax): Eventually remove the IsExternal() condition, + // see https://github.com/nodejs/node/pull/30339#issuecomment-552225353 + // for details. + if (!ab->IsDetachable() || ab->IsExternal()) continue; - } if (std::find(array_buffers.begin(), array_buffers.end(), ab) != array_buffers.end()) { ThrowDataCloneException( @@ -363,7 +370,9 @@ Maybe<bool> Message::Serialize(Environment* env, for (Local<ArrayBuffer> ab : array_buffers) { // If serialization succeeded, we render it inaccessible in this Isolate. std::shared_ptr<BackingStore> backing_store = ab->GetBackingStore(); - ab->Externalize(backing_store); + // TODO(addaleax): This can/should be dropped once we have V8 8.0. + if (!ab->IsExternal()) + ab->Externalize(backing_store); ab->Detach(); array_buffers_.emplace_back(std::move(backing_store)); diff --git a/src/node_os.cc b/src/node_os.cc index 131e380556..12a4ec3551 100644 --- a/src/node_os.cc +++ b/src/node_os.cc @@ -171,7 +171,7 @@ static void GetLoadAvg(const FunctionCallbackInfo<Value>& args) { Local<Float64Array> array = args[0].As<Float64Array>(); CHECK_EQ(array->Length(), 3); Local<ArrayBuffer> ab = array->Buffer(); - double* loadavg = static_cast<double*>(ab->GetContents().Data()); + double* loadavg = static_cast<double*>(ab->GetBackingStore()->Data()); uv_loadavg(loadavg); } diff --git a/src/node_process_methods.cc b/src/node_process_methods.cc index 7e2af37907..7efe8efb9b 100644 --- a/src/node_process_methods.cc +++ b/src/node_process_methods.cc @@ -109,7 +109,7 @@ static void CPUUsage(const FunctionCallbackInfo<Value>& args) { Local<Float64Array> array = args[0].As<Float64Array>(); CHECK_EQ(array->Length(), 2); Local<ArrayBuffer> ab = array->Buffer(); - double* fields = static_cast<double*>(ab->GetContents().Data()); + double* fields = static_cast<double*>(ab->GetBackingStore()->Data()); // Set the Float64Array elements to be user / system values in microseconds. fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec; @@ -148,7 +148,7 @@ static void Hrtime(const FunctionCallbackInfo<Value>& args) { uint64_t t = uv_hrtime(); Local<ArrayBuffer> ab = args[0].As<Uint32Array>()->Buffer(); - uint32_t* fields = static_cast<uint32_t*>(ab->GetContents().Data()); + uint32_t* fields = static_cast<uint32_t*>(ab->GetBackingStore()->Data()); fields[0] = (t / NANOS_PER_SEC) >> 32; fields[1] = (t / NANOS_PER_SEC) & 0xffffffff; @@ -157,7 +157,7 @@ static void Hrtime(const FunctionCallbackInfo<Value>& args) { static void HrtimeBigInt(const FunctionCallbackInfo<Value>& args) { Local<ArrayBuffer> ab = args[0].As<BigUint64Array>()->Buffer(); - uint64_t* fields = static_cast<uint64_t*>(ab->GetContents().Data()); + uint64_t* fields = static_cast<uint64_t*>(ab->GetBackingStore()->Data()); fields[0] = uv_hrtime(); } @@ -204,7 +204,7 @@ static void MemoryUsage(const FunctionCallbackInfo<Value>& args) { Local<Float64Array> array = args[0].As<Float64Array>(); CHECK_EQ(array->Length(), 4); Local<ArrayBuffer> ab = array->Buffer(); - double* fields = static_cast<double*>(ab->GetContents().Data()); + double* fields = static_cast<double*>(ab->GetBackingStore()->Data()); fields[0] = rss; fields[1] = v8_heap_stats.total_heap_size(); @@ -301,7 +301,7 @@ static void ResourceUsage(const FunctionCallbackInfo<Value>& args) { Local<Float64Array> array = args[0].As<Float64Array>(); CHECK_EQ(array->Length(), 16); Local<ArrayBuffer> ab = array->Buffer(); - double* fields = static_cast<double*>(ab->GetContents().Data()); + double* fields = static_cast<double*>(ab->GetBackingStore()->Data()); fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec; fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec; diff --git a/src/node_worker.cc b/src/node_worker.cc index 3c604ec2ec..72717331ee 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -622,7 +622,9 @@ void Worker::GetResourceLimits(const FunctionCallbackInfo<Value>& args) { Local<Float64Array> Worker::GetResourceLimits(Isolate* isolate) const { Local<ArrayBuffer> ab = ArrayBuffer::New(isolate, sizeof(resource_limits_)); - memcpy(ab->GetContents().Data(), resource_limits_, sizeof(resource_limits_)); + memcpy(ab->GetBackingStore()->Data(), + resource_limits_, + sizeof(resource_limits_)); return Float64Array::New(ab, 0, kTotalResourceLimitCount); } diff --git a/src/node_zlib.cc b/src/node_zlib.cc index fdcf685caf..739e36d699 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -590,7 +590,8 @@ class ZlibStream : public CompressionStream<ZlibContext> { CHECK(args[4]->IsUint32Array()); Local<Uint32Array> array = args[4].As<Uint32Array>(); Local<ArrayBuffer> ab = array->Buffer(); - uint32_t* write_result = static_cast<uint32_t*>(ab->GetContents().Data()); + uint32_t* write_result = static_cast<uint32_t*>( + ab->GetBackingStore()->Data()); CHECK(args[5]->IsFunction()); Local<Function> write_js_callback = args[5].As<Function>(); diff --git a/src/util-inl.h b/src/util-inl.h index c06a0ae84c..d44ee09fef 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -514,7 +514,7 @@ void ArrayBufferViewContents<T, S>::Read(v8::Local<v8::ArrayBufferView> abv) { static_assert(sizeof(T) == 1, "Only supports one-byte data at the moment"); length_ = abv->ByteLength(); if (length_ > sizeof(stack_storage_) || abv->HasBuffer()) { - data_ = static_cast<T*>(abv->Buffer()->GetContents().Data()) + + data_ = static_cast<T*>(abv->Buffer()->GetBackingStore()->Data()) + abv->ByteOffset(); } else { abv->CopyContents(stack_storage_, sizeof(stack_storage_)); diff --git a/src/util.h b/src/util.h index f2d3f355f9..2f6c17fc32 100644 --- a/src/util.h +++ b/src/util.h @@ -488,11 +488,12 @@ class BufferValue : public MaybeStackBuffer<char> { #define SPREAD_BUFFER_ARG(val, name) \ CHECK((val)->IsArrayBufferView()); \ v8::Local<v8::ArrayBufferView> name = (val).As<v8::ArrayBufferView>(); \ - v8::ArrayBuffer::Contents name##_c = name->Buffer()->GetContents(); \ + std::shared_ptr<v8::BackingStore> name##_bs = \ + name->Buffer()->GetBackingStore(); \ const size_t name##_offset = name->ByteOffset(); \ const size_t name##_length = name->ByteLength(); \ char* const name##_data = \ - static_cast<char*>(name##_c.Data()) + name##_offset; \ + static_cast<char*>(name##_bs->Data()) + name##_offset; \ if (name##_length > 0) \ CHECK_NE(name##_data, nullptr); |