Commit c64b52a8 authored by Nico Hartmann's avatar Nico Hartmann Committed by Commit Bot

[sandbox] Wire ExternalString resource through bottleneck

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