[builtins] Access external references through constants table

External references are process-specific and thus need to be accessed
through an indirection (or reloc'd by the linker). This CL moves all
used external references to the builtins constants table and rewrites
accesses to load from there.

In the future, this could be made more efficient by removing levels of
indirection or using the native linker.

Bug: v8:6666
Change-Id: I63491670549654edeb59c60bb833acfdc5a48495
Reviewed-on: https://chromium-review.googlesource.com/939783
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51646}
This commit is contained in:
jgruber 2018-02-28 15:36:54 +01:00 committed by Commit Bot
parent 86b4b5345a
commit 184721e23f
4 changed files with 70 additions and 2 deletions

View File

@ -44,6 +44,25 @@ uint32_t BuiltinsConstantsTableBuilder::AddObject(Handle<Object> object) {
}
}
uint32_t BuiltinsConstantsTableBuilder::AddExternalReference(
ExternalReference reference) {
// Not yet finalized.
DCHECK_EQ(isolate_->heap()->empty_fixed_array(),
isolate_->heap()->builtins_constants_table());
auto maybe_entry = external_reference_map_.find(reference.address());
if (maybe_entry == external_reference_map_.end()) {
HandleScope handle_scope(isolate_);
Handle<Foreign> object =
isolate_->factory()->NewForeign(reference.address(), TENURED);
uint32_t index = AddObject(object);
external_reference_map_.emplace(reference.address(), index);
return index;
} else {
return maybe_entry->second;
}
}
void BuiltinsConstantsTableBuilder::Finalize() {
HandleScope handle_scope(isolate_);

View File

@ -5,6 +5,8 @@
#ifndef V8_BUILTINS_CONSTANTS_TABLE_BUILDER_H_
#define V8_BUILTINS_CONSTANTS_TABLE_BUILDER_H_
#include <unordered_map>
#include "src/allocation.h"
#include "src/base/macros.h"
#include "src/handles.h"
@ -24,10 +26,14 @@ class BuiltinsConstantsTableBuilder final {
public:
explicit BuiltinsConstantsTableBuilder(Isolate* isolate);
// Returns the index within the builtins constants list for the given object,
// possibly adding the object to the cache. Objects are deduplicated.
// Returns the index within the builtins constants table for the given
// object, possibly adding the object to the table. Objects are deduplicated.
uint32_t AddObject(Handle<Object> object);
// External references can also be added, and end up as a Foreign object in
// the constants table.
uint32_t AddExternalReference(ExternalReference reference);
// Should be called after all affected code (e.g. builtins and bytecode
// handlers) has been generated.
void Finalize();
@ -39,6 +45,10 @@ class BuiltinsConstantsTableBuilder final {
typedef IdentityMap<uint32_t, FreeStoreAllocationPolicy> ConstantsMap;
ConstantsMap map_;
// Maps external references to corresponding indices within the constants
// list. Note that external references are also in map_ as Foreign objects.
std::unordered_map<Address, uint32_t> external_reference_map_;
DISALLOW_COPY_AND_ASSIGN(BuiltinsConstantsTableBuilder)
};

View File

@ -260,6 +260,39 @@ TNode<HeapObject> CodeAssembler::LookupConstant(Handle<HeapObject> object) {
return UncheckedCast<HeapObject>(
Load(MachineType::AnyTagged(), builtins_constants_table, offset));
}
// External references are stored on the builtins constants list, wrapped in
// Foreign objects.
// TODO(jgruber,v8:6666): A more efficient solution.
TNode<ExternalReference> CodeAssembler::LookupExternalReference(
ExternalReference reference) {
DCHECK(isolate()->serializer_enabled());
// Ensure the given object is in the builtins constants table and fetch its
// index.
BuiltinsConstantsTableBuilder* builder =
isolate()->builtins_constants_table_builder();
uint32_t index = builder->AddExternalReference(reference);
// The builtins constants table is loaded through the root register on all
// supported platforms. This is checked by the
// VerifyBuiltinsIsolateIndependence cctest, which disallows embedded objects
// in isolate-independent builtins.
DCHECK(isolate()->heap()->RootCanBeTreatedAsConstant(
Heap::kBuiltinsConstantsTableRootIndex));
TNode<FixedArray> builtins_constants_table = UncheckedCast<FixedArray>(
LoadRoot(Heap::kBuiltinsConstantsTableRootIndex));
// Generate the lookup.
const int32_t header_size = FixedArray::kHeaderSize - kHeapObjectTag;
TNode<IntPtrT> offset = IntPtrConstant(header_size + kPointerSize * index);
TNode<Object> foreign = UncheckedCast<HeapObject>(
Load(MachineType::AnyTagged(), builtins_constants_table, offset));
return UncheckedCast<ExternalReference>(
Load(MachineType::Pointer(), foreign,
IntPtrConstant(Foreign::kForeignAddressOffset - kHeapObjectTag)));
}
#endif // V8_EMBEDDED_BUILTINS
TNode<Int32T> CodeAssembler::Int32Constant(int32_t value) {
@ -319,6 +352,11 @@ TNode<Oddball> CodeAssembler::BooleanConstant(bool value) {
TNode<ExternalReference> CodeAssembler::ExternalConstant(
ExternalReference address) {
#ifdef V8_EMBEDDED_BUILTINS
if (ShouldLoadConstantsFromRootList()) {
return LookupExternalReference(address);
}
#endif // V8_EMBEDDED_BUILTINS
return UncheckedCast<ExternalReference>(
raw_assembler()->ExternalConstant(address));
}

View File

@ -652,6 +652,7 @@ class V8_EXPORT_PRIVATE CodeAssembler {
}
TNode<HeapObject> LookupConstant(Handle<HeapObject> object);
TNode<ExternalReference> LookupExternalReference(ExternalReference reference);
#endif
// Constants.