[sandbox] Wire ExternalString resource through bottleneck
Bug: v8:10391 Change-Id: Ic92cdaca38c2181427cc12ec5e572d5964afe704 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2152647 Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Nico Hartmann <nicohartmann@chromium.org> Cr-Commit-Position: refs/heads/master@{#67601}
This commit is contained in:
parent
b3b824ba91
commit
c64b52a892
12
include/v8.h
12
include/v8.h
@ -11387,7 +11387,10 @@ String::ExternalStringResource* String::GetExternalStringResource() const {
|
||||
|
||||
ExternalStringResource* result;
|
||||
if (I::IsExternalTwoByteString(I::GetInstanceType(obj))) {
|
||||
void* value = I::ReadRawField<void*>(obj, I::kStringResourceOffset);
|
||||
internal::Isolate* isolate =
|
||||
internal::IsolateFromNeverReadOnlySpaceObject(obj);
|
||||
A value =
|
||||
I::ReadExternalPointerField(isolate, obj, I::kStringResourceOffset);
|
||||
result = reinterpret_cast<String::ExternalStringResource*>(value);
|
||||
} else {
|
||||
result = GetExternalStringResourceSlow();
|
||||
@ -11409,8 +11412,11 @@ String::ExternalStringResourceBase* String::GetExternalStringResourceBase(
|
||||
ExternalStringResourceBase* resource;
|
||||
if (type == I::kExternalOneByteRepresentationTag ||
|
||||
type == I::kExternalTwoByteRepresentationTag) {
|
||||
void* value = I::ReadRawField<void*>(obj, I::kStringResourceOffset);
|
||||
resource = static_cast<ExternalStringResourceBase*>(value);
|
||||
internal::Isolate* isolate =
|
||||
internal::IsolateFromNeverReadOnlySpaceObject(obj);
|
||||
A value =
|
||||
I::ReadExternalPointerField(isolate, obj, I::kStringResourceOffset);
|
||||
resource = reinterpret_cast<ExternalStringResourceBase*>(value);
|
||||
} else {
|
||||
resource = GetExternalStringResourceBaseSlow(encoding_out);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "src/codegen/compiler.h"
|
||||
#include "src/codegen/cpu-features.h"
|
||||
#include "src/common/assert-scope.h"
|
||||
#include "src/common/external-pointer.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/compiler-dispatcher/compiler-dispatcher.h"
|
||||
#include "src/date/date.h"
|
||||
@ -5409,7 +5410,10 @@ String::ExternalStringResource* String::GetExternalStringResourceSlow() const {
|
||||
}
|
||||
|
||||
if (i::StringShape(str).IsExternalTwoByte()) {
|
||||
void* value = I::ReadRawField<void*>(str.ptr(), I::kStringResourceOffset);
|
||||
internal::Isolate* isolate =
|
||||
internal::IsolateFromNeverReadOnlySpaceObject(str.ptr());
|
||||
internal::Address value = I::ReadExternalPointerField(
|
||||
isolate, str.ptr(), I::kStringResourceOffset);
|
||||
return reinterpret_cast<String::ExternalStringResource*>(value);
|
||||
}
|
||||
return nullptr;
|
||||
@ -5431,8 +5435,11 @@ String::ExternalStringResourceBase* String::GetExternalStringResourceBaseSlow(
|
||||
*encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
|
||||
if (i::StringShape(str).IsExternalOneByte() ||
|
||||
i::StringShape(str).IsExternalTwoByte()) {
|
||||
void* value = I::ReadRawField<void*>(string, I::kStringResourceOffset);
|
||||
resource = static_cast<ExternalStringResourceBase*>(value);
|
||||
internal::Isolate* isolate =
|
||||
internal::IsolateFromNeverReadOnlySpaceObject(string);
|
||||
internal::Address value =
|
||||
I::ReadExternalPointerField(isolate, string, I::kStringResourceOffset);
|
||||
resource = reinterpret_cast<ExternalStringResourceBase*>(value);
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
|
@ -378,7 +378,7 @@ void Heap::FinalizeExternalString(String string) {
|
||||
ExternalBackingStoreType::kExternalString,
|
||||
ext_string.ExternalPayloadSize());
|
||||
|
||||
ext_string.DisposeResource();
|
||||
ext_string.DisposeResource(isolate());
|
||||
}
|
||||
|
||||
Address Heap::NewSpaceTop() { return new_space_->top(); }
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef V8_OBJECTS_STRING_INL_H_
|
||||
#define V8_OBJECTS_STRING_INL_H_
|
||||
|
||||
#include "src/common/external-pointer.h"
|
||||
#include "src/objects/string.h"
|
||||
|
||||
#include "src/handles/handles-inl.h"
|
||||
@ -600,12 +601,17 @@ bool ExternalString::is_uncached() const {
|
||||
return (type & kUncachedExternalStringMask) == kUncachedExternalStringTag;
|
||||
}
|
||||
|
||||
Address ExternalString::resource_as_address() {
|
||||
return ReadField<Address>(kResourceOffset);
|
||||
DEF_GETTER(ExternalString, resource_as_address, Address) {
|
||||
ExternalPointer_t encoded_address =
|
||||
ReadField<ExternalPointer_t>(kResourceOffset);
|
||||
return DecodeExternalPointer(isolate, encoded_address);
|
||||
}
|
||||
|
||||
void ExternalString::set_address_as_resource(Address address) {
|
||||
WriteField<Address>(kResourceOffset, address);
|
||||
void ExternalString::set_address_as_resource(Isolate* isolate,
|
||||
Address address) {
|
||||
const ExternalPointer_t encoded_address =
|
||||
EncodeExternalPointer(isolate, address);
|
||||
WriteField<ExternalPointer_t>(kResourceOffset, encoded_address);
|
||||
if (IsExternalOneByteString()) {
|
||||
ExternalOneByteString::cast(*this).update_data_cache();
|
||||
} else {
|
||||
@ -614,29 +620,39 @@ void ExternalString::set_address_as_resource(Address address) {
|
||||
}
|
||||
|
||||
uint32_t ExternalString::resource_as_uint32() {
|
||||
return static_cast<uint32_t>(ReadField<Address>(kResourceOffset));
|
||||
ExternalPointer_t encoded_address =
|
||||
ReadField<ExternalPointer_t>(kResourceOffset);
|
||||
return static_cast<uint32_t>(encoded_address);
|
||||
}
|
||||
|
||||
void ExternalString::set_uint32_as_resource(uint32_t value) {
|
||||
WriteField<Address>(kResourceOffset, value);
|
||||
WriteField<ExternalPointer_t>(kResourceOffset, value);
|
||||
if (is_uncached()) return;
|
||||
WriteField<Address>(kResourceDataOffset, kNullAddress);
|
||||
}
|
||||
|
||||
void ExternalString::DisposeResource() {
|
||||
void ExternalString::DisposeResource(Isolate* isolate) {
|
||||
const ExternalPointer_t encoded_address =
|
||||
ReadField<ExternalPointer_t>(kResourceOffset);
|
||||
v8::String::ExternalStringResourceBase* resource =
|
||||
reinterpret_cast<v8::String::ExternalStringResourceBase*>(
|
||||
ReadField<Address>(ExternalString::kResourceOffset));
|
||||
DecodeExternalPointer(isolate, encoded_address));
|
||||
|
||||
// Dispose of the C++ object if it has not already been disposed.
|
||||
if (resource != nullptr) {
|
||||
resource->Dispose();
|
||||
WriteField<Address>(ExternalString::kResourceOffset, kNullAddress);
|
||||
const ExternalPointer_t encoded_address =
|
||||
EncodeExternalPointer(isolate, kNullAddress);
|
||||
WriteField<ExternalPointer_t>(kResourceOffset, encoded_address);
|
||||
}
|
||||
}
|
||||
|
||||
const ExternalOneByteString::Resource* ExternalOneByteString::resource() {
|
||||
return reinterpret_cast<Resource*>(ReadField<Address>(kResourceOffset));
|
||||
DEF_GETTER(ExternalOneByteString, resource,
|
||||
const ExternalOneByteString::Resource*) {
|
||||
const ExternalPointer_t encoded_address =
|
||||
ReadField<ExternalPointer_t>(kResourceOffset);
|
||||
return reinterpret_cast<Resource*>(
|
||||
DecodeExternalPointer(isolate, encoded_address));
|
||||
}
|
||||
|
||||
void ExternalOneByteString::update_data_cache() {
|
||||
@ -647,7 +663,7 @@ void ExternalOneByteString::update_data_cache() {
|
||||
|
||||
void ExternalOneByteString::SetResource(
|
||||
Isolate* isolate, const ExternalOneByteString::Resource* resource) {
|
||||
set_resource(resource);
|
||||
set_resource(isolate, resource);
|
||||
size_t new_payload = resource == nullptr ? 0 : resource->length();
|
||||
if (new_payload > 0) {
|
||||
isolate->heap()->UpdateExternalString(*this, 0, new_payload);
|
||||
@ -655,8 +671,10 @@ void ExternalOneByteString::SetResource(
|
||||
}
|
||||
|
||||
void ExternalOneByteString::set_resource(
|
||||
const ExternalOneByteString::Resource* resource) {
|
||||
WriteField<Address>(kResourceOffset, reinterpret_cast<Address>(resource));
|
||||
Isolate* isolate, const ExternalOneByteString::Resource* resource) {
|
||||
const ExternalPointer_t encoded_address =
|
||||
EncodeExternalPointer(isolate, reinterpret_cast<Address>(resource));
|
||||
WriteField<ExternalPointer_t>(kResourceOffset, encoded_address);
|
||||
if (resource != nullptr) update_data_cache();
|
||||
}
|
||||
|
||||
@ -669,8 +687,12 @@ uint8_t ExternalOneByteString::Get(int index) {
|
||||
return GetChars()[index];
|
||||
}
|
||||
|
||||
const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
|
||||
return reinterpret_cast<Resource*>(ReadField<Address>(kResourceOffset));
|
||||
DEF_GETTER(ExternalTwoByteString, resource,
|
||||
const ExternalTwoByteString::Resource*) {
|
||||
const ExternalPointer_t encoded_address =
|
||||
ReadField<ExternalPointer_t>(kResourceOffset);
|
||||
return reinterpret_cast<Resource*>(
|
||||
DecodeExternalPointer(isolate, encoded_address));
|
||||
}
|
||||
|
||||
void ExternalTwoByteString::update_data_cache() {
|
||||
@ -681,7 +703,7 @@ void ExternalTwoByteString::update_data_cache() {
|
||||
|
||||
void ExternalTwoByteString::SetResource(
|
||||
Isolate* isolate, const ExternalTwoByteString::Resource* resource) {
|
||||
set_resource(resource);
|
||||
set_resource(isolate, resource);
|
||||
size_t new_payload = resource == nullptr ? 0 : resource->length() * 2;
|
||||
if (new_payload > 0) {
|
||||
isolate->heap()->UpdateExternalString(*this, 0, new_payload);
|
||||
@ -689,8 +711,10 @@ void ExternalTwoByteString::SetResource(
|
||||
}
|
||||
|
||||
void ExternalTwoByteString::set_resource(
|
||||
const ExternalTwoByteString::Resource* resource) {
|
||||
WriteField<Address>(kResourceOffset, reinterpret_cast<Address>(resource));
|
||||
Isolate* isolate, const ExternalTwoByteString::Resource* resource) {
|
||||
const ExternalPointer_t encoded_address =
|
||||
EncodeExternalPointer(isolate, reinterpret_cast<Address>(resource));
|
||||
WriteField<ExternalPointer_t>(kResourceOffset, encoded_address);
|
||||
if (resource != nullptr) update_data_cache();
|
||||
}
|
||||
|
||||
|
@ -716,13 +716,13 @@ class ExternalString : public String {
|
||||
int ExternalPayloadSize() const;
|
||||
|
||||
// Used in the serializer/deserializer.
|
||||
inline Address resource_as_address();
|
||||
inline void set_address_as_resource(Address address);
|
||||
DECL_GETTER(resource_as_address, Address)
|
||||
inline void set_address_as_resource(Isolate* isolate, Address address);
|
||||
inline uint32_t resource_as_uint32();
|
||||
inline void set_uint32_as_resource(uint32_t value);
|
||||
|
||||
// Disposes string's resource object if it has not already been disposed.
|
||||
inline void DisposeResource();
|
||||
inline void DisposeResource(Isolate* isolate);
|
||||
|
||||
STATIC_ASSERT(kResourceOffset == Internals::kStringResourceOffset);
|
||||
static const int kSizeOfAllExternalStrings = kHeaderSize;
|
||||
@ -739,13 +739,13 @@ class ExternalOneByteString : public ExternalString {
|
||||
using Resource = v8::String::ExternalOneByteStringResource;
|
||||
|
||||
// The underlying resource.
|
||||
inline const Resource* resource();
|
||||
DECL_GETTER(resource, const Resource*)
|
||||
|
||||
// It is assumed that the previous resource is null. If it is not null, then
|
||||
// it is the responsability of the caller the handle the previous resource.
|
||||
inline void SetResource(Isolate* isolate, const Resource* buffer);
|
||||
// Used only during serialization.
|
||||
inline void set_resource(const Resource* buffer);
|
||||
inline void set_resource(Isolate* isolate, const Resource* buffer);
|
||||
|
||||
// Update the pointer cache to the external character array.
|
||||
// The cached pointer is always valid, as the external character array does =
|
||||
@ -780,13 +780,13 @@ class ExternalTwoByteString : public ExternalString {
|
||||
using Resource = v8::String::ExternalStringResource;
|
||||
|
||||
// The underlying string resource.
|
||||
inline const Resource* resource();
|
||||
DECL_GETTER(resource, const Resource*)
|
||||
|
||||
// It is assumed that the previous resource is null. If it is not null, then
|
||||
// it is the responsability of the caller the handle the previous resource.
|
||||
inline void SetResource(Isolate* isolate, const Resource* buffer);
|
||||
// Used only during serialization.
|
||||
inline void set_resource(const Resource* buffer);
|
||||
inline void set_resource(Isolate* isolate, const Resource* buffer);
|
||||
|
||||
// Update the pointer cache to the external character array.
|
||||
// The cached pointer is always valid, as the external character array does =
|
||||
|
@ -19,7 +19,7 @@ extern class ConsString extends String {
|
||||
@abstract
|
||||
@generateBodyDescriptor
|
||||
extern class ExternalString extends String {
|
||||
resource: RawPtr;
|
||||
resource: ExternalPointer;
|
||||
resource_data: RawPtr;
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,7 @@ HeapObject Deserializer::PostProcessNewObject(HeapObject obj,
|
||||
uint32_t index = string.resource_as_uint32();
|
||||
Address address =
|
||||
static_cast<Address>(isolate_->api_external_references()[index]);
|
||||
string.set_address_as_resource(address);
|
||||
string.set_address_as_resource(isolate_, address);
|
||||
isolate_->heap()->UpdateExternalString(string, 0,
|
||||
string.ExternalPayloadSize());
|
||||
isolate_->heap()->RegisterExternalString(String::cast(obj));
|
||||
|
@ -415,7 +415,7 @@ void Serializer::ObjectSerializer::SerializeExternalString() {
|
||||
DCHECK(reference.is_from_api());
|
||||
string.set_uint32_as_resource(reference.index());
|
||||
SerializeObject();
|
||||
string.set_address_as_resource(resource);
|
||||
string.set_address_as_resource(serializer_->isolate(), resource);
|
||||
} else {
|
||||
SerializeExternalStringAsSequentialString();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user