Bring back the js-function-inl.h inline header
This is a manual revert of 67cdacd
. Experiments have shown that inline
headers do bring real benefits and we won't be proceeding with inline
header removal.
Bug: v8:10749
Change-Id: Icd3d0b3926d0b7a24edb19d9f177e9c8818abe09
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2412174
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69915}
This commit is contained in:
parent
64610bda59
commit
c417a08d02
2
BUILD.gn
2
BUILD.gn
@ -1063,6 +1063,7 @@ action("postmortem-metadata") {
|
||||
"src/objects/js-array-buffer-inl.h",
|
||||
"src/objects/js-array.h",
|
||||
"src/objects/js-array-inl.h",
|
||||
"src/objects/js-function-inl.h",
|
||||
"src/objects/js-function.cc",
|
||||
"src/objects/js-function.h",
|
||||
"src/objects/js-objects.cc",
|
||||
@ -2874,6 +2875,7 @@ v8_source_set("v8_base_without_compiler") {
|
||||
"src/objects/js-display-names-inl.h",
|
||||
"src/objects/js-display-names.cc",
|
||||
"src/objects/js-display-names.h",
|
||||
"src/objects/js-function-inl.h",
|
||||
"src/objects/js-function.cc",
|
||||
"src/objects/js-function.h",
|
||||
"src/objects/js-generator-inl.h",
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "src/interpreter/interpreter.h"
|
||||
#include "src/logging/log-inl.h"
|
||||
#include "src/objects/feedback-cell-inl.h"
|
||||
#include "src/objects/js-function-inl.h"
|
||||
#include "src/objects/map.h"
|
||||
#include "src/objects/object-list-macros.h"
|
||||
#include "src/objects/shared-function-info.h"
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "src/execution/protectors.h"
|
||||
#include "src/handles/handles-inl.h"
|
||||
#include "src/objects/allocation-site-inl.h"
|
||||
#include "src/objects/js-function-inl.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
#include "src/zone/zone-handle-set.h"
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "src/objects/contexts.h"
|
||||
#include "src/objects/dictionary-inl.h"
|
||||
#include "src/objects/fixed-array-inl.h"
|
||||
#include "src/objects/js-function-inl.h"
|
||||
#include "src/objects/js-objects-inl.h"
|
||||
#include "src/objects/map-inl.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
|
304
src/objects/js-function-inl.h
Normal file
304
src/objects/js-function-inl.h
Normal file
@ -0,0 +1,304 @@
|
||||
// Copyright 2020 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_OBJECTS_JS_FUNCTION_INL_H_
|
||||
#define V8_OBJECTS_JS_FUNCTION_INL_H_
|
||||
|
||||
#include "src/codegen/compiler.h"
|
||||
#include "src/diagnostics/code-tracer.h"
|
||||
#include "src/heap/heap-inl.h"
|
||||
#include "src/ic/ic.h"
|
||||
#include "src/init/bootstrapper.h"
|
||||
#include "src/objects/feedback-cell-inl.h"
|
||||
#include "src/objects/js-function.h"
|
||||
#include "src/strings/string-builder-inl.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
#include "src/objects/object-macros.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(JSFunctionOrBoundFunction)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(JSBoundFunction)
|
||||
OBJECT_CONSTRUCTORS_IMPL(JSFunction, JSFunctionOrBoundFunction)
|
||||
|
||||
CAST_ACCESSOR(JSFunction)
|
||||
|
||||
ACCESSORS(JSFunction, raw_feedback_cell, FeedbackCell, kFeedbackCellOffset)
|
||||
|
||||
FeedbackVector JSFunction::feedback_vector() const {
|
||||
DCHECK(has_feedback_vector());
|
||||
return FeedbackVector::cast(raw_feedback_cell().value());
|
||||
}
|
||||
|
||||
ClosureFeedbackCellArray JSFunction::closure_feedback_cell_array() const {
|
||||
DCHECK(has_closure_feedback_cell_array());
|
||||
return ClosureFeedbackCellArray::cast(raw_feedback_cell().value());
|
||||
}
|
||||
|
||||
bool JSFunction::HasOptimizationMarker() {
|
||||
return has_feedback_vector() && feedback_vector().has_optimization_marker();
|
||||
}
|
||||
|
||||
void JSFunction::ClearOptimizationMarker() {
|
||||
DCHECK(has_feedback_vector());
|
||||
feedback_vector().ClearOptimizationMarker();
|
||||
}
|
||||
|
||||
bool JSFunction::ChecksOptimizationMarker() {
|
||||
return code().checks_optimization_marker();
|
||||
}
|
||||
|
||||
bool JSFunction::IsMarkedForOptimization() {
|
||||
return has_feedback_vector() && feedback_vector().optimization_marker() ==
|
||||
OptimizationMarker::kCompileOptimized;
|
||||
}
|
||||
|
||||
bool JSFunction::IsMarkedForConcurrentOptimization() {
|
||||
return has_feedback_vector() &&
|
||||
feedback_vector().optimization_marker() ==
|
||||
OptimizationMarker::kCompileOptimizedConcurrent;
|
||||
}
|
||||
|
||||
void JSFunction::MarkForOptimization(ConcurrencyMode mode) {
|
||||
Isolate* isolate = GetIsolate();
|
||||
if (!isolate->concurrent_recompilation_enabled() ||
|
||||
isolate->bootstrapper()->IsActive()) {
|
||||
mode = ConcurrencyMode::kNotConcurrent;
|
||||
}
|
||||
|
||||
DCHECK(!is_compiled() || ActiveTierIsIgnition() || ActiveTierIsNCI());
|
||||
DCHECK(!ActiveTierIsTurbofan());
|
||||
DCHECK(shared().IsInterpreted());
|
||||
DCHECK(shared().allows_lazy_compilation() ||
|
||||
!shared().optimization_disabled());
|
||||
|
||||
if (mode == ConcurrencyMode::kConcurrent) {
|
||||
if (IsInOptimizationQueue()) {
|
||||
if (FLAG_trace_concurrent_recompilation) {
|
||||
PrintF(" ** Not marking ");
|
||||
ShortPrint();
|
||||
PrintF(" -- already in optimization queue.\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (FLAG_trace_concurrent_recompilation) {
|
||||
PrintF(" ** Marking ");
|
||||
ShortPrint();
|
||||
PrintF(" for concurrent recompilation.\n");
|
||||
}
|
||||
}
|
||||
|
||||
SetOptimizationMarker(mode == ConcurrencyMode::kConcurrent
|
||||
? OptimizationMarker::kCompileOptimizedConcurrent
|
||||
: OptimizationMarker::kCompileOptimized);
|
||||
}
|
||||
|
||||
bool JSFunction::IsInOptimizationQueue() {
|
||||
return has_feedback_vector() && feedback_vector().optimization_marker() ==
|
||||
OptimizationMarker::kInOptimizationQueue;
|
||||
}
|
||||
|
||||
void JSFunction::CompleteInobjectSlackTrackingIfActive() {
|
||||
if (!has_prototype_slot()) return;
|
||||
if (has_initial_map() && initial_map().IsInobjectSlackTrackingInProgress()) {
|
||||
initial_map().CompleteInobjectSlackTracking(GetIsolate());
|
||||
}
|
||||
}
|
||||
|
||||
AbstractCode JSFunction::abstract_code() {
|
||||
if (ActiveTierIsIgnition()) {
|
||||
return AbstractCode::cast(shared().GetBytecodeArray());
|
||||
} else {
|
||||
return AbstractCode::cast(code());
|
||||
}
|
||||
}
|
||||
|
||||
int JSFunction::length() { return shared().length(); }
|
||||
|
||||
Code JSFunction::code() const {
|
||||
return Code::cast(RELAXED_READ_FIELD(*this, kCodeOffset));
|
||||
}
|
||||
|
||||
void JSFunction::set_code(Code value) {
|
||||
DCHECK(!ObjectInYoungGeneration(value));
|
||||
RELAXED_WRITE_FIELD(*this, kCodeOffset, value);
|
||||
#ifndef V8_DISABLE_WRITE_BARRIERS
|
||||
WriteBarrier::Marking(*this, RawField(kCodeOffset), value);
|
||||
#endif
|
||||
}
|
||||
|
||||
void JSFunction::set_code_no_write_barrier(Code value) {
|
||||
DCHECK(!ObjectInYoungGeneration(value));
|
||||
RELAXED_WRITE_FIELD(*this, kCodeOffset, value);
|
||||
}
|
||||
|
||||
// TODO(ishell): Why relaxed read but release store?
|
||||
DEF_GETTER(JSFunction, shared, SharedFunctionInfo) {
|
||||
return SharedFunctionInfo::cast(
|
||||
RELAXED_READ_FIELD(*this, kSharedFunctionInfoOffset));
|
||||
}
|
||||
|
||||
void JSFunction::set_shared(SharedFunctionInfo value, WriteBarrierMode mode) {
|
||||
// Release semantics to support acquire read in NeedsResetDueToFlushedBytecode
|
||||
RELEASE_WRITE_FIELD(*this, kSharedFunctionInfoOffset, value);
|
||||
CONDITIONAL_WRITE_BARRIER(*this, kSharedFunctionInfoOffset, value, mode);
|
||||
}
|
||||
|
||||
void JSFunction::ClearOptimizedCodeSlot(const char* reason) {
|
||||
if (has_feedback_vector() && feedback_vector().has_optimized_code()) {
|
||||
if (FLAG_trace_opt) {
|
||||
CodeTracer::Scope scope(GetIsolate()->GetCodeTracer());
|
||||
PrintF(scope.file(),
|
||||
"[evicting entry from optimizing code feedback slot (%s) for ",
|
||||
reason);
|
||||
ShortPrint(scope.file());
|
||||
PrintF(scope.file(), "]\n");
|
||||
}
|
||||
feedback_vector().ClearOptimizedCode();
|
||||
}
|
||||
}
|
||||
|
||||
void JSFunction::SetOptimizationMarker(OptimizationMarker marker) {
|
||||
DCHECK(has_feedback_vector());
|
||||
DCHECK(ChecksOptimizationMarker());
|
||||
DCHECK(!ActiveTierIsTurbofan());
|
||||
|
||||
feedback_vector().SetOptimizationMarker(marker);
|
||||
}
|
||||
|
||||
bool JSFunction::has_feedback_vector() const {
|
||||
return shared().is_compiled() &&
|
||||
raw_feedback_cell().value().IsFeedbackVector();
|
||||
}
|
||||
|
||||
bool JSFunction::has_closure_feedback_cell_array() const {
|
||||
return shared().is_compiled() &&
|
||||
raw_feedback_cell().value().IsClosureFeedbackCellArray();
|
||||
}
|
||||
|
||||
Context JSFunction::context() {
|
||||
return TaggedField<Context, kContextOffset>::load(*this);
|
||||
}
|
||||
|
||||
bool JSFunction::has_context() const {
|
||||
return TaggedField<HeapObject, kContextOffset>::load(*this).IsContext();
|
||||
}
|
||||
|
||||
JSGlobalProxy JSFunction::global_proxy() { return context().global_proxy(); }
|
||||
|
||||
NativeContext JSFunction::native_context() {
|
||||
return context().native_context();
|
||||
}
|
||||
|
||||
void JSFunction::set_context(HeapObject value) {
|
||||
DCHECK(value.IsUndefined() || value.IsContext());
|
||||
WRITE_FIELD(*this, kContextOffset, value);
|
||||
WRITE_BARRIER(*this, kContextOffset, value);
|
||||
}
|
||||
|
||||
ACCESSORS_CHECKED(JSFunction, prototype_or_initial_map, HeapObject,
|
||||
kPrototypeOrInitialMapOffset, map().has_prototype_slot())
|
||||
|
||||
DEF_GETTER(JSFunction, has_prototype_slot, bool) {
|
||||
return map(isolate).has_prototype_slot();
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, initial_map, Map) {
|
||||
return Map::cast(prototype_or_initial_map(isolate));
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, has_initial_map, bool) {
|
||||
DCHECK(has_prototype_slot(isolate));
|
||||
return prototype_or_initial_map(isolate).IsMap(isolate);
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, has_instance_prototype, bool) {
|
||||
DCHECK(has_prototype_slot(isolate));
|
||||
// Can't use ReadOnlyRoots(isolate) as this isolate could be produced by
|
||||
// i::GetIsolateForPtrCompr(HeapObject).
|
||||
return has_initial_map(isolate) ||
|
||||
!prototype_or_initial_map(isolate).IsTheHole(
|
||||
GetReadOnlyRoots(isolate));
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, has_prototype, bool) {
|
||||
DCHECK(has_prototype_slot(isolate));
|
||||
return map(isolate).has_non_instance_prototype() ||
|
||||
has_instance_prototype(isolate);
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, has_prototype_property, bool) {
|
||||
return (has_prototype_slot(isolate) && IsConstructor(isolate)) ||
|
||||
IsGeneratorFunction(shared(isolate).kind());
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, PrototypeRequiresRuntimeLookup, bool) {
|
||||
return !has_prototype_property(isolate) ||
|
||||
map(isolate).has_non_instance_prototype();
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, instance_prototype, HeapObject) {
|
||||
DCHECK(has_instance_prototype(isolate));
|
||||
if (has_initial_map(isolate)) return initial_map(isolate).prototype(isolate);
|
||||
// When there is no initial map and the prototype is a JSReceiver, the
|
||||
// initial map field is used for the prototype field.
|
||||
return HeapObject::cast(prototype_or_initial_map(isolate));
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, prototype, Object) {
|
||||
DCHECK(has_prototype(isolate));
|
||||
// If the function's prototype property has been set to a non-JSReceiver
|
||||
// value, that value is stored in the constructor field of the map.
|
||||
if (map(isolate).has_non_instance_prototype()) {
|
||||
Object prototype = map(isolate).GetConstructor(isolate);
|
||||
// The map must have a prototype in that field, not a back pointer.
|
||||
DCHECK(!prototype.IsMap(isolate));
|
||||
DCHECK(!prototype.IsFunctionTemplateInfo(isolate));
|
||||
return prototype;
|
||||
}
|
||||
return instance_prototype(isolate);
|
||||
}
|
||||
|
||||
bool JSFunction::is_compiled() const {
|
||||
return code().builtin_index() != Builtins::kCompileLazy &&
|
||||
shared().is_compiled();
|
||||
}
|
||||
|
||||
bool JSFunction::NeedsResetDueToFlushedBytecode() {
|
||||
// Do a raw read for shared and code fields here since this function may be
|
||||
// called on a concurrent thread and the JSFunction might not be fully
|
||||
// initialized yet.
|
||||
Object maybe_shared = ACQUIRE_READ_FIELD(*this, kSharedFunctionInfoOffset);
|
||||
Object maybe_code = RELAXED_READ_FIELD(*this, kCodeOffset);
|
||||
|
||||
if (!maybe_shared.IsSharedFunctionInfo() || !maybe_code.IsCode()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SharedFunctionInfo shared = SharedFunctionInfo::cast(maybe_shared);
|
||||
Code code = Code::cast(maybe_code);
|
||||
return !shared.is_compiled() &&
|
||||
code.builtin_index() != Builtins::kCompileLazy;
|
||||
}
|
||||
|
||||
void JSFunction::ResetIfBytecodeFlushed(
|
||||
base::Optional<std::function<void(HeapObject object, ObjectSlot slot,
|
||||
HeapObject target)>>
|
||||
gc_notify_updated_slot) {
|
||||
if (FLAG_flush_bytecode && NeedsResetDueToFlushedBytecode()) {
|
||||
// Bytecode was flushed and function is now uncompiled, reset JSFunction
|
||||
// by setting code to CompileLazy and clearing the feedback vector.
|
||||
set_code(GetIsolate()->builtins()->builtin(i::Builtins::kCompileLazy));
|
||||
raw_feedback_cell().reset_feedback_vector(gc_notify_updated_slot);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#include "src/objects/object-macros-undef.h"
|
||||
|
||||
#endif // V8_OBJECTS_JS_FUNCTION_INL_H_
|
@ -18,24 +18,6 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL_NONINLINE(JSFunctionOrBoundFunction)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL_NONINLINE(JSBoundFunction)
|
||||
OBJECT_CONSTRUCTORS_IMPL_NONINLINE(JSFunction, JSFunctionOrBoundFunction)
|
||||
|
||||
CAST_ACCESSOR(JSFunction)
|
||||
|
||||
ACCESSORS(JSFunction, raw_feedback_cell, FeedbackCell, kFeedbackCellOffset)
|
||||
|
||||
FeedbackVector JSFunction::feedback_vector() const {
|
||||
DCHECK(has_feedback_vector());
|
||||
return FeedbackVector::cast(raw_feedback_cell().value());
|
||||
}
|
||||
|
||||
ClosureFeedbackCellArray JSFunction::closure_feedback_cell_array() const {
|
||||
DCHECK(has_closure_feedback_cell_array());
|
||||
return ClosureFeedbackCellArray::cast(raw_feedback_cell().value());
|
||||
}
|
||||
|
||||
CodeKinds JSFunction::GetAttachedCodeKinds() const {
|
||||
CodeKinds result;
|
||||
|
||||
@ -167,230 +149,6 @@ bool JSFunction::CanDiscardCompiled() const {
|
||||
return (result & kJSFunctionCodeKindsMask) != 0;
|
||||
}
|
||||
|
||||
bool JSFunction::HasOptimizationMarker() {
|
||||
return has_feedback_vector() && feedback_vector().has_optimization_marker();
|
||||
}
|
||||
|
||||
void JSFunction::ClearOptimizationMarker() {
|
||||
DCHECK(has_feedback_vector());
|
||||
feedback_vector().ClearOptimizationMarker();
|
||||
}
|
||||
|
||||
bool JSFunction::ChecksOptimizationMarker() {
|
||||
return code().checks_optimization_marker();
|
||||
}
|
||||
|
||||
bool JSFunction::IsMarkedForOptimization() {
|
||||
return has_feedback_vector() && feedback_vector().optimization_marker() ==
|
||||
OptimizationMarker::kCompileOptimized;
|
||||
}
|
||||
|
||||
bool JSFunction::IsMarkedForConcurrentOptimization() {
|
||||
return has_feedback_vector() &&
|
||||
feedback_vector().optimization_marker() ==
|
||||
OptimizationMarker::kCompileOptimizedConcurrent;
|
||||
}
|
||||
|
||||
bool JSFunction::IsInOptimizationQueue() {
|
||||
return has_feedback_vector() && feedback_vector().optimization_marker() ==
|
||||
OptimizationMarker::kInOptimizationQueue;
|
||||
}
|
||||
|
||||
void JSFunction::CompleteInobjectSlackTrackingIfActive() {
|
||||
if (!has_prototype_slot()) return;
|
||||
if (has_initial_map() && initial_map().IsInobjectSlackTrackingInProgress()) {
|
||||
initial_map().CompleteInobjectSlackTracking(GetIsolate());
|
||||
}
|
||||
}
|
||||
|
||||
AbstractCode JSFunction::abstract_code() {
|
||||
if (ActiveTierIsIgnition()) {
|
||||
return AbstractCode::cast(shared().GetBytecodeArray());
|
||||
} else {
|
||||
return AbstractCode::cast(code());
|
||||
}
|
||||
}
|
||||
|
||||
int JSFunction::length() { return shared().length(); }
|
||||
|
||||
Code JSFunction::code() const {
|
||||
return Code::cast(RELAXED_READ_FIELD(*this, kCodeOffset));
|
||||
}
|
||||
|
||||
void JSFunction::set_code(Code value) {
|
||||
DCHECK(!ObjectInYoungGeneration(value));
|
||||
RELAXED_WRITE_FIELD(*this, kCodeOffset, value);
|
||||
#ifndef V8_DISABLE_WRITE_BARRIERS
|
||||
WriteBarrier::Marking(*this, RawField(kCodeOffset), value);
|
||||
#endif
|
||||
}
|
||||
|
||||
void JSFunction::set_code_no_write_barrier(Code value) {
|
||||
DCHECK(!ObjectInYoungGeneration(value));
|
||||
RELAXED_WRITE_FIELD(*this, kCodeOffset, value);
|
||||
}
|
||||
|
||||
// TODO(ishell): Why relaxed read but release store?
|
||||
DEF_GETTER(JSFunction, shared, SharedFunctionInfo) {
|
||||
return SharedFunctionInfo::cast(
|
||||
RELAXED_READ_FIELD(*this, kSharedFunctionInfoOffset));
|
||||
}
|
||||
|
||||
void JSFunction::set_shared(SharedFunctionInfo value, WriteBarrierMode mode) {
|
||||
// Release semantics to support acquire read in NeedsResetDueToFlushedBytecode
|
||||
RELEASE_WRITE_FIELD(*this, kSharedFunctionInfoOffset, value);
|
||||
CONDITIONAL_WRITE_BARRIER(*this, kSharedFunctionInfoOffset, value, mode);
|
||||
}
|
||||
|
||||
void JSFunction::ClearOptimizedCodeSlot(const char* reason) {
|
||||
if (has_feedback_vector() && feedback_vector().has_optimized_code()) {
|
||||
if (FLAG_trace_opt) {
|
||||
CodeTracer::Scope scope(GetIsolate()->GetCodeTracer());
|
||||
PrintF(scope.file(),
|
||||
"[evicting entry from optimizing code feedback slot (%s) for ",
|
||||
reason);
|
||||
ShortPrint(scope.file());
|
||||
PrintF(scope.file(), "]\n");
|
||||
}
|
||||
feedback_vector().ClearOptimizedCode();
|
||||
}
|
||||
}
|
||||
|
||||
void JSFunction::SetOptimizationMarker(OptimizationMarker marker) {
|
||||
DCHECK(has_feedback_vector());
|
||||
DCHECK(ChecksOptimizationMarker());
|
||||
DCHECK(!ActiveTierIsTurbofan());
|
||||
|
||||
feedback_vector().SetOptimizationMarker(marker);
|
||||
}
|
||||
|
||||
bool JSFunction::has_feedback_vector() const {
|
||||
return shared().is_compiled() &&
|
||||
raw_feedback_cell().value().IsFeedbackVector();
|
||||
}
|
||||
|
||||
bool JSFunction::has_closure_feedback_cell_array() const {
|
||||
return shared().is_compiled() &&
|
||||
raw_feedback_cell().value().IsClosureFeedbackCellArray();
|
||||
}
|
||||
|
||||
Context JSFunction::context() {
|
||||
return TaggedField<Context, kContextOffset>::load(*this);
|
||||
}
|
||||
|
||||
bool JSFunction::has_context() const {
|
||||
return TaggedField<HeapObject, kContextOffset>::load(*this).IsContext();
|
||||
}
|
||||
|
||||
JSGlobalProxy JSFunction::global_proxy() { return context().global_proxy(); }
|
||||
|
||||
NativeContext JSFunction::native_context() {
|
||||
return context().native_context();
|
||||
}
|
||||
|
||||
void JSFunction::set_context(HeapObject value) {
|
||||
DCHECK(value.IsUndefined() || value.IsContext());
|
||||
WRITE_FIELD(*this, kContextOffset, value);
|
||||
WRITE_BARRIER(*this, kContextOffset, value);
|
||||
}
|
||||
|
||||
ACCESSORS_CHECKED(JSFunction, prototype_or_initial_map, HeapObject,
|
||||
kPrototypeOrInitialMapOffset, map().has_prototype_slot())
|
||||
|
||||
DEF_GETTER(JSFunction, has_prototype_slot, bool) {
|
||||
return map(isolate).has_prototype_slot();
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, initial_map, Map) {
|
||||
return Map::cast(prototype_or_initial_map(isolate));
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, has_initial_map, bool) {
|
||||
DCHECK(has_prototype_slot(isolate));
|
||||
return prototype_or_initial_map(isolate).IsMap(isolate);
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, has_instance_prototype, bool) {
|
||||
DCHECK(has_prototype_slot(isolate));
|
||||
// Can't use ReadOnlyRoots(isolate) as this isolate could be produced by
|
||||
// i::GetIsolateForPtrCompr(HeapObject).
|
||||
return has_initial_map(isolate) ||
|
||||
!prototype_or_initial_map(isolate).IsTheHole(
|
||||
GetReadOnlyRoots(isolate));
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, has_prototype, bool) {
|
||||
DCHECK(has_prototype_slot(isolate));
|
||||
return map(isolate).has_non_instance_prototype() ||
|
||||
has_instance_prototype(isolate);
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, has_prototype_property, bool) {
|
||||
return (has_prototype_slot(isolate) && IsConstructor(isolate)) ||
|
||||
IsGeneratorFunction(shared(isolate).kind());
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, PrototypeRequiresRuntimeLookup, bool) {
|
||||
return !has_prototype_property(isolate) ||
|
||||
map(isolate).has_non_instance_prototype();
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, instance_prototype, HeapObject) {
|
||||
DCHECK(has_instance_prototype(isolate));
|
||||
if (has_initial_map(isolate)) return initial_map(isolate).prototype(isolate);
|
||||
// When there is no initial map and the prototype is a JSReceiver, the
|
||||
// initial map field is used for the prototype field.
|
||||
return HeapObject::cast(prototype_or_initial_map(isolate));
|
||||
}
|
||||
|
||||
DEF_GETTER(JSFunction, prototype, Object) {
|
||||
DCHECK(has_prototype(isolate));
|
||||
// If the function's prototype property has been set to a non-JSReceiver
|
||||
// value, that value is stored in the constructor field of the map.
|
||||
if (map(isolate).has_non_instance_prototype()) {
|
||||
Object prototype = map(isolate).GetConstructor(isolate);
|
||||
// The map must have a prototype in that field, not a back pointer.
|
||||
DCHECK(!prototype.IsMap(isolate));
|
||||
DCHECK(!prototype.IsFunctionTemplateInfo(isolate));
|
||||
return prototype;
|
||||
}
|
||||
return instance_prototype(isolate);
|
||||
}
|
||||
|
||||
bool JSFunction::is_compiled() const {
|
||||
return code().builtin_index() != Builtins::kCompileLazy &&
|
||||
shared().is_compiled();
|
||||
}
|
||||
|
||||
bool JSFunction::NeedsResetDueToFlushedBytecode() {
|
||||
// Do a raw read for shared and code fields here since this function may be
|
||||
// called on a concurrent thread and the JSFunction might not be fully
|
||||
// initialized yet.
|
||||
Object maybe_shared = ACQUIRE_READ_FIELD(*this, kSharedFunctionInfoOffset);
|
||||
Object maybe_code = RELAXED_READ_FIELD(*this, kCodeOffset);
|
||||
|
||||
if (!maybe_shared.IsSharedFunctionInfo() || !maybe_code.IsCode()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SharedFunctionInfo shared = SharedFunctionInfo::cast(maybe_shared);
|
||||
Code code = Code::cast(maybe_code);
|
||||
return !shared.is_compiled() &&
|
||||
code.builtin_index() != Builtins::kCompileLazy;
|
||||
}
|
||||
|
||||
void JSFunction::ResetIfBytecodeFlushed(
|
||||
base::Optional<std::function<void(HeapObject object, ObjectSlot slot,
|
||||
HeapObject target)>>
|
||||
gc_notify_updated_slot) {
|
||||
if (FLAG_flush_bytecode && NeedsResetDueToFlushedBytecode()) {
|
||||
// Bytecode was flushed and function is now uncompiled, reset JSFunction
|
||||
// by setting code to CompileLazy and clearing the feedback vector.
|
||||
set_code(GetIsolate()->builtins()->builtin(i::Builtins::kCompileLazy));
|
||||
raw_feedback_cell().reset_feedback_vector(gc_notify_updated_slot);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
MaybeHandle<NativeContext> JSBoundFunction::GetFunctionRealm(
|
||||
Handle<JSBoundFunction> function) {
|
||||
@ -473,40 +231,6 @@ Handle<NativeContext> JSFunction::GetFunctionRealm(
|
||||
return handle(function->context().native_context(), function->GetIsolate());
|
||||
}
|
||||
|
||||
void JSFunction::MarkForOptimization(ConcurrencyMode mode) {
|
||||
Isolate* isolate = GetIsolate();
|
||||
if (!isolate->concurrent_recompilation_enabled() ||
|
||||
isolate->bootstrapper()->IsActive()) {
|
||||
mode = ConcurrencyMode::kNotConcurrent;
|
||||
}
|
||||
|
||||
DCHECK(!is_compiled() || ActiveTierIsIgnition() || ActiveTierIsNCI());
|
||||
DCHECK(!ActiveTierIsTurbofan());
|
||||
DCHECK(shared().IsInterpreted());
|
||||
DCHECK(shared().allows_lazy_compilation() ||
|
||||
!shared().optimization_disabled());
|
||||
|
||||
if (mode == ConcurrencyMode::kConcurrent) {
|
||||
if (IsInOptimizationQueue()) {
|
||||
if (FLAG_trace_concurrent_recompilation) {
|
||||
PrintF(" ** Not marking ");
|
||||
ShortPrint();
|
||||
PrintF(" -- already in optimization queue.\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (FLAG_trace_concurrent_recompilation) {
|
||||
PrintF(" ** Marking ");
|
||||
ShortPrint();
|
||||
PrintF(" for concurrent recompilation.\n");
|
||||
}
|
||||
}
|
||||
|
||||
SetOptimizationMarker(mode == ConcurrencyMode::kConcurrent
|
||||
? OptimizationMarker::kCompileOptimizedConcurrent
|
||||
: OptimizationMarker::kCompileOptimized);
|
||||
}
|
||||
|
||||
// static
|
||||
void JSFunction::EnsureClosureFeedbackCellArray(Handle<JSFunction> function) {
|
||||
Isolate* const isolate = function->GetIsolate();
|
||||
|
@ -24,7 +24,7 @@ class JSFunctionOrBoundFunction
|
||||
JSObject> {
|
||||
public:
|
||||
STATIC_ASSERT(kHeaderSize == JSObject::kHeaderSize);
|
||||
TQ_OBJECT_CONSTRUCTORS_NONINLINE(JSFunctionOrBoundFunction)
|
||||
TQ_OBJECT_CONSTRUCTORS(JSFunctionOrBoundFunction)
|
||||
};
|
||||
|
||||
// JSBoundFunction describes a bound function exotic object.
|
||||
@ -47,18 +47,18 @@ class JSBoundFunction
|
||||
// to ES6 section 19.2.3.5 Function.prototype.toString ( ).
|
||||
static Handle<String> ToString(Handle<JSBoundFunction> function);
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS_NONINLINE(JSBoundFunction)
|
||||
TQ_OBJECT_CONSTRUCTORS(JSBoundFunction)
|
||||
};
|
||||
|
||||
// JSFunction describes JavaScript functions.
|
||||
class JSFunction : public JSFunctionOrBoundFunction {
|
||||
public:
|
||||
// [prototype_or_initial_map]:
|
||||
DECL_ACCESSORS_NONINLINE(prototype_or_initial_map, HeapObject)
|
||||
DECL_ACCESSORS(prototype_or_initial_map, HeapObject)
|
||||
|
||||
// [shared]: The information about the function that
|
||||
// can be shared by instances.
|
||||
DECL_ACCESSORS_NONINLINE(shared, SharedFunctionInfo)
|
||||
DECL_ACCESSORS(shared, SharedFunctionInfo)
|
||||
|
||||
static const int kLengthDescriptorIndex = 0;
|
||||
static const int kNameDescriptorIndex = 1;
|
||||
@ -68,12 +68,12 @@ class JSFunction : public JSFunctionOrBoundFunction {
|
||||
static const int kMinDescriptorsForFastBind = 2;
|
||||
|
||||
// [context]: The context for this function.
|
||||
V8_EXPORT_PRIVATE Context context();
|
||||
bool has_context() const;
|
||||
void set_context(HeapObject context);
|
||||
JSGlobalProxy global_proxy();
|
||||
V8_EXPORT_PRIVATE NativeContext native_context();
|
||||
int length();
|
||||
inline Context context();
|
||||
inline bool has_context() const;
|
||||
inline void set_context(HeapObject context);
|
||||
inline JSGlobalProxy global_proxy();
|
||||
inline NativeContext native_context();
|
||||
inline int length();
|
||||
|
||||
static Handle<Object> GetName(Isolate* isolate, Handle<JSFunction> function);
|
||||
static Handle<NativeContext> GetFunctionRealm(Handle<JSFunction> function);
|
||||
@ -82,13 +82,13 @@ class JSFunction : public JSFunctionOrBoundFunction {
|
||||
// when the function is invoked, e.g. foo() or new foo(). See
|
||||
// [[Call]] and [[Construct]] description in ECMA-262, section
|
||||
// 8.6.2, page 27.
|
||||
V8_EXPORT_PRIVATE Code code() const;
|
||||
V8_EXPORT_PRIVATE void set_code(Code code);
|
||||
void set_code_no_write_barrier(Code code);
|
||||
inline Code code() const;
|
||||
inline void set_code(Code code);
|
||||
inline void set_code_no_write_barrier(Code code);
|
||||
|
||||
// Get the abstract code associated with the function, which will either be
|
||||
// a Code object or a BytecodeArray.
|
||||
V8_EXPORT_PRIVATE AbstractCode abstract_code();
|
||||
inline AbstractCode abstract_code();
|
||||
|
||||
// The predicates for querying code kinds related to this function have
|
||||
// specific terminology:
|
||||
@ -125,30 +125,30 @@ class JSFunction : public JSFunctionOrBoundFunction {
|
||||
|
||||
// Tells whether or not this function checks its optimization marker in its
|
||||
// feedback vector.
|
||||
bool ChecksOptimizationMarker();
|
||||
inline bool ChecksOptimizationMarker();
|
||||
|
||||
// Tells whether or not this function has a (non-zero) optimization marker.
|
||||
bool HasOptimizationMarker();
|
||||
inline bool HasOptimizationMarker();
|
||||
|
||||
// Mark this function for lazy recompilation. The function will be recompiled
|
||||
// the next time it is executed.
|
||||
void MarkForOptimization(ConcurrencyMode mode);
|
||||
inline void MarkForOptimization(ConcurrencyMode mode);
|
||||
|
||||
// Tells whether or not the function is already marked for lazy recompilation.
|
||||
bool IsMarkedForOptimization();
|
||||
bool IsMarkedForConcurrentOptimization();
|
||||
inline bool IsMarkedForOptimization();
|
||||
inline bool IsMarkedForConcurrentOptimization();
|
||||
|
||||
// Tells whether or not the function is on the concurrent recompilation queue.
|
||||
bool IsInOptimizationQueue();
|
||||
inline bool IsInOptimizationQueue();
|
||||
|
||||
// Clears the optimized code slot in the function's feedback vector.
|
||||
void ClearOptimizedCodeSlot(const char* reason);
|
||||
inline void ClearOptimizedCodeSlot(const char* reason);
|
||||
|
||||
// Sets the optimization marker in the function's feedback vector.
|
||||
void SetOptimizationMarker(OptimizationMarker marker);
|
||||
inline void SetOptimizationMarker(OptimizationMarker marker);
|
||||
|
||||
// Clears the optimization marker in the function's feedback vector.
|
||||
void ClearOptimizationMarker();
|
||||
inline void ClearOptimizationMarker();
|
||||
|
||||
// If slack tracking is active, it computes instance size of the initial map
|
||||
// with minimum permissible object slack. If it is not active, it simply
|
||||
@ -156,28 +156,28 @@ class JSFunction : public JSFunctionOrBoundFunction {
|
||||
int ComputeInstanceSizeWithMinSlack(Isolate* isolate);
|
||||
|
||||
// Completes inobject slack tracking on initial map if it is active.
|
||||
void CompleteInobjectSlackTrackingIfActive();
|
||||
inline void CompleteInobjectSlackTrackingIfActive();
|
||||
|
||||
// [raw_feedback_cell]: Gives raw access to the FeedbackCell used to hold the
|
||||
/// FeedbackVector eventually. Generally this shouldn't be used to get the
|
||||
// feedback_vector, instead use feedback_vector() which correctly deals with
|
||||
// the JSFunction's bytecode being flushed.
|
||||
DECL_ACCESSORS_NONINLINE(raw_feedback_cell, FeedbackCell)
|
||||
DECL_ACCESSORS(raw_feedback_cell, FeedbackCell)
|
||||
|
||||
// Functions related to feedback vector. feedback_vector() can be used once
|
||||
// the function has feedback vectors allocated. feedback vectors may not be
|
||||
// available after compile when lazily allocating feedback vectors.
|
||||
V8_EXPORT_PRIVATE FeedbackVector feedback_vector() const;
|
||||
V8_EXPORT_PRIVATE bool has_feedback_vector() const;
|
||||
inline FeedbackVector feedback_vector() const;
|
||||
inline bool has_feedback_vector() const;
|
||||
V8_EXPORT_PRIVATE static void EnsureFeedbackVector(
|
||||
Handle<JSFunction> function, IsCompiledScope* compiled_scope);
|
||||
|
||||
// Functions related to clousre feedback cell array that holds feedback cells
|
||||
// Functions related to closure feedback cell array that holds feedback cells
|
||||
// used to create closures from this function. We allocate closure feedback
|
||||
// cell arrays after compile, when we want to allocate feedback vectors
|
||||
// lazily.
|
||||
V8_EXPORT_PRIVATE bool has_closure_feedback_cell_array() const;
|
||||
ClosureFeedbackCellArray closure_feedback_cell_array() const;
|
||||
inline bool has_closure_feedback_cell_array() const;
|
||||
inline ClosureFeedbackCellArray closure_feedback_cell_array() const;
|
||||
static void EnsureClosureFeedbackCellArray(Handle<JSFunction> function);
|
||||
|
||||
// Initializes the feedback cell of |function|. In lite mode, this would be
|
||||
@ -191,20 +191,20 @@ class JSFunction : public JSFunctionOrBoundFunction {
|
||||
void ClearTypeFeedbackInfo();
|
||||
|
||||
// Resets function to clear compiled data after bytecode has been flushed.
|
||||
bool NeedsResetDueToFlushedBytecode();
|
||||
void ResetIfBytecodeFlushed(
|
||||
inline bool NeedsResetDueToFlushedBytecode();
|
||||
inline void ResetIfBytecodeFlushed(
|
||||
base::Optional<std::function<void(HeapObject object, ObjectSlot slot,
|
||||
HeapObject target)>>
|
||||
gc_notify_updated_slot = base::nullopt);
|
||||
|
||||
DECL_GETTER_NONINLINE(has_prototype_slot, bool)
|
||||
DECL_GETTER(has_prototype_slot, bool)
|
||||
|
||||
// The initial map for an object created by this constructor.
|
||||
DECL_GETTER_NONINLINE(initial_map, Map)
|
||||
DECL_GETTER(initial_map, Map)
|
||||
|
||||
static void SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
|
||||
Handle<HeapObject> prototype);
|
||||
DECL_GETTER_NONINLINE(has_initial_map, bool)
|
||||
DECL_GETTER(has_initial_map, bool)
|
||||
V8_EXPORT_PRIVATE static void EnsureHasInitialMap(
|
||||
Handle<JSFunction> function);
|
||||
|
||||
@ -219,16 +219,16 @@ class JSFunction : public JSFunctionOrBoundFunction {
|
||||
// function has an initial map the prototype is set on the initial
|
||||
// map. Otherwise, the prototype is put in the initial map field
|
||||
// until an initial map is needed.
|
||||
DECL_GETTER_NONINLINE(has_prototype, bool)
|
||||
DECL_GETTER_NONINLINE(has_instance_prototype, bool)
|
||||
DECL_GETTER_NONINLINE(prototype, Object)
|
||||
DECL_GETTER_NONINLINE(instance_prototype, HeapObject)
|
||||
DECL_GETTER_NONINLINE(has_prototype_property, bool)
|
||||
DECL_GETTER_NONINLINE(PrototypeRequiresRuntimeLookup, bool)
|
||||
DECL_GETTER(has_prototype, bool)
|
||||
DECL_GETTER(has_instance_prototype, bool)
|
||||
DECL_GETTER(prototype, Object)
|
||||
DECL_GETTER(instance_prototype, HeapObject)
|
||||
DECL_GETTER(has_prototype_property, bool)
|
||||
DECL_GETTER(PrototypeRequiresRuntimeLookup, bool)
|
||||
static void SetPrototype(Handle<JSFunction> function, Handle<Object> value);
|
||||
|
||||
// Returns if this function has been compiled to native code yet.
|
||||
V8_EXPORT_PRIVATE bool is_compiled() const;
|
||||
inline bool is_compiled() const;
|
||||
|
||||
static int GetHeaderSize(bool function_has_prototype_slot) {
|
||||
return function_has_prototype_slot ? JSFunction::kSizeWithPrototype
|
||||
@ -238,7 +238,7 @@ class JSFunction : public JSFunctionOrBoundFunction {
|
||||
// Prints the name of the function using PrintF.
|
||||
void PrintName(FILE* out = stdout);
|
||||
|
||||
DECL_CAST_NONINLINE(JSFunction)
|
||||
DECL_CAST(JSFunction)
|
||||
|
||||
// Calculate the instance size and in-object properties count.
|
||||
// {CalculateExpectedNofProperties} can trigger compilation.
|
||||
@ -311,7 +311,7 @@ class JSFunction : public JSFunctionOrBoundFunction {
|
||||
static constexpr int kSizeWithoutPrototype = kPrototypeOrInitialMapOffset;
|
||||
static constexpr int kSizeWithPrototype = FieldOffsets::kHeaderSize;
|
||||
|
||||
OBJECT_CONSTRUCTORS_NONINLINE(JSFunction, JSFunctionOrBoundFunction);
|
||||
OBJECT_CONSTRUCTORS(JSFunction, JSFunctionOrBoundFunction);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "src/objects/descriptor-array-inl.h"
|
||||
#include "src/objects/field-type.h"
|
||||
#include "src/objects/instance-type-inl.h"
|
||||
#include "src/objects/js-function-inl.h"
|
||||
#include "src/objects/layout-descriptor-inl.h"
|
||||
#include "src/objects/map.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
|
@ -81,10 +81,3 @@
|
||||
#undef DEFINE_DEOPT_ENTRY_ACCESSORS
|
||||
#undef TQ_OBJECT_CONSTRUCTORS
|
||||
#undef TQ_OBJECT_CONSTRUCTORS_IMPL
|
||||
#undef OBJECT_CONSTRUCTORS_NONINLINE
|
||||
#undef OBJECT_CONSTRUCTORS_IMPL_NONINLINE
|
||||
#undef DECL_GETTER_NONINLINE
|
||||
#undef DECL_ACCESSORS_NONINLINE
|
||||
#undef DECL_CAST_NONINLINE
|
||||
#undef TQ_OBJECT_CONSTRUCTORS_NONINLINE
|
||||
#undef TQ_OBJECT_CONSTRUCTORS_IMPL_NONINLINE
|
||||
|
@ -16,19 +16,6 @@
|
||||
|
||||
#include "src/base/memory.h"
|
||||
|
||||
// TODO(v8:10749): When we've had a chance to collect performance impact,
|
||||
// either move towards using _NONINLINE versions everywhere, or revert back to
|
||||
// inline use and remove _NONINLINE macros.
|
||||
#define OBJECT_CONSTRUCTORS_NONINLINE(Type, ...) \
|
||||
public: \
|
||||
constexpr Type() : __VA_ARGS__() {} \
|
||||
\
|
||||
protected: \
|
||||
template <typename TFieldType, int kFieldOffset> \
|
||||
friend class TaggedField; \
|
||||
\
|
||||
V8_EXPORT_PRIVATE explicit Type(Address ptr)
|
||||
|
||||
// Since this changes visibility, it should always be last in a class
|
||||
// definition.
|
||||
#define OBJECT_CONSTRUCTORS(Type, ...) \
|
||||
@ -41,9 +28,6 @@
|
||||
\
|
||||
explicit inline Type(Address ptr)
|
||||
|
||||
#define OBJECT_CONSTRUCTORS_IMPL_NONINLINE(Type, Super) \
|
||||
Type::Type(Address ptr) : Super(ptr) { SLOW_DCHECK(Is##Type()); }
|
||||
|
||||
#define OBJECT_CONSTRUCTORS_IMPL(Type, Super) \
|
||||
inline Type::Type(Address ptr) : Super(ptr) { SLOW_DCHECK(Is##Type()); }
|
||||
// In these cases, we don't have our own instance type to check, so check the
|
||||
@ -100,10 +84,6 @@
|
||||
inline type name() const; \
|
||||
inline type name(const Isolate* isolate) const;
|
||||
|
||||
#define DECL_GETTER_NONINLINE(name, type) \
|
||||
V8_EXPORT_PRIVATE type name() const; \
|
||||
V8_EXPORT_PRIVATE type name(const Isolate* isolate) const;
|
||||
|
||||
#define DEF_GETTER(holder, name, type) \
|
||||
type holder::name() const { \
|
||||
const Isolate* isolate = GetIsolateForPtrCompr(*this); \
|
||||
@ -116,23 +96,12 @@
|
||||
inline void set_##name(type value, \
|
||||
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
||||
|
||||
#define DECL_ACCESSORS_NONINLINE(name, type) \
|
||||
DECL_GETTER_NONINLINE(name, type) \
|
||||
V8_EXPORT_PRIVATE void set_##name( \
|
||||
type value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
||||
|
||||
// TODO(solanes, neis): Unify naming for synchronized accessor uses.
|
||||
#define DECL_SYNCHRONIZED_ACCESSORS(name, type) \
|
||||
DECL_GETTER(synchronized_##name, type) \
|
||||
inline void set_synchronized_##name( \
|
||||
type value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
||||
|
||||
#define DECL_CAST_NONINLINE(Type) \
|
||||
V8_EXPORT_PRIVATE static Type cast(Object object); \
|
||||
inline static Type unchecked_cast(Object object) { \
|
||||
return bit_cast<Type>(object); \
|
||||
}
|
||||
|
||||
#define DECL_CAST(Type) \
|
||||
V8_INLINE static Type cast(Object object); \
|
||||
V8_INLINE static Type unchecked_cast(Object object) { \
|
||||
@ -519,20 +488,6 @@
|
||||
set(IndexForEntry(i) + k##name##Offset, value); \
|
||||
}
|
||||
|
||||
#define TQ_OBJECT_CONSTRUCTORS_NONINLINE(Type) \
|
||||
public: \
|
||||
constexpr Type() = default; \
|
||||
\
|
||||
protected: \
|
||||
template <typename TFieldType, int kFieldOffset> \
|
||||
friend class TaggedField; \
|
||||
\
|
||||
V8_EXPORT_PRIVATE explicit Type(Address ptr); \
|
||||
friend class TorqueGenerated##Type<Type, Super>;
|
||||
|
||||
#define TQ_OBJECT_CONSTRUCTORS_IMPL_NONINLINE(Type) \
|
||||
Type::Type(Address ptr) : TorqueGenerated##Type<Type, Type::Super>(ptr) {}
|
||||
|
||||
#define TQ_OBJECT_CONSTRUCTORS(Type) \
|
||||
public: \
|
||||
constexpr Type() = default; \
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "src/logging/counters.h"
|
||||
#include "src/objects/heap-object-inl.h"
|
||||
#include "src/objects/js-array-inl.h"
|
||||
#include "src/objects/js-function-inl.h"
|
||||
#include "src/objects/js-regexp-inl.h"
|
||||
#include "src/objects/smi.h"
|
||||
#include "src/snapshot/snapshot.h"
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "src/objects/foreign-inl.h"
|
||||
#include "src/objects/heap-number-inl.h"
|
||||
#include "src/objects/js-array-buffer-inl.h"
|
||||
#include "src/objects/js-function-inl.h"
|
||||
#include "src/objects/js-objects-inl.h"
|
||||
#include "src/objects/managed.h"
|
||||
#include "src/objects/oddball-inl.h"
|
||||
|
Loading…
Reference in New Issue
Block a user