diff --git a/core/bindings.rs b/core/bindings.rs index b7c20c2ee2..6fe21b53b0 100644 --- a/core/bindings.rs +++ b/core/bindings.rs @@ -3,7 +3,6 @@ use crate::es_isolate::EsIsolate; use crate::isolate::Isolate; use crate::isolate::PinnedBuf; -use crate::isolate::SHARED_RESPONSE_BUF_SIZE; use rusty_v8 as v8; use v8::MapFnTo; @@ -181,38 +180,15 @@ pub fn initialize_context<'s>( scope.escape(context) } -pub unsafe fn slice_to_uint8array<'sc>( - deno_isolate: &mut Isolate, +pub fn boxed_slice_to_uint8array<'sc>( scope: &mut impl v8::ToLocal<'sc>, - buf: &[u8], + buf: Box<[u8]>, ) -> v8::Local<'sc, v8::Uint8Array> { - if buf.is_empty() { - let ab = v8::ArrayBuffer::new(scope, 0); - return v8::Uint8Array::new(ab, 0, 0).expect("Failed to create UintArray8"); - } - + assert!(!buf.is_empty()); let buf_len = buf.len(); - let buf_ptr = buf.as_ptr(); - - // To avoid excessively allocating new ArrayBuffers, we try to reuse a single - // global ArrayBuffer. The caveat is that users must extract data from it - // before the next tick. We only do this for ArrayBuffers less than 1024 - // bytes. - let ab = if buf_len > SHARED_RESPONSE_BUF_SIZE { - // Simple case. We allocate a new ArrayBuffer for this. - v8::ArrayBuffer::new(scope, buf_len) - } else if deno_isolate.shared_response_buf.is_empty() { - let buf = v8::ArrayBuffer::new(scope, SHARED_RESPONSE_BUF_SIZE); - deno_isolate.shared_response_buf.set(scope, buf); - buf - } else { - deno_isolate.shared_response_buf.get(scope).unwrap() - }; - - let mut backing_store = ab.get_backing_store(); - let data = backing_store.data(); - let data: *mut u8 = data as *mut libc::c_void as *mut u8; - std::ptr::copy_nonoverlapping(buf_ptr, data, buf_len); + let backing_store = + unsafe { &mut v8::ArrayBuffer::new_backing_store_from_boxed_slice(buf) }; + let ab = v8::ArrayBuffer::new_with_backing_store(scope, backing_store); v8::Uint8Array::new(ab, 0, buf_len).expect("Failed to create UintArray8") } @@ -444,8 +420,8 @@ fn send( let (_op_id, buf) = response; if !buf.is_empty() { - let ab = unsafe { slice_to_uint8array(deno_isolate, scope, &buf) }; - rv.set(ab.into()) + let ui8 = boxed_slice_to_uint8array(scope, buf); + rv.set(ui8.into()) } } } diff --git a/core/isolate.rs b/core/isolate.rs index fc0d5899b1..07bd8ad1d3 100644 --- a/core/isolate.rs +++ b/core/isolate.rs @@ -32,12 +32,6 @@ use std::slice; use std::sync::{Arc, Mutex, Once}; use std::task::Context; use std::task::Poll; - -/// Size of `ArrayBuffer` that will be allocated and shared -/// between responses. If response is bigger a new one-off -/// `ArrayBuffer` will be allocated. -pub const SHARED_RESPONSE_BUF_SIZE: usize = 1024 * 1024; - /// A PinnedBuf encapsulates a slice that's been borrowed from a JavaScript /// ArrayBuffer object. JavaScript objects can normally be garbage collected, /// but the existence of a PinnedBuf inhibits this until it is dropped. It @@ -173,7 +167,6 @@ pub struct Isolate { pub(crate) shared_ab: v8::Global, pub(crate) js_recv_cb: v8::Global, pub(crate) pending_promise_map: HashMap>, - pub(crate) shared_response_buf: v8::Global, shared_isolate_handle: Arc>>, js_error_create: Arc, needs_init: bool, @@ -205,7 +198,6 @@ impl Drop for Isolate { // self.global_context.reset(scope); self.shared_ab.reset(scope); - self.shared_response_buf.reset(scope); self.last_exception_handle.reset(scope); self.js_recv_cb.reset(scope); for (_key, handle) in self.pending_promise_map.iter_mut() { @@ -333,7 +325,6 @@ impl Isolate { pending_promise_map: HashMap::new(), shared_ab: v8::Global::::new(), js_recv_cb: v8::Global::::new(), - shared_response_buf: v8::Global::::new(), snapshot_creator: maybe_snapshot_creator, snapshot: load_snapshot, has_snapshotted: false, @@ -639,11 +630,11 @@ impl Isolate { let maybe_value = if !buf.is_empty() { let op_id: v8::Local = v8::Integer::new(scope, op_id as i32).into(); - let buf: v8::Local = - unsafe { bindings::slice_to_uint8array(self, scope, &buf) }.into(); + let ui8: v8::Local = + bindings::boxed_slice_to_uint8array(scope, buf).into(); js_recv_cb .unwrap() - .call(scope, context, global, &[op_id, buf]) + .call(scope, context, global, &[op_id, ui8]) } else { js_recv_cb.unwrap().call(scope, context, global, &[]) }; @@ -680,7 +671,6 @@ impl Isolate { let mut hs = v8::HandleScope::new(locker.enter()); let scope = hs.enter(); self.global_context.reset(scope); - self.shared_response_buf.reset(scope); let snapshot_creator = self.snapshot_creator.as_mut().unwrap(); let snapshot = snapshot_creator