Commit e4361df0 authored by Igor Sheludko's avatar Igor Sheludko Committed by V8 LUCI CQ

[ext-code-space] Migrate CodeDataContainer::next_code_link to CodeT

... and OPTIMIZED_CODE_LIST and DEOPTIMIZED_CODE_LIST slots of
NativeContext which serve as heads of respective weak lists of Code
objects.

Drive-by: trivial NativeContext methods are moved to contexts-inl.h
header.

Bug: v8:11880
Change-Id: I0f2ca967b2820f84c279fea702bab28829f65d0e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2968416Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75268}
parent 2ef8f917
......@@ -181,7 +181,7 @@ Code Deoptimizer::FindDeoptimizingCode(Address addr) {
NativeContext native_context = function_.context().native_context();
Object element = native_context.DeoptimizedCodeListHead();
while (!element.IsUndefined(isolate)) {
Code code = Code::cast(element);
Code code = FromCodeT(CodeT::cast(element));
CHECK(CodeKindCanDeoptimize(code.kind()));
if (code.contains(isolate, addr)) return code;
element = code.next_code_link();
......@@ -336,7 +336,7 @@ void Deoptimizer::DeoptimizeMarkedCodeForContext(NativeContext native_context) {
Code prev;
Object element = native_context.OptimizedCodeListHead();
while (!element.IsUndefined(isolate)) {
Code code = Code::cast(element);
Code code = FromCodeT(CodeT::cast(element));
CHECK(CodeKindCanDeoptimize(code.kind()));
Object next = code.next_code_link();
......@@ -353,7 +353,7 @@ void Deoptimizer::DeoptimizeMarkedCodeForContext(NativeContext native_context) {
// Move the code to the _deoptimized_ code list.
code.set_next_code_link(native_context.DeoptimizedCodeListHead());
native_context.SetDeoptimizedCodeListHead(code);
native_context.SetDeoptimizedCodeListHead(ToCodeT(code));
} else {
// Not marked; preserve this element.
prev = code;
......@@ -418,7 +418,7 @@ void Deoptimizer::MarkAllCodeForContext(NativeContext native_context) {
Object element = native_context.OptimizedCodeListHead();
Isolate* isolate = native_context.GetIsolate();
while (!element.IsUndefined(isolate)) {
Code code = Code::cast(element);
Code code = FromCodeT(CodeT::cast(element));
CHECK(CodeKindCanDeoptimize(code.kind()));
code.set_marked_for_deoptimization(true);
element = code.next_code_link();
......@@ -694,7 +694,7 @@ int Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) {
NativeContext native_context = NativeContext::cast(context);
Object element = native_context.DeoptimizedCodeListHead();
while (!element.IsUndefined(isolate)) {
Code code = Code::cast(element);
Code code = FromCodeT(CodeT::cast(element));
DCHECK(CodeKindCanDeoptimize(code.kind()));
if (!code.marked_for_deoptimization()) {
length++;
......
......@@ -968,7 +968,7 @@ void PropertyCell::PropertyCellVerify(Isolate* isolate) {
void CodeDataContainer::CodeDataContainerVerify(Isolate* isolate) {
CHECK(IsCodeDataContainer());
VerifyObjectField(isolate, kNextCodeLinkOffset);
CHECK(next_code_link().IsCode() || next_code_link().IsUndefined(isolate));
CHECK(next_code_link().IsCodeT() || next_code_link().IsUndefined(isolate));
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
if (raw_code() != Smi::zero()) {
CHECK_EQ(code().InstructionStart(), code_entry_point());
......
......@@ -85,32 +85,31 @@ static void ClearWeakList(Heap* heap, Object list) {
}
template <>
struct WeakListVisitor<Code> {
static void SetWeakNext(Code code, Object next) {
code.code_data_container(kAcquireLoad)
.set_next_code_link(next, UPDATE_WEAK_WRITE_BARRIER);
struct WeakListVisitor<CodeT> {
static void SetWeakNext(CodeT code, Object next) {
CodeDataContainerFromCodeT(code).set_next_code_link(
next, UPDATE_WEAK_WRITE_BARRIER);
}
static Object WeakNext(Code code) {
return code.code_data_container(kAcquireLoad).next_code_link();
static Object WeakNext(CodeT code) {
return CodeDataContainerFromCodeT(code).next_code_link();
}
static HeapObject WeakNextHolder(Code code) {
return code.code_data_container(kAcquireLoad);
static HeapObject WeakNextHolder(CodeT code) {
return CodeDataContainerFromCodeT(code);
}
static int WeakNextOffset() { return CodeDataContainer::kNextCodeLinkOffset; }
static void VisitLiveObject(Heap*, Code, WeakObjectRetainer*) {}
static void VisitLiveObject(Heap*, CodeT, WeakObjectRetainer*) {}
static void VisitPhantomObject(Heap* heap, Code code) {
static void VisitPhantomObject(Heap* heap, CodeT code) {
// Even though the code is dying, its code_data_container can still be
// alive. Clear the next_code_link slot to avoid a dangling pointer.
SetWeakNext(code, ReadOnlyRoots(heap).undefined_value());
}
};
template <>
struct WeakListVisitor<Context> {
static void SetWeakNext(Context context, Object next) {
......@@ -139,8 +138,9 @@ struct WeakListVisitor<Context> {
}
// Code objects are always allocated in Code space, we do not have to
// visit them during scavenges.
DoWeakList<Code>(heap, context, retainer, Context::OPTIMIZED_CODE_LIST);
DoWeakList<Code>(heap, context, retainer, Context::DEOPTIMIZED_CODE_LIST);
DoWeakList<CodeT>(heap, context, retainer, Context::OPTIMIZED_CODE_LIST);
DoWeakList<CodeT>(heap, context, retainer,
Context::DEOPTIMIZED_CODE_LIST);
}
}
......@@ -162,8 +162,8 @@ struct WeakListVisitor<Context> {
}
static void VisitPhantomObject(Heap* heap, Context context) {
ClearWeakList<Code>(heap, context.get(Context::OPTIMIZED_CODE_LIST));
ClearWeakList<Code>(heap, context.get(Context::DEOPTIMIZED_CODE_LIST));
ClearWeakList<CodeT>(heap, context.get(Context::OPTIMIZED_CODE_LIST));
ClearWeakList<CodeT>(heap, context.get(Context::DEOPTIMIZED_CODE_LIST));
}
};
......
......@@ -378,7 +378,8 @@ Code Code::OptimizedCodeIterator::Next() {
// Exhausted contexts.
return Code();
}
current_code_ = next.IsUndefined(isolate_) ? Code() : Code::cast(next);
current_code_ =
next.IsUndefined(isolate_) ? Code() : FromCodeT(CodeT::cast(next));
} while (current_code_.is_null());
DCHECK(CodeKindCanDeoptimize(current_code_.kind()));
return current_code_;
......
......@@ -294,6 +294,22 @@ OSROptimizedCodeCache NativeContext::GetOSROptimizedCodeCache() {
return OSROptimizedCodeCache::cast(osr_code_cache());
}
void NativeContext::SetOptimizedCodeListHead(Object head) {
set(OPTIMIZED_CODE_LIST, head, UPDATE_WEAK_WRITE_BARRIER, kReleaseStore);
}
Object NativeContext::OptimizedCodeListHead() {
return get(OPTIMIZED_CODE_LIST);
}
void NativeContext::SetDeoptimizedCodeListHead(Object head) {
set(DEOPTIMIZED_CODE_LIST, head, UPDATE_WEAK_WRITE_BARRIER, kReleaseStore);
}
Object NativeContext::DeoptimizedCodeListHead() {
return get(DEOPTIMIZED_CODE_LIST);
}
OBJECT_CONSTRUCTORS_IMPL(NativeContext, Context)
} // namespace internal
......
......@@ -408,24 +408,9 @@ Handle<Object> Context::Lookup(Handle<Context> context, Handle<String> name,
void NativeContext::AddOptimizedCode(Code code) {
DCHECK(CodeKindCanDeoptimize(code.kind()));
DCHECK(code.next_code_link().IsUndefined());
code.set_next_code_link(get(OPTIMIZED_CODE_LIST));
set(OPTIMIZED_CODE_LIST, code, UPDATE_WEAK_WRITE_BARRIER, kReleaseStore);
}
void NativeContext::SetOptimizedCodeListHead(Object head) {
set(OPTIMIZED_CODE_LIST, head, UPDATE_WEAK_WRITE_BARRIER, kReleaseStore);
}
Object NativeContext::OptimizedCodeListHead() {
return get(OPTIMIZED_CODE_LIST);
}
void NativeContext::SetDeoptimizedCodeListHead(Object head) {
set(DEOPTIMIZED_CODE_LIST, head, UPDATE_WEAK_WRITE_BARRIER, kReleaseStore);
}
Object NativeContext::DeoptimizedCodeListHead() {
return get(DEOPTIMIZED_CODE_LIST);
code.set_next_code_link(OptimizedCodeListHead());
set(OPTIMIZED_CODE_LIST, ToCodeT(code), UPDATE_WEAK_WRITE_BARRIER,
kReleaseStore);
}
Handle<Object> Context::ErrorMessageForCodeGenerationFromStrings() {
......
......@@ -729,10 +729,10 @@ class NativeContext : public Context {
// The native context stores a list of all optimized code and a list of all
// deoptimized code, which are needed by the deoptimizer.
V8_EXPORT_PRIVATE void AddOptimizedCode(Code code);
void SetOptimizedCodeListHead(Object head);
Object OptimizedCodeListHead();
void SetDeoptimizedCodeListHead(Object head);
Object DeoptimizedCodeListHead();
inline void SetOptimizedCodeListHead(Object head);
inline Object OptimizedCodeListHead();
inline void SetDeoptimizedCodeListHead(Object head);
inline Object DeoptimizedCodeListHead();
inline OSROptimizedCodeCache GetOSROptimizedCodeCache();
......
......@@ -1053,13 +1053,13 @@ void V8HeapExplorer::ExtractContextReferences(HeapEntry* entry,
FixedArray::OffsetOfElementAt(index));
}
SetWeakReference(
entry, "optimized_code_list", context.get(Context::OPTIMIZED_CODE_LIST),
FixedArray::OffsetOfElementAt(Context::OPTIMIZED_CODE_LIST));
SetWeakReference(entry, "optimized_code_list",
context.get(Context::OPTIMIZED_CODE_LIST),
Context::OffsetOfElementAt(Context::OPTIMIZED_CODE_LIST));
SetWeakReference(
entry, "deoptimized_code_list",
context.get(Context::DEOPTIMIZED_CODE_LIST),
FixedArray::OffsetOfElementAt(Context::DEOPTIMIZED_CODE_LIST));
Context::OffsetOfElementAt(Context::DEOPTIMIZED_CODE_LIST));
STATIC_ASSERT(Context::OPTIMIZED_CODE_LIST == Context::FIRST_WEAK_SLOT);
STATIC_ASSERT(Context::NEXT_CONTEXT_LINK + 1 ==
Context::NATIVE_CONTEXT_SLOTS);
......
......@@ -4338,9 +4338,9 @@ static Handle<JSFunction> OptimizeDummyFunction(v8::Isolate* isolate,
static int GetCodeChainLength(Code code) {
int result = 0;
while (code.next_code_link().IsCode()) {
while (code.next_code_link().IsCodeT()) {
result++;
code = Code::cast(code.next_code_link());
code = FromCodeT(CodeT::cast(code.next_code_link()));
}
return result;
}
......@@ -4364,7 +4364,7 @@ TEST(NextCodeLinkIsWeak) {
OptimizeDummyFunction(CcTest::isolate(), "mortal");
Handle<JSFunction> immortal =
OptimizeDummyFunction(CcTest::isolate(), "immortal");
CHECK_EQ(immortal->code().next_code_link(), mortal->code());
CHECK_EQ(immortal->code().next_code_link(), ToCodeT(mortal->code()));
code_chain_length_before = GetCodeChainLength(immortal->code());
// Keep the immortal code and let the mortal code die.
code = scope.CloseAndEscape(Handle<Code>(immortal->code(), isolate));
......@@ -4392,7 +4392,7 @@ TEST(NextCodeLinkInCodeDataContainerIsCleared) {
OptimizeDummyFunction(CcTest::isolate(), "mortal1");
Handle<JSFunction> mortal2 =
OptimizeDummyFunction(CcTest::isolate(), "mortal2");
CHECK_EQ(mortal2->code().next_code_link(), mortal1->code());
CHECK_EQ(mortal2->code().next_code_link(), ToCodeT(mortal1->code()));
code_data_container = scope.CloseAndEscape(Handle<CodeDataContainer>(
mortal2->code().code_data_container(kAcquireLoad), isolate));
CompileRun("mortal1 = null; mortal2 = null;");
......@@ -4434,7 +4434,8 @@ TEST(NextCodeLinkIsWeak2) {
if (!isolate->use_optimizer()) return;
HandleScope outer_scope(heap->isolate());
CcTest::CollectAllAvailableGarbage();
Handle<Context> context(Context::cast(heap->native_contexts_list()), isolate);
Handle<NativeContext> context(
NativeContext::cast(heap->native_contexts_list()), isolate);
Handle<Code> new_head;
Handle<Object> old_head(context->get(Context::OPTIMIZED_CODE_LIST), isolate);
{
......@@ -4442,8 +4443,8 @@ TEST(NextCodeLinkIsWeak2) {
Handle<Code> immortal = DummyOptimizedCode(isolate);
Handle<Code> mortal = DummyOptimizedCode(isolate);
mortal->set_next_code_link(*old_head);
immortal->set_next_code_link(*mortal);
context->set(Context::OPTIMIZED_CODE_LIST, *immortal);
immortal->set_next_code_link(ToCodeT(*mortal));
context->SetOptimizedCodeListHead(ToCodeT(*immortal));
new_head = scope.CloseAndEscape(immortal);
}
CcTest::CollectAllAvailableGarbage();
......
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