Commit f82ae284 authored by Juliana Franco's avatar Juliana Franco Committed by Commit Bot

Remove the next field from JS functions.

Given that we no longer need to iterate over lists of optimized JS functions 
(c.f. https://chromium-review.googlesource.com/c/v8/v8/+/647596), we can 
remove this field. Thus saving the size of one pointer per function.

Bug: v8:6637
Change-Id: If77951f2eddba33ba350fa9ddf03a4edb3f7c7d8
Reviewed-on: https://chromium-review.googlesource.com/652373Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Juliana Patricia Vicente Franco <jupvfranco@google.com>
Cr-Commit-Position: refs/heads/master@{#47875}
parent 7b53a0e0
......@@ -195,8 +195,6 @@ void AsyncBuiltinsAssembler::InitializeNativeClosure(Node* context,
Node* const code =
LoadObjectField(shared_info, SharedFunctionInfo::kCodeOffset);
StoreObjectFieldNoWriteBarrier(function, JSFunction::kCodeOffset, code);
StoreObjectFieldRoot(function, JSFunction::kNextFunctionLinkOffset,
Heap::kUndefinedValueRootIndex);
}
Node* AsyncBuiltinsAssembler::CreateUnwrapClosure(Node* native_context,
......
......@@ -189,9 +189,6 @@ Node* ConstructorBuiltinsAssembler::EmitFastNewClosure(Node* shared_info,
isolate->builtins()->builtin(Builtins::kCompileLazy));
Node* lazy_builtin = HeapConstant(lazy_builtin_handle);
StoreObjectFieldNoWriteBarrier(result, JSFunction::kCodeOffset, lazy_builtin);
StoreObjectFieldNoWriteBarrier(result, JSFunction::kNextFunctionLinkOffset,
UndefinedConstant());
return result;
}
......
......@@ -9861,9 +9861,6 @@ Node* CodeStubAssembler::AllocateFunctionWithMapAndContext(Node* map,
shared_info);
StoreObjectFieldNoWriteBarrier(fun, JSFunction::kContextOffset, context);
StoreObjectFieldNoWriteBarrier(fun, JSFunction::kCodeOffset, code);
StoreObjectFieldRoot(fun, JSFunction::kNextFunctionLinkOffset,
Heap::kUndefinedValueRootIndex);
return fun;
}
......
......@@ -173,16 +173,6 @@ FieldAccess AccessBuilder::ForJSFunctionCode() {
return access;
}
// static
FieldAccess AccessBuilder::ForJSFunctionNextFunctionLink() {
FieldAccess access = {
kTaggedBase, JSFunction::kNextFunctionLinkOffset,
Handle<Name>(), MaybeHandle<Map>(),
Type::Any(), MachineType::AnyTagged(),
kPointerWriteBarrier};
return access;
}
// static
FieldAccess AccessBuilder::ForJSBoundFunctionBoundTargetFunction() {
FieldAccess access = {
......
......@@ -73,9 +73,6 @@ class V8_EXPORT_PRIVATE AccessBuilder final
// Provides access to JSFunction::code() field.
static FieldAccess ForJSFunctionCode();
// Provides access to JSFunction::next_function_link() field.
static FieldAccess ForJSFunctionNextFunctionLink();
// Provides access to JSBoundFunction::bound_target_function() field.
static FieldAccess ForJSBoundFunctionBoundTargetFunction();
......
......@@ -1488,7 +1488,6 @@ Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
function->set_context(*context_or_undefined);
function->set_prototype_or_initial_map(*the_hole_value());
function->set_feedback_vector_cell(*undefined_cell());
function->set_next_function_link(*undefined_value(), SKIP_WRITE_BARRIER);
isolate()->heap()->InitializeJSObjectBody(*function, *map, JSFunction::kSize);
return function;
}
......
......@@ -83,25 +83,6 @@ static void ClearWeakList(Heap* heap, Object* list) {
}
}
template <>
struct WeakListVisitor<JSFunction> {
static void SetWeakNext(JSFunction* function, Object* next) {
function->set_next_function_link(next, UPDATE_WEAK_WRITE_BARRIER);
}
static Object* WeakNext(JSFunction* function) {
return function->next_function_link();
}
static int WeakNextOffset() { return JSFunction::kNextFunctionLinkOffset; }
static void VisitLiveObject(Heap*, JSFunction*, WeakObjectRetainer*) {}
static void VisitPhantomObject(Heap*, JSFunction*) {}
};
template <>
struct WeakListVisitor<Code> {
static void SetWeakNext(Code* code, Object* next) {
......
......@@ -108,13 +108,8 @@ class JSObject::FastBodyDescriptor final : public BodyDescriptorBase {
}
};
// Iterates the function object according to the visiting policy.
template <JSFunction::BodyVisitingPolicy body_visiting_policy>
class JSFunction::BodyDescriptorImpl final : public BodyDescriptorBase {
class JSFunction::BodyDescriptor final : public BodyDescriptorBase {
public:
STATIC_ASSERT(kNonWeakFieldsEndOffset == kNextFunctionLinkOffset);
STATIC_ASSERT(kNextFunctionLinkOffset + kPointerSize == kSize);
static bool IsValidSlot(HeapObject* obj, int offset) {
if (offset < kSize) return true;
return IsValidSlotImpl(obj, offset);
......@@ -123,10 +118,7 @@ class JSFunction::BodyDescriptorImpl final : public BodyDescriptorBase {
template <typename ObjectVisitor>
static inline void IterateBody(HeapObject* obj, int object_size,
ObjectVisitor* v) {
IteratePointers(obj, kPropertiesOrHashOffset, kNonWeakFieldsEndOffset, v);
if (body_visiting_policy == kIgnoreWeakness) {
IteratePointers(obj, kNextFunctionLinkOffset, kSize, v);
}
IteratePointers(obj, kPropertiesOrHashOffset, kSize, v);
IterateBodyImpl(obj, kSize, object_size, v);
}
......
......@@ -702,11 +702,7 @@ void JSBoundFunction::JSBoundFunctionVerify() {
void JSFunction::JSFunctionVerify() {
CHECK(IsJSFunction());
VerifyObjectField(kPrototypeOrInitialMapOffset);
VerifyObjectField(kNextFunctionLinkOffset);
CHECK(code()->IsCode());
CHECK(next_function_link() == NULL ||
next_function_link()->IsUndefined(GetIsolate()) ||
next_function_link()->IsJSFunction());
CHECK(map()->is_callable());
}
......
......@@ -4275,7 +4275,6 @@ ACCESSORS(JSBoundFunction, bound_arguments, FixedArray, kBoundArgumentsOffset)
ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
ACCESSORS(JSFunction, feedback_vector_cell, Cell, kFeedbackVectorOffset)
ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
ACCESSORS(JSGlobalObject, native_context, Context, kNativeContextOffset)
ACCESSORS(JSGlobalObject, global_proxy, JSObject, kGlobalProxyOffset)
......
......@@ -4994,11 +4994,6 @@ class JSFunction: public JSObject {
// Returns if this function has been compiled to native code yet.
inline bool is_compiled();
// [next_function_link]: Links functions into various lists, e.g. the list
// of optimized functions hanging off the native_context. Treated weakly
// by the garbage collector.
DECL_ACCESSORS(next_function_link, Object)
// Prints the name of the function using PrintF.
void PrintName(FILE* out = stdout);
......@@ -5014,13 +5009,8 @@ class JSFunction: public JSObject {
int requested_in_object_properties,
int* instance_size,
int* in_object_properties);
enum BodyVisitingPolicy { kIgnoreWeakness, kRespectWeakness };
// Iterates the function object according to the visiting policy.
template <BodyVisitingPolicy>
class BodyDescriptorImpl;
typedef BodyDescriptorImpl<kIgnoreWeakness> BodyDescriptor;
typedef BodyDescriptorImpl<kRespectWeakness> BodyDescriptorWeak;
class BodyDescriptor;
// Dispatched behavior.
DECL_PRINTER(JSFunction)
......@@ -5054,9 +5044,7 @@ class JSFunction: public JSObject {
static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize;
static const int kFeedbackVectorOffset = kContextOffset + kPointerSize;
static const int kCodeOffset = kFeedbackVectorOffset + kPointerSize;
static const int kNonWeakFieldsEndOffset = kCodeOffset + kPointerSize;
static const int kNextFunctionLinkOffset = kNonWeakFieldsEndOffset;
static const int kSize = kNextFunctionLinkOffset + kPointerSize;
static const int kSize = kCodeOffset + kPointerSize;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction);
......
......@@ -957,11 +957,6 @@ void V8HeapExplorer::ExtractJSObjectReferences(
TagCodeObject(js_fun->code());
SetInternalReference(js_fun, entry, "code", js_fun->code(),
JSFunction::kCodeOffset);
// Ensure no new weak references appeared in JSFunction.
STATIC_ASSERT(JSFunction::kNonWeakFieldsEndOffset ==
JSFunction::kNextFunctionLinkOffset);
STATIC_ASSERT(JSFunction::kNextFunctionLinkOffset + kPointerSize
== JSFunction::kSize);
} else if (obj->IsJSGlobalObject()) {
JSGlobalObject* global_obj = JSGlobalObject::cast(obj);
SetInternalReference(global_obj, entry, "native_context",
......@@ -1681,9 +1676,6 @@ bool V8HeapExplorer::IsEssentialHiddenReference(Object* parent,
if (parent->IsAllocationSite() &&
field_offset == AllocationSite::kWeakNextOffset)
return false;
if (parent->IsJSFunction() &&
field_offset == JSFunction::kNextFunctionLinkOffset)
return false;
if (parent->IsCode() && field_offset == Code::kNextCodeLinkOffset)
return false;
if (parent->IsContext() &&
......
......@@ -163,7 +163,6 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
// Set the code of the target function.
target->ReplaceCode(source_shared->code());
DCHECK(target->next_function_link()->IsUndefined(isolate));
Handle<Context> context(source->context());
target->set_context(*context);
......
......@@ -2265,7 +2265,6 @@ TEST(AllocateFunctionWithMapAndContext) {
CHECK_EQ(isolate->heap()->the_hole_value(), fun->prototype_or_initial_map());
CHECK_EQ(*isolate->promise_resolve_shared_fun(), fun->shared());
CHECK_EQ(isolate->promise_resolve_shared_fun()->code(), fun->code());
CHECK_EQ(isolate->heap()->undefined_value(), fun->next_function_link());
}
TEST(CreatePromiseGetCapabilitiesExecutorContext) {
......
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