Commit f468e8e7 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[nci] Verify native context independent code

After native-context-independent codegen, verify that the resulting
Code object does not embed any nc-dependent objects, and that no code
dependencies have been created.

Bug: v8:8888
Change-Id: I894e74b27e86e7727ff17aa0dbfdd908373a5e55
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2284498
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68757}
parent f44900d2
...@@ -328,6 +328,13 @@ class RelocInfo { ...@@ -328,6 +328,13 @@ class RelocInfo {
static const int kApplyMask; // Modes affected by apply. Depends on arch. static const int kApplyMask; // Modes affected by apply. Depends on arch.
static constexpr int AllRealModesMask() {
constexpr Mode kFirstUnrealRelocMode =
static_cast<Mode>(RelocInfo::LAST_REAL_RELOC_MODE + 1);
return (ModeMask(kFirstUnrealRelocMode) - 1) &
~(ModeMask(RelocInfo::FIRST_REAL_RELOC_MODE) - 1);
}
static int EmbeddedObjectModeMask() { static int EmbeddedObjectModeMask() {
return ModeMask(RelocInfo::FULL_EMBEDDED_OBJECT) | return ModeMask(RelocInfo::FULL_EMBEDDED_OBJECT) |
ModeMask(RelocInfo::COMPRESSED_EMBEDDED_OBJECT); ModeMask(RelocInfo::COMPRESSED_EMBEDDED_OBJECT);
......
...@@ -513,6 +513,11 @@ MaybeHandle<Code> CodeGenerator::FinalizeCode() { ...@@ -513,6 +513,11 @@ MaybeHandle<Code> CodeGenerator::FinalizeCode() {
return MaybeHandle<Code>(); return MaybeHandle<Code>();
} }
// TODO(jgruber,v8:8888): Turn this into a DCHECK once confidence is
// high that the implementation is complete.
CHECK_IMPLIES(info()->native_context_independent(),
code->IsNativeContextIndependent(isolate()));
isolate()->counters()->total_compiled_code_size()->Increment( isolate()->counters()->total_compiled_code_size()->Increment(
code->raw_instruction_size()); code->raw_instruction_size());
......
...@@ -505,6 +505,12 @@ bool CompilationDependencies::AreValid() const { ...@@ -505,6 +505,12 @@ bool CompilationDependencies::AreValid() const {
} }
bool CompilationDependencies::Commit(Handle<Code> code) { bool CompilationDependencies::Commit(Handle<Code> code) {
// Dependencies are context-dependent. In the future it may be possible to
// restore them in the consumer native context, but for now they are
// disabled.
CHECK_IMPLIES(broker_->is_native_context_independent(),
dependencies_.empty());
for (auto dep : dependencies_) { for (auto dep : dependencies_) {
if (!dep->IsValid()) { if (!dep->IsValid()) {
dependencies_.clear(); dependencies_.clear();
......
...@@ -3760,6 +3760,10 @@ Reduction JSCallReducer::ReduceCallOrConstructWithArrayLikeOrSpread( ...@@ -3760,6 +3760,10 @@ Reduction JSCallReducer::ReduceCallOrConstructWithArrayLikeOrSpread(
start_index = formal_parameter_count; start_index = formal_parameter_count;
} }
// TODO(jgruber,v8:8888): Attempt to remove this restriction. The reason it
// currently exists is because we cannot create code dependencies in NCI code.
if (broker()->is_native_context_independent()) return NoChange();
// For call/construct with spread, we need to also install a code // For call/construct with spread, we need to also install a code
// dependency on the array iterator lookup protector cell to ensure // dependency on the array iterator lookup protector cell to ensure
// that no one messed with the %ArrayIteratorPrototype%.next method. // that no one messed with the %ArrayIteratorPrototype%.next method.
......
...@@ -238,15 +238,12 @@ const char* AbstractCode::Kind2String(Kind kind) { ...@@ -238,15 +238,12 @@ const char* AbstractCode::Kind2String(Kind kind) {
} }
bool Code::IsIsolateIndependent(Isolate* isolate) { bool Code::IsIsolateIndependent(Isolate* isolate) {
constexpr int all_real_modes_mask = static constexpr int kModeMask =
(1 << (RelocInfo::LAST_REAL_RELOC_MODE + 1)) - RelocInfo::AllRealModesMask() &
(1 << (RelocInfo::FIRST_REAL_RELOC_MODE - 1)) - 1; ~RelocInfo::ModeMask(RelocInfo::CONST_POOL) &
constexpr int mode_mask = all_real_modes_mask & ~RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) &
~RelocInfo::ModeMask(RelocInfo::CONST_POOL) & ~RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
~RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) & STATIC_ASSERT(kModeMask ==
~RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
STATIC_ASSERT(RelocInfo::LAST_REAL_RELOC_MODE == RelocInfo::VENEER_POOL);
STATIC_ASSERT(mode_mask ==
(RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | (RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::RELATIVE_CODE_TARGET) | RelocInfo::ModeMask(RelocInfo::RELATIVE_CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::COMPRESSED_EMBEDDED_OBJECT) | RelocInfo::ModeMask(RelocInfo::COMPRESSED_EMBEDDED_OBJECT) |
...@@ -258,8 +255,7 @@ bool Code::IsIsolateIndependent(Isolate* isolate) { ...@@ -258,8 +255,7 @@ bool Code::IsIsolateIndependent(Isolate* isolate) {
RelocInfo::ModeMask(RelocInfo::WASM_CALL) | RelocInfo::ModeMask(RelocInfo::WASM_CALL) |
RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL))); RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL)));
bool is_process_independent = true; for (RelocIterator it(*this, kModeMask); !it.done(); it.next()) {
for (RelocIterator it(*this, mode_mask); !it.done(); it.next()) {
#if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_ARM64) || \ #if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_ARM64) || \
defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS) || \ defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS) || \
defined(V8_TARGET_ARCH_S390) || defined(V8_TARGET_ARCH_IA32) defined(V8_TARGET_ARCH_S390) || defined(V8_TARGET_ARCH_IA32)
...@@ -276,10 +272,70 @@ bool Code::IsIsolateIndependent(Isolate* isolate) { ...@@ -276,10 +272,70 @@ bool Code::IsIsolateIndependent(Isolate* isolate) {
if (Builtins::IsIsolateIndependentBuiltin(target)) continue; if (Builtins::IsIsolateIndependentBuiltin(target)) continue;
} }
#endif #endif
is_process_independent = false; return false;
}
return true;
}
// Multiple native contexts live on the same heap, and V8 currently
// draws no clear distinction between native-context-dependent and
// independent objects. A good guideline is "objects embedded into
// bytecode are nc-independent", since bytecode is shared between
// native contexts. Among others, this is the case for ScopeInfo,
// SharedFunctionInfo, String, etc.
bool Code::IsNativeContextIndependent(Isolate* isolate) {
static constexpr int kModeMask =
RelocInfo::AllRealModesMask() &
~RelocInfo::ModeMask(RelocInfo::CONST_POOL) &
~RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) &
~RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) &
~RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) &
~RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) &
~RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) &
~RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
STATIC_ASSERT(kModeMask ==
(RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::RELATIVE_CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::COMPRESSED_EMBEDDED_OBJECT) |
RelocInfo::ModeMask(RelocInfo::FULL_EMBEDDED_OBJECT) |
RelocInfo::ModeMask(RelocInfo::WASM_CALL) |
RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL)));
bool is_independent = true;
for (RelocIterator it(*this, kModeMask); !it.done(); it.next()) {
if (RelocInfo::IsEmbeddedObjectMode(it.rinfo()->rmode())) {
HeapObject o = it.rinfo()->target_object();
// TODO(jgruber,v8:8888): Extend this with further NCI objects,
// and define a more systematic
// IsNativeContextIndependent<T>() predicate.
if (o.IsString()) continue;
if (o.IsScopeInfo()) continue;
if (o.IsHeapNumber()) continue;
if (o.IsBigInt()) continue;
if (o.IsSharedFunctionInfo()) continue;
if (o.IsArrayBoilerplateDescription()) continue;
if (o.IsObjectBoilerplateDescription()) continue;
if (o.IsTemplateObjectDescription()) continue;
if (o.IsFixedArray()) {
// Some uses of FixedArray are valid.
// 1. Passed as arg to %DeclareGlobals, contains only strings
// and SFIs.
// 2. Passed as arg to %DefineClass. No well defined contents.
// .. ?
// TODO(jgruber): Consider assigning dedicated instance
// types instead of assuming fixed arrays are okay.
continue;
}
// Other objects are expected to be context-dependent.
PrintF("Found native-context-dependent object:\n");
o.Print();
o.map().Print();
}
is_independent = false;
} }
return is_process_independent; return is_independent;
} }
bool Code::Inlines(SharedFunctionInfo sfi) { bool Code::Inlines(SharedFunctionInfo sfi) {
......
...@@ -371,6 +371,7 @@ class Code : public HeapObject { ...@@ -371,6 +371,7 @@ class Code : public HeapObject {
inline HandlerTable::CatchPrediction GetBuiltinCatchPrediction(); inline HandlerTable::CatchPrediction GetBuiltinCatchPrediction();
bool IsIsolateIndependent(Isolate* isolate); bool IsIsolateIndependent(Isolate* isolate);
bool IsNativeContextIndependent(Isolate* isolate);
inline bool CanContainWeakObjects(); inline bool CanContainWeakObjects();
......
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