[torque] Begin porting ScopeInfo to Torque
This change adds Torque field definitions for ScopeInfo and begins to use the Torque-generated accessors in some places. It does not change the in-memory layout of ScopeInfo. Torque compiler changes: - Fix an issue where the parser created constexpr types for classes based on the class name rather than the `generates` clause. This meant that generated accessors referred to the imaginary type HashTable rather than the real C++ type FixedArray. - Don't pass Isolate* through the generated runtime functions that implement Torque macros. Maybe we'll need it eventually, but we don't right now and it complicates a lot of things. - Don't emit `kSomeFieldOffset` if some_field has an unknown offset. Instead, emit a member function `SomeFieldOffset()` which fetches the slice for some_field and returns its offset. - Emit an `AllocatedSize()` member function for classes which have complex length expressions. It fetches the slice for the last field and performs the multiply&add to compute the total object size. - Emit field accessors for fields with complex length expressions, using the new offset functions. - Fix a few minor bugs where Torque can write uncompilable code. With this change, most code still treats ScopeInfo like a FixedArray, so I would like to follow up with some additional changes: 1. Generate a GC visitor for ScopeInfo and use it 2. Generate accessors for struct-typed fields (indexed or otherwise), and use them 3. Get rid of the FixedArray-style get and set accessors; use TaggedField::load and similar instead 4. Inherit from HeapObject rather than FixedArrayBase to remove the unnecessary `length` field After that, there will only be one ugly part left: initialization. I think it's possible to generate a factory function that takes a bunch of iterator parameters and returns a fully-formed, verifiably correct ScopeInfo instance, but doing so is more complicated than the four mostly-mechanical changes listed above. Bug: v8:7793 Change-Id: I55fcfe9189e4d1613c68d49e378da5dc02597b36 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2357758 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Reviewed-by: Peter Marshall <petermarshall@chromium.org> Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Commit-Queue: Seth Brenith <seth.brenith@microsoft.com> Cr-Commit-Position: refs/heads/master@{#72187}
This commit is contained in:
parent
1dd3e29b52
commit
ecaac3292f
2
BUILD.gn
2
BUILD.gn
@ -1192,6 +1192,7 @@ action("postmortem-metadata") {
|
||||
"src/objects/primitive-heap-object.h",
|
||||
"src/objects/primitive-heap-object-inl.h",
|
||||
"src/objects/scope-info.h",
|
||||
"src/objects/scope-info-inl.h",
|
||||
"src/objects/script.h",
|
||||
"src/objects/script-inl.h",
|
||||
"src/objects/shared-function-info.cc",
|
||||
@ -3184,6 +3185,7 @@ v8_source_set("v8_base_without_compiler") {
|
||||
"src/objects/prototype-info.h",
|
||||
"src/objects/prototype.h",
|
||||
"src/objects/regexp-match-info.h",
|
||||
"src/objects/scope-info-inl.h",
|
||||
"src/objects/scope-info.cc",
|
||||
"src/objects/scope-info.h",
|
||||
"src/objects/script-inl.h",
|
||||
|
@ -2013,6 +2013,11 @@ TNode<IntPtrT> CodeStubAssembler::LoadArrayLength(
|
||||
return LoadAndUntagWeakFixedArrayLength(array);
|
||||
}
|
||||
|
||||
template <>
|
||||
TNode<IntPtrT> CodeStubAssembler::LoadArrayLength(TNode<ScopeInfo> array) {
|
||||
return LoadAndUntagFixedArrayBaseLength(array);
|
||||
}
|
||||
|
||||
template <typename Array, typename TIndex, typename TValue>
|
||||
TNode<TValue> CodeStubAssembler::LoadArrayElement(
|
||||
TNode<Array> array, int array_header_size, TNode<TIndex> index_node,
|
||||
@ -2043,6 +2048,10 @@ TNode<TValue> CodeStubAssembler::LoadArrayElement(
|
||||
template V8_EXPORT_PRIVATE TNode<MaybeObject>
|
||||
CodeStubAssembler::LoadArrayElement<TransitionArray, IntPtrT>(
|
||||
TNode<TransitionArray>, int, TNode<IntPtrT>, int, LoadSensitivity);
|
||||
template V8_EXPORT_PRIVATE TNode<MaybeObject>
|
||||
CodeStubAssembler::LoadArrayElement<ScopeInfo, IntPtrT>(TNode<ScopeInfo>, int,
|
||||
TNode<IntPtrT>, int,
|
||||
LoadSensitivity);
|
||||
|
||||
template <typename TIndex>
|
||||
TNode<Object> CodeStubAssembler::LoadFixedArrayElement(
|
||||
|
@ -182,7 +182,6 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
|
||||
case NUMBER_DICTIONARY_TYPE:
|
||||
case SIMPLE_NUMBER_DICTIONARY_TYPE:
|
||||
case EPHEMERON_HASH_TABLE_TYPE:
|
||||
case SCOPE_INFO_TYPE:
|
||||
case SCRIPT_CONTEXT_TABLE_TYPE:
|
||||
FixedArray::cast(*this).FixedArrayVerify(isolate);
|
||||
break;
|
||||
@ -581,6 +580,20 @@ void Context::ContextVerify(Isolate* isolate) {
|
||||
}
|
||||
}
|
||||
|
||||
void ScopeInfo::ScopeInfoVerify(Isolate* isolate) {
|
||||
TorqueGeneratedClassVerifiers::ScopeInfoVerify(*this, isolate);
|
||||
|
||||
// Make sure that the FixedArray-style length matches the length that we would
|
||||
// compute based on the Torque indexed fields.
|
||||
CHECK_EQ(FixedArray::SizeFor(length()), AllocatedSize());
|
||||
|
||||
// Code that treats ScopeInfo like a FixedArray expects all values to be
|
||||
// tagged.
|
||||
for (int i = 0; i < length(); ++i) {
|
||||
Object::VerifyPointer(isolate, get(isolate, i));
|
||||
}
|
||||
}
|
||||
|
||||
void NativeContext::NativeContextVerify(Isolate* isolate) {
|
||||
ContextVerify(isolate);
|
||||
CHECK_EQ(length(), NativeContext::NATIVE_CONTEXT_SLOTS);
|
||||
|
@ -209,9 +209,6 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
|
||||
case STORE_HANDLER_TYPE:
|
||||
StoreHandler::cast(*this).StoreHandlerPrint(os);
|
||||
break;
|
||||
case SCOPE_INFO_TYPE:
|
||||
ScopeInfo::cast(*this).ScopeInfoPrint(os);
|
||||
break;
|
||||
case FEEDBACK_METADATA_TYPE:
|
||||
FeedbackMetadata::cast(*this).FeedbackMetadataPrint(os);
|
||||
break;
|
||||
|
@ -676,8 +676,11 @@ template <typename Impl>
|
||||
Handle<ScopeInfo> FactoryBase<Impl>::NewScopeInfo(int length,
|
||||
AllocationType type) {
|
||||
DCHECK(type == AllocationType::kOld || type == AllocationType::kReadOnly);
|
||||
return Handle<ScopeInfo>::cast(NewFixedArrayWithMap(
|
||||
read_only_roots().scope_info_map_handle(), length, type));
|
||||
Handle<HeapObject> result =
|
||||
Handle<HeapObject>::cast(NewFixedArray(length, type));
|
||||
result->set_map_after_allocation(*read_only_roots().scope_info_map_handle(),
|
||||
SKIP_WRITE_BARRIER);
|
||||
return Handle<ScopeInfo>::cast(result);
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
|
@ -14,46 +14,47 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
#define TYPED_VISITOR_ID_LIST(V) \
|
||||
V(AllocationSite) \
|
||||
V(BigInt) \
|
||||
V(ByteArray) \
|
||||
V(BytecodeArray) \
|
||||
V(Cell) \
|
||||
V(Code) \
|
||||
V(CodeDataContainer) \
|
||||
V(CoverageInfo) \
|
||||
V(DataHandler) \
|
||||
V(EmbedderDataArray) \
|
||||
V(EphemeronHashTable) \
|
||||
V(FeedbackCell) \
|
||||
V(FeedbackMetadata) \
|
||||
V(FixedDoubleArray) \
|
||||
V(JSArrayBuffer) \
|
||||
V(JSDataView) \
|
||||
V(JSFunction) \
|
||||
V(JSObject) \
|
||||
V(JSTypedArray) \
|
||||
V(WeakCell) \
|
||||
V(JSWeakCollection) \
|
||||
V(JSWeakRef) \
|
||||
V(Map) \
|
||||
V(NativeContext) \
|
||||
V(PreparseData) \
|
||||
V(PropertyArray) \
|
||||
V(PropertyCell) \
|
||||
V(PrototypeInfo) \
|
||||
V(SmallOrderedHashMap) \
|
||||
V(SmallOrderedHashSet) \
|
||||
V(SmallOrderedNameDictionary) \
|
||||
V(SourceTextModule) \
|
||||
V(Symbol) \
|
||||
V(SyntheticModule) \
|
||||
V(TransitionArray) \
|
||||
V(WasmArray) \
|
||||
V(WasmIndirectFunctionTable) \
|
||||
V(WasmInstanceObject) \
|
||||
V(WasmStruct) \
|
||||
#define TYPED_VISITOR_ID_LIST(V) \
|
||||
V(AllocationSite) \
|
||||
V(BigInt) \
|
||||
V(ByteArray) \
|
||||
V(BytecodeArray) \
|
||||
V(Cell) \
|
||||
V(Code) \
|
||||
V(CodeDataContainer) \
|
||||
V(CoverageInfo) \
|
||||
V(DataHandler) \
|
||||
V(EmbedderDataArray) \
|
||||
V(EphemeronHashTable) \
|
||||
V(FeedbackCell) \
|
||||
V(FeedbackMetadata) \
|
||||
V(FixedDoubleArray) \
|
||||
V(JSArrayBuffer) \
|
||||
V(JSDataView) \
|
||||
V(JSFunction) \
|
||||
V(JSObject) \
|
||||
V(JSTypedArray) \
|
||||
V(WeakCell) \
|
||||
V(JSWeakCollection) \
|
||||
V(JSWeakRef) \
|
||||
V(Map) \
|
||||
V(NativeContext) \
|
||||
V(PreparseData) \
|
||||
V(PropertyArray) \
|
||||
V(PropertyCell) \
|
||||
V(PrototypeInfo) \
|
||||
V(ScopeInfo) \
|
||||
V(SmallOrderedHashMap) \
|
||||
V(SmallOrderedHashSet) \
|
||||
V(SmallOrderedNameDictionary) \
|
||||
V(SourceTextModule) \
|
||||
V(Symbol) \
|
||||
V(SyntheticModule) \
|
||||
V(TransitionArray) \
|
||||
V(WasmArray) \
|
||||
V(WasmIndirectFunctionTable) \
|
||||
V(WasmInstanceObject) \
|
||||
V(WasmStruct) \
|
||||
V(WasmTypeInfo)
|
||||
|
||||
#define FORWARD_DECLARE(TypeName) class TypeName;
|
||||
|
@ -532,16 +532,16 @@ bool Heap::CreateInitialMaps() {
|
||||
AllocationType::kReadOnly);
|
||||
if (!alloc.To(&obj)) return false;
|
||||
obj.set_map_after_allocation(roots.scope_info_map(), SKIP_WRITE_BARRIER);
|
||||
FixedArray::cast(obj).set_length(ScopeInfo::kVariablePartIndex);
|
||||
ScopeInfo::cast(obj).set_length(ScopeInfo::kVariablePartIndex);
|
||||
int flags = ScopeInfo::IsEmptyBit::encode(true);
|
||||
DCHECK_EQ(ScopeInfo::LanguageModeBit::decode(flags), LanguageMode::kSloppy);
|
||||
DCHECK_EQ(ScopeInfo::ReceiverVariableBits::decode(flags),
|
||||
VariableAllocationInfo::NONE);
|
||||
DCHECK_EQ(ScopeInfo::FunctionVariableBits::decode(flags),
|
||||
VariableAllocationInfo::NONE);
|
||||
ScopeInfo::cast(obj).SetFlags(flags);
|
||||
ScopeInfo::cast(obj).SetContextLocalCount(0);
|
||||
ScopeInfo::cast(obj).SetParameterCount(0);
|
||||
ScopeInfo::cast(obj).set_flags(flags);
|
||||
ScopeInfo::cast(obj).set_context_local_count(0);
|
||||
ScopeInfo::cast(obj).set_parameter_count(0);
|
||||
}
|
||||
set_empty_scope_info(ScopeInfo::cast(obj));
|
||||
|
||||
|
@ -3067,13 +3067,11 @@ void AccessorAssembler::ScriptContextTableLookup(
|
||||
ScriptContextTable::kFirstContextSlotIndex * kTaggedSize));
|
||||
TNode<ScopeInfo> scope_info =
|
||||
CAST(LoadContextElement(script_context, Context::SCOPE_INFO_INDEX));
|
||||
TNode<IntPtrT> length = LoadAndUntagFixedArrayBaseLength(scope_info);
|
||||
GotoIf(IntPtrLessThanOrEqual(length, IntPtrConstant(0)), &loop);
|
||||
|
||||
TVARIABLE(IntPtrT, scope_var_index,
|
||||
IntPtrConstant(ScopeInfo::kVariablePartIndex - 1));
|
||||
TNode<IntPtrT> num_scope_vars = SmiUntag(CAST(LoadFixedArrayElement(
|
||||
scope_info, IntPtrConstant(ScopeInfo::Fields::kContextLocalCount))));
|
||||
TNode<IntPtrT> num_scope_vars = SmiUntag(
|
||||
CAST(LoadObjectField(scope_info, ScopeInfo::kContextLocalCountOffset)));
|
||||
TNode<IntPtrT> end_index = IntPtrAdd(
|
||||
num_scope_vars, IntPtrConstant(ScopeInfo::kVariablePartIndex));
|
||||
Label loop_scope_info(this, &scope_var_index);
|
||||
@ -3085,8 +3083,9 @@ void AccessorAssembler::ScriptContextTableLookup(
|
||||
GotoIf(IntPtrGreaterThanOrEqual(scope_var_index.value(), end_index),
|
||||
&loop);
|
||||
|
||||
TNode<Object> var_name =
|
||||
LoadFixedArrayElement(scope_info, scope_var_index.value(), 0);
|
||||
FixedArrayBoundsCheck(scope_info, scope_var_index.value(), 0);
|
||||
TNode<Object> var_name = CAST(LoadArrayElement(
|
||||
scope_info, FixedArray::kHeaderSize, scope_var_index.value()));
|
||||
GotoIf(TaggedNotEqual(var_name, name), &loop_scope_info);
|
||||
|
||||
TNode<IntPtrT> var_index =
|
||||
|
@ -68,6 +68,7 @@
|
||||
#include "src/objects/property-cell-inl.h"
|
||||
#include "src/objects/property-descriptor-object-inl.h"
|
||||
#include "src/objects/prototype-info-inl.h"
|
||||
#include "src/objects/scope-info-inl.h"
|
||||
#include "src/objects/script-inl.h"
|
||||
#include "src/objects/shared-function-info-inl.h"
|
||||
#include "src/objects/slots-atomic-inl.h"
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "src/objects/tagged-field.h"
|
||||
#include "src/roots/roots.h"
|
||||
#include "src/torque/runtime-macro-shims.h"
|
||||
#include "src/torque/runtime-support.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
#include "src/objects/object-macros.h"
|
||||
|
@ -154,7 +154,6 @@ VisitorId Map::GetVisitorId(Map map) {
|
||||
case GLOBAL_DICTIONARY_TYPE:
|
||||
case NUMBER_DICTIONARY_TYPE:
|
||||
case SIMPLE_NUMBER_DICTIONARY_TYPE:
|
||||
case SCOPE_INFO_TYPE:
|
||||
case SCRIPT_CONTEXT_TABLE_TYPE:
|
||||
return kVisitFixedArray;
|
||||
|
||||
@ -190,6 +189,9 @@ VisitorId Map::GetVisitorId(Map map) {
|
||||
case MAP_TYPE:
|
||||
return kVisitMap;
|
||||
|
||||
case SCOPE_INFO_TYPE:
|
||||
return kVisitScopeInfo;
|
||||
|
||||
case CODE_TYPE:
|
||||
return kVisitCode;
|
||||
|
||||
|
@ -32,46 +32,47 @@ enum InstanceType : uint16_t;
|
||||
V(FeedbackMetadata) \
|
||||
V(FixedDoubleArray)
|
||||
|
||||
#define POINTER_VISITOR_ID_LIST(V) \
|
||||
V(AllocationSite) \
|
||||
V(BytecodeArray) \
|
||||
V(Cell) \
|
||||
V(Code) \
|
||||
V(CodeDataContainer) \
|
||||
V(DataHandler) \
|
||||
V(EmbedderDataArray) \
|
||||
V(EphemeronHashTable) \
|
||||
V(FeedbackCell) \
|
||||
V(FreeSpace) \
|
||||
V(JSApiObject) \
|
||||
V(JSArrayBuffer) \
|
||||
V(JSDataView) \
|
||||
V(JSFunction) \
|
||||
V(JSObject) \
|
||||
V(JSObjectFast) \
|
||||
V(JSTypedArray) \
|
||||
V(JSWeakRef) \
|
||||
V(JSWeakCollection) \
|
||||
V(Map) \
|
||||
V(NativeContext) \
|
||||
V(PreparseData) \
|
||||
V(PropertyArray) \
|
||||
V(PropertyCell) \
|
||||
V(PrototypeInfo) \
|
||||
V(ShortcutCandidate) \
|
||||
V(SmallOrderedHashMap) \
|
||||
V(SmallOrderedHashSet) \
|
||||
V(SmallOrderedNameDictionary) \
|
||||
V(SourceTextModule) \
|
||||
V(Struct) \
|
||||
V(Symbol) \
|
||||
V(SyntheticModule) \
|
||||
V(TransitionArray) \
|
||||
V(WasmIndirectFunctionTable) \
|
||||
V(WasmInstanceObject) \
|
||||
V(WasmArray) \
|
||||
V(WasmStruct) \
|
||||
V(WasmTypeInfo) \
|
||||
#define POINTER_VISITOR_ID_LIST(V) \
|
||||
V(AllocationSite) \
|
||||
V(BytecodeArray) \
|
||||
V(Cell) \
|
||||
V(Code) \
|
||||
V(CodeDataContainer) \
|
||||
V(DataHandler) \
|
||||
V(EmbedderDataArray) \
|
||||
V(EphemeronHashTable) \
|
||||
V(FeedbackCell) \
|
||||
V(FreeSpace) \
|
||||
V(JSApiObject) \
|
||||
V(JSArrayBuffer) \
|
||||
V(JSDataView) \
|
||||
V(JSFunction) \
|
||||
V(JSObject) \
|
||||
V(JSObjectFast) \
|
||||
V(JSTypedArray) \
|
||||
V(JSWeakRef) \
|
||||
V(JSWeakCollection) \
|
||||
V(Map) \
|
||||
V(NativeContext) \
|
||||
V(PreparseData) \
|
||||
V(PropertyArray) \
|
||||
V(PropertyCell) \
|
||||
V(PrototypeInfo) \
|
||||
V(ScopeInfo) \
|
||||
V(ShortcutCandidate) \
|
||||
V(SmallOrderedHashMap) \
|
||||
V(SmallOrderedHashSet) \
|
||||
V(SmallOrderedNameDictionary) \
|
||||
V(SourceTextModule) \
|
||||
V(Struct) \
|
||||
V(Symbol) \
|
||||
V(SyntheticModule) \
|
||||
V(TransitionArray) \
|
||||
V(WasmIndirectFunctionTable) \
|
||||
V(WasmInstanceObject) \
|
||||
V(WasmArray) \
|
||||
V(WasmStruct) \
|
||||
V(WasmTypeInfo) \
|
||||
V(WeakCell)
|
||||
|
||||
#define TORQUE_VISITOR_ID_LIST(V) \
|
||||
|
@ -898,7 +898,6 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
|
||||
case GLOBAL_DICTIONARY_TYPE:
|
||||
case NUMBER_DICTIONARY_TYPE:
|
||||
case SIMPLE_NUMBER_DICTIONARY_TYPE:
|
||||
case SCOPE_INFO_TYPE:
|
||||
case SCRIPT_CONTEXT_TABLE_TYPE:
|
||||
return Op::template apply<FixedArray::BodyDescriptor>(p1, p2, p3, p4);
|
||||
case EPHEMERON_HASH_TABLE_TYPE:
|
||||
@ -997,6 +996,8 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
|
||||
case WASM_MODULE_OBJECT_TYPE:
|
||||
case WASM_TABLE_OBJECT_TYPE:
|
||||
return Op::template apply<JSObject::BodyDescriptor>(p1, p2, p3, p4);
|
||||
case SCOPE_INFO_TYPE:
|
||||
return Op::template apply<ScopeInfo::BodyDescriptor>(p1, p2, p3, p4);
|
||||
case WASM_INSTANCE_OBJECT_TYPE:
|
||||
return Op::template apply<WasmInstanceObject::BodyDescriptor>(p1, p2, p3,
|
||||
p4);
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "src/objects/property-details.h"
|
||||
#include "src/objects/property.h"
|
||||
#include "src/objects/regexp-match-info.h"
|
||||
#include "src/objects/scope-info.h"
|
||||
#include "src/objects/scope-info-inl.h"
|
||||
#include "src/objects/shared-function-info.h"
|
||||
#include "src/objects/slots-inl.h"
|
||||
#include "src/objects/smi-inl.h"
|
||||
@ -450,7 +450,6 @@ bool Object::IsMinusZero() const {
|
||||
}
|
||||
|
||||
OBJECT_CONSTRUCTORS_IMPL(RegExpMatchInfo, FixedArray)
|
||||
OBJECT_CONSTRUCTORS_IMPL(ScopeInfo, FixedArray)
|
||||
OBJECT_CONSTRUCTORS_IMPL(BigIntBase, PrimitiveHeapObject)
|
||||
OBJECT_CONSTRUCTORS_IMPL(BigInt, BigIntBase)
|
||||
OBJECT_CONSTRUCTORS_IMPL(FreshlyAllocatedBigInt, BigIntBase)
|
||||
@ -461,7 +460,6 @@ OBJECT_CONSTRUCTORS_IMPL(FreshlyAllocatedBigInt, BigIntBase)
|
||||
CAST_ACCESSOR(BigIntBase)
|
||||
CAST_ACCESSOR(BigInt)
|
||||
CAST_ACCESSOR(RegExpMatchInfo)
|
||||
CAST_ACCESSOR(ScopeInfo)
|
||||
|
||||
bool Object::HasValidElements() {
|
||||
// Dictionary is covered under FixedArray. ByteArray is used
|
||||
@ -1119,21 +1117,6 @@ static inline Handle<Object> MakeEntryPair(Isolate* isolate, Handle<Object> key,
|
||||
PACKED_ELEMENTS, 2);
|
||||
}
|
||||
|
||||
bool ScopeInfo::IsAsmModule() const { return IsAsmModuleBit::decode(Flags()); }
|
||||
|
||||
bool ScopeInfo::HasSimpleParameters() const {
|
||||
return HasSimpleParametersBit::decode(Flags());
|
||||
}
|
||||
|
||||
#define FIELD_ACCESSORS(name) \
|
||||
void ScopeInfo::Set##name(int value) { set(k##name, Smi::FromInt(value)); } \
|
||||
int ScopeInfo::name() const { \
|
||||
DCHECK_GE(length(), kVariablePartIndex); \
|
||||
return Smi::ToInt(get(k##name)); \
|
||||
}
|
||||
FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS)
|
||||
#undef FIELD_ACCESSORS
|
||||
|
||||
FreshlyAllocatedBigInt FreshlyAllocatedBigInt::cast(Object object) {
|
||||
SLOW_DCHECK(object.IsBigInt());
|
||||
return FreshlyAllocatedBigInt(object.ptr());
|
||||
|
@ -2298,6 +2298,9 @@ int HeapObject::SizeFromMap(Map map) const {
|
||||
return FeedbackVector::SizeFor(
|
||||
FeedbackVector::unchecked_cast(*this).length());
|
||||
}
|
||||
if (instance_type == SCOPE_INFO_TYPE) {
|
||||
return FixedArray::SizeFor(ScopeInfo::unchecked_cast(*this).length());
|
||||
}
|
||||
if (instance_type == BIGINT_TYPE) {
|
||||
return BigInt::SizeFor(BigInt::unchecked_cast(*this).length());
|
||||
}
|
||||
|
82
src/objects/scope-info-inl.h
Normal file
82
src/objects/scope-info-inl.h
Normal file
@ -0,0 +1,82 @@
|
||||
// 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_SCOPE_INFO_INL_H_
|
||||
#define V8_OBJECTS_SCOPE_INFO_INL_H_
|
||||
|
||||
#include "src/heap/heap-write-barrier-inl.h"
|
||||
#include "src/objects/fixed-array-inl.h"
|
||||
#include "src/objects/scope-info.h"
|
||||
#include "src/objects/string.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
#include "src/objects/object-macros.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
#include "torque-generated/src/objects/scope-info-tq-inl.inc"
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(ScopeInfo)
|
||||
|
||||
bool ScopeInfo::IsAsmModule() const { return IsAsmModuleBit::decode(Flags()); }
|
||||
|
||||
bool ScopeInfo::HasSimpleParameters() const {
|
||||
return HasSimpleParametersBit::decode(Flags());
|
||||
}
|
||||
|
||||
int ScopeInfo::Flags() const { return flags(); }
|
||||
int ScopeInfo::ParameterCount() const { return parameter_count(); }
|
||||
int ScopeInfo::ContextLocalCount() const { return context_local_count(); }
|
||||
|
||||
Object ScopeInfo::get(int index) const {
|
||||
IsolateRoot isolate = GetIsolateForPtrCompr(*this);
|
||||
return get(isolate, index);
|
||||
}
|
||||
|
||||
Object ScopeInfo::get(IsolateRoot isolate, int index) const {
|
||||
DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
|
||||
return TaggedField<Object>::Relaxed_Load(
|
||||
isolate, *this, FixedArray::OffsetOfElementAt(index));
|
||||
}
|
||||
|
||||
void ScopeInfo::set(int index, Smi value) {
|
||||
DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map());
|
||||
DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
|
||||
DCHECK(Object(value).IsSmi());
|
||||
int offset = FixedArray::OffsetOfElementAt(index);
|
||||
RELAXED_WRITE_FIELD(*this, offset, value);
|
||||
}
|
||||
|
||||
void ScopeInfo::set(int index, Object value, WriteBarrierMode mode) {
|
||||
DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map());
|
||||
DCHECK(IsScopeInfo());
|
||||
DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
|
||||
int offset = FixedArray::OffsetOfElementAt(index);
|
||||
RELAXED_WRITE_FIELD(*this, offset, value);
|
||||
CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode);
|
||||
}
|
||||
|
||||
void ScopeInfo::CopyElements(Isolate* isolate, int dst_index, ScopeInfo src,
|
||||
int src_index, int len, WriteBarrierMode mode) {
|
||||
if (len == 0) return;
|
||||
DCHECK_LE(dst_index + len, length());
|
||||
DCHECK_LE(src_index + len, src.length());
|
||||
DisallowGarbageCollection no_gc;
|
||||
|
||||
ObjectSlot dst_slot(RawFieldOfElementAt(dst_index));
|
||||
ObjectSlot src_slot(src.RawFieldOfElementAt(src_index));
|
||||
isolate->heap()->CopyRange(*this, dst_slot, src_slot, len, mode);
|
||||
}
|
||||
|
||||
ObjectSlot ScopeInfo::RawFieldOfElementAt(int index) {
|
||||
return RawField(FixedArray::OffsetOfElementAt(index));
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#include "src/objects/object-macros-undef.h"
|
||||
|
||||
#endif // V8_OBJECTS_SCOPE_INFO_INL_H_
|
@ -11,6 +11,7 @@
|
||||
#include "src/init/bootstrapper.h"
|
||||
#include "src/objects/module-inl.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
#include "src/objects/scope-info-inl.h"
|
||||
#include "src/objects/string-set-inl.h"
|
||||
#include "src/roots/roots.h"
|
||||
|
||||
@ -157,6 +158,12 @@ Handle<ScopeInfo> ScopeInfo::Create(LocalIsolate* isolate, Zone* zone,
|
||||
: 0;
|
||||
const bool has_outer_scope_info = !outer_scope.is_null();
|
||||
|
||||
Handle<SourceTextModuleInfo> module_info;
|
||||
if (scope->is_module_scope()) {
|
||||
module_info = SourceTextModuleInfo::New(isolate, zone,
|
||||
scope->AsModuleScope()->module());
|
||||
}
|
||||
|
||||
const int length = kVariablePartIndex + 2 * context_local_count +
|
||||
(should_save_class_variable_index ? 1 : 0) +
|
||||
(has_receiver ? 1 : 0) +
|
||||
@ -216,16 +223,16 @@ Handle<ScopeInfo> ScopeInfo::Create(LocalIsolate* isolate, Zone* zone,
|
||||
HasContextExtensionSlotBit::encode(scope->HasContextExtensionSlot()) |
|
||||
IsReplModeScopeBit::encode(scope->is_repl_mode_scope()) |
|
||||
HasLocalsBlockListBit::encode(false);
|
||||
scope_info.SetFlags(flags);
|
||||
scope_info.set_flags(flags);
|
||||
|
||||
scope_info.SetParameterCount(parameter_count);
|
||||
scope_info.SetContextLocalCount(context_local_count);
|
||||
scope_info.set_parameter_count(parameter_count);
|
||||
scope_info.set_context_local_count(context_local_count);
|
||||
|
||||
// Add context locals' names and info, module variables' names and info.
|
||||
// Context locals are added using their index.
|
||||
int context_local_base = index;
|
||||
int context_local_info_base = context_local_base + context_local_count;
|
||||
int module_var_entry = scope_info.ModuleVariablesIndex();
|
||||
int module_var_entry = scope_info.ModuleVariableCountIndex() + 1;
|
||||
|
||||
for (Variable* var : *scope->locals()) {
|
||||
switch (var->location()) {
|
||||
@ -237,11 +244,11 @@ Handle<ScopeInfo> ScopeInfo::Create(LocalIsolate* isolate, Zone* zone,
|
||||
DCHECK_LE(0, local_index);
|
||||
DCHECK_LT(local_index, context_local_count);
|
||||
uint32_t info =
|
||||
VariableModeField::encode(var->mode()) |
|
||||
InitFlagField::encode(var->initialization_flag()) |
|
||||
MaybeAssignedFlagField::encode(var->maybe_assigned()) |
|
||||
ParameterNumberField::encode(ParameterNumberField::kMax) |
|
||||
IsStaticFlagField::encode(var->is_static_flag());
|
||||
VariableModeBits::encode(var->mode()) |
|
||||
InitFlagBit::encode(var->initialization_flag()) |
|
||||
MaybeAssignedFlagBit::encode(var->maybe_assigned()) |
|
||||
ParameterNumberBits::encode(ParameterNumberBits::kMax) |
|
||||
IsStaticFlagBit::encode(var->is_static_flag());
|
||||
scope_info.set(context_local_base + local_index, *var->name(), mode);
|
||||
scope_info.set(context_local_info_base + local_index,
|
||||
Smi::FromInt(info));
|
||||
@ -253,11 +260,11 @@ Handle<ScopeInfo> ScopeInfo::Create(LocalIsolate* isolate, Zone* zone,
|
||||
scope_info.set(module_var_entry + kModuleVariableIndexOffset,
|
||||
Smi::FromInt(var->index()));
|
||||
uint32_t properties =
|
||||
VariableModeField::encode(var->mode()) |
|
||||
InitFlagField::encode(var->initialization_flag()) |
|
||||
MaybeAssignedFlagField::encode(var->maybe_assigned()) |
|
||||
ParameterNumberField::encode(ParameterNumberField::kMax) |
|
||||
IsStaticFlagField::encode(var->is_static_flag());
|
||||
VariableModeBits::encode(var->mode()) |
|
||||
InitFlagBit::encode(var->initialization_flag()) |
|
||||
MaybeAssignedFlagBit::encode(var->maybe_assigned()) |
|
||||
ParameterNumberBits::encode(ParameterNumberBits::kMax) |
|
||||
IsStaticFlagBit::encode(var->is_static_flag());
|
||||
scope_info.set(module_var_entry + kModuleVariablePropertiesOffset,
|
||||
Smi::FromInt(properties));
|
||||
module_var_entry += kModuleVariableEntryLength;
|
||||
@ -282,7 +289,7 @@ Handle<ScopeInfo> ScopeInfo::Create(LocalIsolate* isolate, Zone* zone,
|
||||
int index = parameter->index() - scope->ContextHeaderLength();
|
||||
int info_index = context_local_info_base + index;
|
||||
int info = Smi::ToInt(scope_info.get(info_index));
|
||||
info = ParameterNumberField::update(info, i);
|
||||
info = ParameterNumberBits::update(info, i);
|
||||
scope_info.set(info_index, Smi::FromInt(info));
|
||||
}
|
||||
|
||||
@ -292,11 +299,11 @@ Handle<ScopeInfo> ScopeInfo::Create(LocalIsolate* isolate, Zone* zone,
|
||||
if (var->location() == VariableLocation::CONTEXT) {
|
||||
int local_index = var->index() - scope->ContextHeaderLength();
|
||||
uint32_t info =
|
||||
VariableModeField::encode(var->mode()) |
|
||||
InitFlagField::encode(var->initialization_flag()) |
|
||||
MaybeAssignedFlagField::encode(var->maybe_assigned()) |
|
||||
ParameterNumberField::encode(ParameterNumberField::kMax) |
|
||||
IsStaticFlagField::encode(var->is_static_flag());
|
||||
VariableModeBits::encode(var->mode()) |
|
||||
InitFlagBit::encode(var->initialization_flag()) |
|
||||
MaybeAssignedFlagBit::encode(var->maybe_assigned()) |
|
||||
ParameterNumberBits::encode(ParameterNumberBits::kMax) |
|
||||
IsStaticFlagBit::encode(var->is_static_flag());
|
||||
scope_info.set(context_local_base + local_index, *var->name(), mode);
|
||||
scope_info.set(context_local_info_base + local_index,
|
||||
Smi::FromInt(info));
|
||||
@ -358,19 +365,17 @@ Handle<ScopeInfo> ScopeInfo::Create(LocalIsolate* isolate, Zone* zone,
|
||||
if (has_outer_scope_info) {
|
||||
scope_info.set(index++, *outer_scope.ToHandleChecked(), mode);
|
||||
}
|
||||
}
|
||||
|
||||
// Module-specific information (only for module scopes).
|
||||
if (scope->is_module_scope()) {
|
||||
Handle<SourceTextModuleInfo> module_info = SourceTextModuleInfo::New(
|
||||
isolate, zone, scope->AsModuleScope()->module());
|
||||
DCHECK_EQ(index, scope_info_handle->ModuleInfoIndex());
|
||||
scope_info_handle->set(index++, *module_info);
|
||||
DCHECK_EQ(index, scope_info_handle->ModuleVariableCountIndex());
|
||||
scope_info_handle->set(index++, Smi::FromInt(module_vars_count));
|
||||
DCHECK_EQ(index, scope_info_handle->ModuleVariablesIndex());
|
||||
// The variable entries themselves have already been written above.
|
||||
index += kModuleVariableEntryLength * module_vars_count;
|
||||
// Module-specific information (only for module scopes).
|
||||
if (scope->is_module_scope()) {
|
||||
DCHECK_EQ(index, scope_info.ModuleInfoIndex());
|
||||
scope_info.set(index++, *module_info);
|
||||
DCHECK_EQ(index, scope_info.ModuleVariableCountIndex());
|
||||
scope_info.set(index++, Smi::FromInt(module_vars_count));
|
||||
DCHECK_EQ(index, scope_info.ModuleVariablesIndex());
|
||||
// The variable entries themselves have already been written above.
|
||||
index += kModuleVariableEntryLength * module_vars_count;
|
||||
}
|
||||
}
|
||||
|
||||
DCHECK_EQ(index, scope_info_handle->length());
|
||||
@ -416,10 +421,10 @@ Handle<ScopeInfo> ScopeInfo::CreateForWithScope(
|
||||
PrivateNameLookupSkipsOuterClassBit::encode(false) |
|
||||
HasContextExtensionSlotBit::encode(true) |
|
||||
IsReplModeScopeBit::encode(false) | HasLocalsBlockListBit::encode(false);
|
||||
scope_info->SetFlags(flags);
|
||||
scope_info->set_flags(flags);
|
||||
|
||||
scope_info->SetParameterCount(0);
|
||||
scope_info->SetContextLocalCount(0);
|
||||
scope_info->set_parameter_count(0);
|
||||
scope_info->set_context_local_count(0);
|
||||
|
||||
int index = kVariablePartIndex;
|
||||
DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
|
||||
@ -496,9 +501,9 @@ Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate,
|
||||
PrivateNameLookupSkipsOuterClassBit::encode(false) |
|
||||
HasContextExtensionSlotBit::encode(is_native_context) |
|
||||
IsReplModeScopeBit::encode(false) | HasLocalsBlockListBit::encode(false);
|
||||
scope_info->SetFlags(flags);
|
||||
scope_info->SetParameterCount(parameter_count);
|
||||
scope_info->SetContextLocalCount(context_local_count);
|
||||
scope_info->set_flags(flags);
|
||||
scope_info->set_parameter_count(parameter_count);
|
||||
scope_info->set_context_local_count(context_local_count);
|
||||
|
||||
int index = kVariablePartIndex;
|
||||
|
||||
@ -510,11 +515,11 @@ Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate,
|
||||
DCHECK_EQ(index, scope_info->ContextLocalInfosIndex());
|
||||
if (context_local_count > 0) {
|
||||
const uint32_t value =
|
||||
VariableModeField::encode(VariableMode::kConst) |
|
||||
InitFlagField::encode(kCreatedInitialized) |
|
||||
MaybeAssignedFlagField::encode(kNotAssigned) |
|
||||
ParameterNumberField::encode(ParameterNumberField::kMax) |
|
||||
IsStaticFlagField::encode(IsStaticFlag::kNotStatic);
|
||||
VariableModeBits::encode(VariableMode::kConst) |
|
||||
InitFlagBit::encode(kCreatedInitialized) |
|
||||
MaybeAssignedFlagBit::encode(kNotAssigned) |
|
||||
ParameterNumberBits::encode(ParameterNumberBits::kMax) |
|
||||
IsStaticFlagBit::encode(IsStaticFlag::kNotStatic);
|
||||
scope_info->set(index++, Smi::FromInt(value));
|
||||
}
|
||||
|
||||
@ -564,7 +569,7 @@ Handle<ScopeInfo> ScopeInfo::RecreateWithBlockList(
|
||||
// blocklist field, so {LocalsBlockListIndex} returns the correct value.
|
||||
scope_info->CopyElements(isolate, 0, *original, 0, kVariablePartIndex,
|
||||
WriteBarrierMode::UPDATE_WRITE_BARRIER);
|
||||
scope_info->SetFlags(
|
||||
scope_info->set_flags(
|
||||
HasLocalsBlockListBit::update(scope_info->Flags(), true));
|
||||
|
||||
// Copy the dynamic part including the provided blocklist:
|
||||
@ -575,7 +580,7 @@ Handle<ScopeInfo> ScopeInfo::RecreateWithBlockList(
|
||||
isolate, kVariablePartIndex, *original, kVariablePartIndex,
|
||||
scope_info->LocalsBlockListIndex() - kVariablePartIndex,
|
||||
WriteBarrierMode::UPDATE_WRITE_BARRIER);
|
||||
scope_info->set(scope_info->LocalsBlockListIndex(), *blocklist);
|
||||
scope_info->set_locals_block_list(0, *blocklist);
|
||||
scope_info->CopyElements(
|
||||
isolate, scope_info->LocalsBlockListIndex() + 1, *original,
|
||||
scope_info->LocalsBlockListIndex(),
|
||||
@ -700,7 +705,7 @@ void ScopeInfo::SetFunctionName(Object name) {
|
||||
|
||||
void ScopeInfo::SetInferredFunctionName(String name) {
|
||||
DCHECK(HasInferredFunctionName());
|
||||
set(InferredFunctionNameIndex(), name);
|
||||
set_inferred_function_name(0, name);
|
||||
}
|
||||
|
||||
bool ScopeInfo::HasOuterScopeInfo() const {
|
||||
@ -714,7 +719,7 @@ bool ScopeInfo::IsDebugEvaluateScope() const {
|
||||
void ScopeInfo::SetIsDebugEvaluateScope() {
|
||||
CHECK(!IsEmpty());
|
||||
DCHECK_EQ(scope_type(), WITH_SCOPE);
|
||||
SetFlags(Flags() | IsDebugEvaluateScopeBit::encode(true));
|
||||
set_flags(Flags() | IsDebugEvaluateScopeBit::encode(true));
|
||||
}
|
||||
|
||||
bool ScopeInfo::PrivateNameLookupSkipsOuterClass() const {
|
||||
@ -731,7 +736,7 @@ bool ScopeInfo::HasLocalsBlockList() const {
|
||||
|
||||
StringSet ScopeInfo::LocalsBlockList() const {
|
||||
DCHECK(HasLocalsBlockList());
|
||||
return StringSet::cast(get(LocalsBlockListIndex()));
|
||||
return StringSet::cast(locals_block_list(0));
|
||||
}
|
||||
|
||||
bool ScopeInfo::HasContext() const { return ContextLength() > 0; }
|
||||
@ -743,7 +748,7 @@ Object ScopeInfo::FunctionName() const {
|
||||
|
||||
Object ScopeInfo::InferredFunctionName() const {
|
||||
DCHECK(HasInferredFunctionName());
|
||||
return get(InferredFunctionNameIndex());
|
||||
return inferred_function_name(0);
|
||||
}
|
||||
|
||||
String ScopeInfo::FunctionDebugName() const {
|
||||
@ -778,66 +783,47 @@ void ScopeInfo::SetPositionInfo(int start, int end) {
|
||||
|
||||
ScopeInfo ScopeInfo::OuterScopeInfo() const {
|
||||
DCHECK(HasOuterScopeInfo());
|
||||
return ScopeInfo::cast(get(OuterScopeInfoIndex()));
|
||||
return ScopeInfo::cast(outer_scope_info(0));
|
||||
}
|
||||
|
||||
SourceTextModuleInfo ScopeInfo::ModuleDescriptorInfo() const {
|
||||
DCHECK(scope_type() == MODULE_SCOPE);
|
||||
return SourceTextModuleInfo::cast(get(ModuleInfoIndex()));
|
||||
return SourceTextModuleInfo::cast(module_info(0));
|
||||
}
|
||||
|
||||
String ScopeInfo::ContextLocalName(int var) const {
|
||||
DCHECK_LE(0, var);
|
||||
DCHECK_LT(var, ContextLocalCount());
|
||||
int info_index = ContextLocalNamesIndex() + var;
|
||||
return String::cast(get(info_index));
|
||||
return context_local_names(var);
|
||||
}
|
||||
|
||||
VariableMode ScopeInfo::ContextLocalMode(int var) const {
|
||||
DCHECK_LE(0, var);
|
||||
DCHECK_LT(var, ContextLocalCount());
|
||||
int info_index = ContextLocalInfosIndex() + var;
|
||||
int value = Smi::ToInt(get(info_index));
|
||||
return VariableModeField::decode(value);
|
||||
int value = context_local_infos(var);
|
||||
return VariableModeBits::decode(value);
|
||||
}
|
||||
|
||||
IsStaticFlag ScopeInfo::ContextLocalIsStaticFlag(int var) const {
|
||||
DCHECK_LE(0, var);
|
||||
DCHECK_LT(var, ContextLocalCount());
|
||||
int info_index = ContextLocalInfosIndex() + var;
|
||||
int value = Smi::ToInt(get(info_index));
|
||||
return IsStaticFlagField::decode(value);
|
||||
int value = context_local_infos(var);
|
||||
return IsStaticFlagBit::decode(value);
|
||||
}
|
||||
|
||||
InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) const {
|
||||
DCHECK_LE(0, var);
|
||||
DCHECK_LT(var, ContextLocalCount());
|
||||
int info_index = ContextLocalInfosIndex() + var;
|
||||
int value = Smi::ToInt(get(info_index));
|
||||
return InitFlagField::decode(value);
|
||||
int value = context_local_infos(var);
|
||||
return InitFlagBit::decode(value);
|
||||
}
|
||||
|
||||
bool ScopeInfo::ContextLocalIsParameter(int var) const {
|
||||
DCHECK_LE(0, var);
|
||||
DCHECK_LT(var, ContextLocalCount());
|
||||
int info_index = ContextLocalInfosIndex() + var;
|
||||
int value = Smi::ToInt(get(info_index));
|
||||
return ParameterNumberField::decode(value) != ParameterNumberField::kMax;
|
||||
int value = context_local_infos(var);
|
||||
return ParameterNumberBits::decode(value) != ParameterNumberBits::kMax;
|
||||
}
|
||||
|
||||
uint32_t ScopeInfo::ContextLocalParameterNumber(int var) const {
|
||||
DCHECK(ContextLocalIsParameter(var));
|
||||
int info_index = ContextLocalInfosIndex() + var;
|
||||
int value = Smi::ToInt(get(info_index));
|
||||
return ParameterNumberField::decode(value);
|
||||
int value = context_local_infos(var);
|
||||
return ParameterNumberBits::decode(value);
|
||||
}
|
||||
|
||||
MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) const {
|
||||
DCHECK_LE(0, var);
|
||||
DCHECK_LT(var, ContextLocalCount());
|
||||
int info_index = ContextLocalInfosIndex() + var;
|
||||
int value = Smi::ToInt(get(info_index));
|
||||
return MaybeAssignedFlagField::decode(value);
|
||||
int value = context_local_infos(var);
|
||||
return MaybeAssignedFlagBit::decode(value);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -860,7 +846,7 @@ int ScopeInfo::ModuleIndex(String name, VariableMode* mode,
|
||||
DCHECK_NOT_NULL(init_flag);
|
||||
DCHECK_NOT_NULL(maybe_assigned_flag);
|
||||
|
||||
int module_vars_count = Smi::ToInt(get(ModuleVariableCountIndex()));
|
||||
int module_vars_count = module_variable_count(0);
|
||||
int entry = ModuleVariablesIndex();
|
||||
for (int i = 0; i < module_vars_count; ++i) {
|
||||
String var_name = String::cast(get(entry + kModuleVariableNameOffset));
|
||||
@ -890,7 +876,7 @@ int ScopeInfo::ContextSlotIndex(ScopeInfo scope_info, String name,
|
||||
if (scope_info.IsEmpty()) return -1;
|
||||
|
||||
int start = scope_info.ContextLocalNamesIndex();
|
||||
int end = start + scope_info.ContextLocalCount();
|
||||
int end = start + scope_info.context_local_count();
|
||||
for (int i = start; i < end; ++i) {
|
||||
if (name != scope_info.get(i)) continue;
|
||||
int var = i - start;
|
||||
@ -909,7 +895,7 @@ int ScopeInfo::ContextSlotIndex(ScopeInfo scope_info, String name,
|
||||
|
||||
int ScopeInfo::SavedClassVariableContextLocalIndex() const {
|
||||
if (HasSavedClassVariableIndexBit::decode(Flags())) {
|
||||
int index = Smi::ToInt(get(SavedClassVariableInfoIndex()));
|
||||
int index = saved_class_variable_info(0);
|
||||
return index - Context::MIN_CONTEXT_SLOTS;
|
||||
}
|
||||
return -1;
|
||||
@ -918,7 +904,7 @@ int ScopeInfo::SavedClassVariableContextLocalIndex() const {
|
||||
int ScopeInfo::ReceiverContextSlotIndex() const {
|
||||
if (ReceiverVariableBits::decode(Flags()) ==
|
||||
VariableAllocationInfo::CONTEXT) {
|
||||
return Smi::ToInt(get(ReceiverInfoIndex()));
|
||||
return receiver_info(0);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -938,53 +924,51 @@ FunctionKind ScopeInfo::function_kind() const {
|
||||
}
|
||||
|
||||
int ScopeInfo::ContextLocalNamesIndex() const {
|
||||
DCHECK_LE(kVariablePartIndex, length());
|
||||
return kVariablePartIndex;
|
||||
return ConvertOffsetToIndex(kContextLocalNamesOffset);
|
||||
}
|
||||
|
||||
int ScopeInfo::ContextLocalInfosIndex() const {
|
||||
return ContextLocalNamesIndex() + ContextLocalCount();
|
||||
return ConvertOffsetToIndex(ContextLocalInfosOffset());
|
||||
}
|
||||
|
||||
int ScopeInfo::SavedClassVariableInfoIndex() const {
|
||||
return ContextLocalInfosIndex() + ContextLocalCount();
|
||||
return ConvertOffsetToIndex(SavedClassVariableInfoOffset());
|
||||
}
|
||||
|
||||
int ScopeInfo::ReceiverInfoIndex() const {
|
||||
return SavedClassVariableInfoIndex() + (HasSavedClassVariableIndex() ? 1 : 0);
|
||||
return ConvertOffsetToIndex(ReceiverInfoOffset());
|
||||
}
|
||||
|
||||
int ScopeInfo::FunctionNameInfoIndex() const {
|
||||
return ReceiverInfoIndex() + (HasAllocatedReceiver() ? 1 : 0);
|
||||
return ConvertOffsetToIndex(FunctionNameInfoOffset());
|
||||
}
|
||||
|
||||
int ScopeInfo::InferredFunctionNameIndex() const {
|
||||
return FunctionNameInfoIndex() +
|
||||
(HasFunctionName() ? kFunctionNameEntries : 0);
|
||||
return ConvertOffsetToIndex(InferredFunctionNameOffset());
|
||||
}
|
||||
|
||||
int ScopeInfo::PositionInfoIndex() const {
|
||||
return InferredFunctionNameIndex() + (HasInferredFunctionName() ? 1 : 0);
|
||||
return ConvertOffsetToIndex(PositionInfoOffset());
|
||||
}
|
||||
|
||||
int ScopeInfo::OuterScopeInfoIndex() const {
|
||||
return PositionInfoIndex() + (HasPositionInfo() ? kPositionInfoEntries : 0);
|
||||
return ConvertOffsetToIndex(OuterScopeInfoOffset());
|
||||
}
|
||||
|
||||
int ScopeInfo::LocalsBlockListIndex() const {
|
||||
return OuterScopeInfoIndex() + (HasOuterScopeInfo() ? 1 : 0);
|
||||
return ConvertOffsetToIndex(LocalsBlockListOffset());
|
||||
}
|
||||
|
||||
int ScopeInfo::ModuleInfoIndex() const {
|
||||
return LocalsBlockListIndex() + (HasLocalsBlockList() ? 1 : 0);
|
||||
return ConvertOffsetToIndex(ModuleInfoOffset());
|
||||
}
|
||||
|
||||
int ScopeInfo::ModuleVariableCountIndex() const {
|
||||
return ModuleInfoIndex() + 1;
|
||||
return ConvertOffsetToIndex(ModuleVariableCountOffset());
|
||||
}
|
||||
|
||||
int ScopeInfo::ModuleVariablesIndex() const {
|
||||
return ModuleVariableCountIndex() + 1;
|
||||
return ConvertOffsetToIndex(ModuleVariablesOffset());
|
||||
}
|
||||
|
||||
void ScopeInfo::ModuleVariable(int i, String* name, int* index,
|
||||
@ -992,7 +976,7 @@ void ScopeInfo::ModuleVariable(int i, String* name, int* index,
|
||||
InitializationFlag* init_flag,
|
||||
MaybeAssignedFlag* maybe_assigned_flag) {
|
||||
DCHECK_LE(0, i);
|
||||
DCHECK_LT(i, Smi::ToInt(get(ModuleVariableCountIndex())));
|
||||
DCHECK_LT(i, module_variable_count(0));
|
||||
|
||||
int entry = ModuleVariablesIndex() + i * kModuleVariableEntryLength;
|
||||
int properties = Smi::ToInt(get(entry + kModuleVariablePropertiesOffset));
|
||||
@ -1005,13 +989,13 @@ void ScopeInfo::ModuleVariable(int i, String* name, int* index,
|
||||
DCHECK_NE(*index, 0);
|
||||
}
|
||||
if (mode != nullptr) {
|
||||
*mode = VariableModeField::decode(properties);
|
||||
*mode = VariableModeBits::decode(properties);
|
||||
}
|
||||
if (init_flag != nullptr) {
|
||||
*init_flag = InitFlagField::decode(properties);
|
||||
*init_flag = InitFlagBit::decode(properties);
|
||||
}
|
||||
if (maybe_assigned_flag != nullptr) {
|
||||
*maybe_assigned_flag = MaybeAssignedFlagField::decode(properties);
|
||||
*maybe_assigned_flag = MaybeAssignedFlagBit::decode(properties);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
#include "torque-generated/src/objects/scope-info-tq.inc"
|
||||
|
||||
template <typename T>
|
||||
class Handle;
|
||||
class Isolate;
|
||||
@ -36,12 +38,27 @@ class Zone;
|
||||
|
||||
// This object provides quick access to scope info details for runtime
|
||||
// routines.
|
||||
class ScopeInfo : public FixedArray {
|
||||
class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, FixedArrayBase> {
|
||||
public:
|
||||
DEFINE_TORQUE_GENERATED_SCOPE_FLAGS()
|
||||
|
||||
DECL_CAST(ScopeInfo)
|
||||
DECL_PRINTER(ScopeInfo)
|
||||
DECL_VERIFIER(ScopeInfo)
|
||||
|
||||
// For refactoring, clone some FixedArray member functions. Eventually this
|
||||
// class will stop pretending to be a FixedArray, but we're not quite there.
|
||||
inline Object get(int index) const;
|
||||
inline Object get(IsolateRoot isolate, int index) const;
|
||||
// Setter that doesn't need write barrier.
|
||||
inline void set(int index, Smi value);
|
||||
// Setter with explicit barrier mode.
|
||||
inline void set(int index, Object value,
|
||||
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
||||
inline void CopyElements(Isolate* isolate, int dst_index, ScopeInfo src,
|
||||
int src_index, int len, WriteBarrierMode mode);
|
||||
inline ObjectSlot RawFieldOfElementAt(int index);
|
||||
|
||||
using BodyDescriptor = FlexibleBodyDescriptor<kHeaderSize>;
|
||||
|
||||
// Return the type of this scope.
|
||||
ScopeType scope_type() const;
|
||||
@ -238,19 +255,12 @@ class ScopeInfo : public FixedArray {
|
||||
// Serializes empty scope info.
|
||||
V8_EXPORT_PRIVATE static ScopeInfo Empty(Isolate* isolate);
|
||||
|
||||
// The layout of the static part of a ScopeInfo is as follows. Each entry is
|
||||
// numeric and occupies one array slot.
|
||||
// 1. A set of properties of the scope.
|
||||
// 2. The number of parameters. For non-function scopes this is 0.
|
||||
// 3. The number of non-parameter and parameter variables allocated in the
|
||||
// context.
|
||||
#define FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(V) \
|
||||
V(Flags) \
|
||||
V(ParameterCount) \
|
||||
V(ContextLocalCount)
|
||||
|
||||
#define FIELD_ACCESSORS(name) \
|
||||
inline void Set##name(int value); \
|
||||
inline int name() const;
|
||||
FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS)
|
||||
#undef FIELD_ACCESSORS
|
||||
@ -262,7 +272,11 @@ class ScopeInfo : public FixedArray {
|
||||
kVariablePartIndex
|
||||
};
|
||||
|
||||
static const int kFlagsOffset = OffsetOfElementAt(Fields::kFlags);
|
||||
// Make sure the Fields enum agrees with Torque-generated offsets.
|
||||
#define ASSERT_MATCHED_FIELD(name) \
|
||||
STATIC_ASSERT(FixedArray::OffsetOfElementAt(k##name) == k##name##Offset);
|
||||
FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(ASSERT_MATCHED_FIELD)
|
||||
#undef ASSERT_MATCHED_FIELD
|
||||
|
||||
STATIC_ASSERT(LanguageModeSize == 1 << LanguageModeBit::kSize);
|
||||
STATIC_ASSERT(kLastFunctionKind <= FunctionKindBits::kMax);
|
||||
@ -270,44 +284,6 @@ class ScopeInfo : public FixedArray {
|
||||
bool IsEmpty() const;
|
||||
|
||||
private:
|
||||
// The layout of the variable part of a ScopeInfo is as follows:
|
||||
// 1. ContextLocalNames:
|
||||
// Contains the names of local variables and parameters that are allocated
|
||||
// in the context. They are stored in increasing order of the context slot
|
||||
// index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per
|
||||
// context local, so in total this part occupies ContextLocalCount() slots
|
||||
// in the array.
|
||||
// 2. ContextLocalInfos:
|
||||
// Contains the variable modes and initialization flags corresponding to
|
||||
// the context locals in ContextLocalNames. One slot is used per
|
||||
// context local, so in total this part occupies ContextLocalCount()
|
||||
// slots in the array.
|
||||
// 3. SavedClassVariableInfo:
|
||||
// If the scope is a class scope and it has static private methods that
|
||||
// may be accessed directly or through eval, one slot is reserved to hold
|
||||
// the context slot index for the class variable.
|
||||
// 4. ReceiverInfo:
|
||||
// If the scope binds a "this" value, one slot is reserved to hold the
|
||||
// context or stack slot index for the variable.
|
||||
// 5. FunctionNameInfo:
|
||||
// If the scope belongs to a named function expression this part contains
|
||||
// information about the function variable. It always occupies two array
|
||||
// slots: a. The name of the function variable.
|
||||
// b. The context or stack slot index for the variable.
|
||||
// 6. InferredFunctionName:
|
||||
// Contains the function's inferred name.
|
||||
// 7. SourcePosition:
|
||||
// Contains two slots with a) the startPosition and b) the endPosition if
|
||||
// the scope belongs to a function or script.
|
||||
// 8. OuterScopeInfoIndex:
|
||||
// The outer scope's ScopeInfo or the hole if there's none.
|
||||
// 9. LocalsBlockList: List of stack allocated local variables. Used by
|
||||
// debug evaluate to properly abort variable lookup when a name clashes
|
||||
// with a stack allocated local that can't be materialized.
|
||||
// 10. SourceTextModuleInfo, ModuleVariableCount, and ModuleVariables:
|
||||
// For a module scope, this part contains the SourceTextModuleInfo, the
|
||||
// number of MODULE-allocated variables, and the metadata of those
|
||||
// variables. For non-module scopes it is empty.
|
||||
int ContextLocalNamesIndex() const;
|
||||
int ContextLocalInfosIndex() const;
|
||||
int SavedClassVariableInfoIndex() const;
|
||||
@ -323,6 +299,13 @@ class ScopeInfo : public FixedArray {
|
||||
|
||||
static bool NeedsPositionInfo(ScopeType type);
|
||||
|
||||
// Converts byte offsets within the object to FixedArray-style indices.
|
||||
static constexpr int ConvertOffsetToIndex(int offset) {
|
||||
int index = (offset - FixedArray::kHeaderSize) / kTaggedSize;
|
||||
CONSTEXPR_DCHECK(FixedArray::OffsetOfElementAt(index) == offset);
|
||||
return index;
|
||||
}
|
||||
|
||||
enum class BootstrappingType { kScript, kFunction, kNative };
|
||||
static Handle<ScopeInfo> CreateForBootstrapping(Isolate* isolate,
|
||||
BootstrappingType type);
|
||||
@ -342,21 +325,13 @@ class ScopeInfo : public FixedArray {
|
||||
static const int kFunctionNameEntries = 2;
|
||||
static const int kPositionInfoEntries = 2;
|
||||
|
||||
// Hide an inherited member function to ensure that callers have been updated
|
||||
// to use IsEmpty instead.
|
||||
using FixedArray::length;
|
||||
|
||||
// Properties of variables.
|
||||
using VariableModeField = base::BitField<VariableMode, 0, 4>;
|
||||
using InitFlagField = VariableModeField::Next<InitializationFlag, 1>;
|
||||
using MaybeAssignedFlagField = InitFlagField::Next<MaybeAssignedFlag, 1>;
|
||||
using ParameterNumberField = MaybeAssignedFlagField::Next<uint32_t, 16>;
|
||||
using IsStaticFlagField = ParameterNumberField::Next<IsStaticFlag, 1>;
|
||||
DEFINE_TORQUE_GENERATED_VARIABLE_PROPERTIES()
|
||||
|
||||
friend class ScopeIterator;
|
||||
friend std::ostream& operator<<(std::ostream& os, VariableAllocationInfo var);
|
||||
|
||||
OBJECT_CONSTRUCTORS(ScopeInfo, FixedArray);
|
||||
TQ_OBJECT_CONSTRUCTORS(ScopeInfo)
|
||||
FRIEND_TEST(TestWithNativeContext, RecreateScopeInfoWithLocalsBlocklistWorks);
|
||||
};
|
||||
|
||||
|
@ -2,23 +2,49 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
extern class ScopeInfo extends FixedArray;
|
||||
|
||||
extern macro EmptyScopeInfoConstant(): ScopeInfo;
|
||||
const kEmptyScopeInfo: ScopeInfo = EmptyScopeInfoConstant();
|
||||
|
||||
const kScopeInfoFlagsIndex:
|
||||
constexpr int32 generates 'ScopeInfo::Fields::kFlags';
|
||||
|
||||
operator '.flags' macro LoadScopeInfoFlags(implicit context: Context)(
|
||||
scopeInfo: ScopeInfo): ScopeFlags {
|
||||
return Convert<ScopeFlags>(
|
||||
UnsafeCast<Smi>(scopeInfo.objects[kScopeInfoFlagsIndex]));
|
||||
extern enum ScopeType extends uint32 {
|
||||
CLASS_SCOPE, // Also used for the empty scope (for NativeContext & builtins).
|
||||
EVAL_SCOPE,
|
||||
FUNCTION_SCOPE,
|
||||
MODULE_SCOPE,
|
||||
SCRIPT_SCOPE,
|
||||
CATCH_SCOPE,
|
||||
BLOCK_SCOPE,
|
||||
WITH_SCOPE
|
||||
}
|
||||
|
||||
type ScopeType extends uint32 constexpr 'ScopeType';
|
||||
type VariableAllocationInfo extends uint32
|
||||
constexpr 'VariableAllocationInfo';
|
||||
extern enum VariableAllocationInfo extends uint32 {
|
||||
NONE,
|
||||
STACK,
|
||||
CONTEXT,
|
||||
UNUSED
|
||||
}
|
||||
|
||||
extern enum VariableMode extends uint32 {
|
||||
kLet,
|
||||
kConst,
|
||||
kVar,
|
||||
kTemporary,
|
||||
kDynamic,
|
||||
kDynamicGlobal,
|
||||
kDynamicLocal,
|
||||
kPrivateMethod,
|
||||
kPrivateSetterOnly,
|
||||
kPrivateGetterOnly,
|
||||
kPrivateGetterAndSetter
|
||||
}
|
||||
|
||||
extern enum InitializationFlag extends uint32 {
|
||||
kNeedsInitialization,
|
||||
kCreatedInitialized
|
||||
}
|
||||
|
||||
extern enum IsStaticFlag extends uint32 { kNotStatic, kStatic }
|
||||
|
||||
extern enum MaybeAssignedFlag extends uint32 { kNotAssigned, kMaybeAssigned }
|
||||
|
||||
// Properties of scopes.
|
||||
bitfield struct ScopeFlags extends uint31 {
|
||||
@ -46,3 +72,97 @@ bitfield struct ScopeFlags extends uint31 {
|
||||
has_locals_block_list: bool: 1 bit;
|
||||
is_empty: bool: 1 bit;
|
||||
}
|
||||
|
||||
struct PositionInfo {
|
||||
start: Smi;
|
||||
end: Smi;
|
||||
}
|
||||
|
||||
struct FunctionNameInfo {
|
||||
function_variable_name: String|Zero;
|
||||
function_variable_context_or_stack_slot_index: Smi;
|
||||
}
|
||||
|
||||
bitfield struct VariableProperties extends uint31 {
|
||||
variable_mode: VariableMode: 4 bit;
|
||||
init_flag: InitializationFlag: 1 bit;
|
||||
maybe_assigned_flag: MaybeAssignedFlag: 1 bit;
|
||||
parameter_number: uint32: 16 bit;
|
||||
is_static_flag: IsStaticFlag: 1 bit;
|
||||
}
|
||||
|
||||
struct ModuleVariable {
|
||||
name: String;
|
||||
index: Smi;
|
||||
properties: SmiTagged<VariableProperties>;
|
||||
}
|
||||
|
||||
@generateCppClass
|
||||
extern class ScopeInfo extends FixedArrayBase {
|
||||
const flags: SmiTagged<ScopeFlags>;
|
||||
|
||||
// The number of parameters. For non-function scopes this is 0.
|
||||
parameter_count: Smi;
|
||||
|
||||
// The number of non-parameter and parameter variables allocated in the
|
||||
// context.
|
||||
const context_local_count: Smi;
|
||||
|
||||
// Contains the names of local variables and parameters that are allocated
|
||||
// in the context. They are stored in increasing order of the context slot
|
||||
// index starting with Context::MIN_CONTEXT_SLOTS.
|
||||
context_local_names[context_local_count]: String;
|
||||
|
||||
// Contains the variable modes and initialization flags corresponding to
|
||||
// the context locals in ContextLocalNames.
|
||||
context_local_infos[context_local_count]: SmiTagged<VariableProperties>;
|
||||
|
||||
// If the scope is a class scope and it has static private methods that
|
||||
// may be accessed directly or through eval, one slot is reserved to hold
|
||||
// the context slot index for the class variable.
|
||||
saved_class_variable_info[flags.has_saved_class_variable_index ? 1 : 0]: Smi;
|
||||
|
||||
// If the scope binds a "this" value, one slot is reserved to hold the
|
||||
// context or stack slot index for the variable.
|
||||
receiver_info[
|
||||
flags.receiver_variable ==
|
||||
FromConstexpr<VariableAllocationInfo>(VariableAllocationInfo::STACK)
|
||||
|| flags.receiver_variable ==
|
||||
FromConstexpr<VariableAllocationInfo>(VariableAllocationInfo::CONTEXT)
|
||||
? 1 : 0]: Smi;
|
||||
|
||||
// If the scope belongs to a named function expression this part contains
|
||||
// information about the function variable. It always occupies two array
|
||||
// slots: a. The name of the function variable.
|
||||
// b. The context or stack slot index for the variable.
|
||||
function_name_info[flags.function_variable != FromConstexpr<VariableAllocationInfo>(VariableAllocationInfo::NONE) ? 1 : 0]:
|
||||
FunctionNameInfo;
|
||||
|
||||
inferred_function_name[flags.has_inferred_function_name ? 1 : 0]: String|
|
||||
Undefined;
|
||||
|
||||
// Contains two slots with a) the startPosition and b) the endPosition if
|
||||
// the scope belongs to a function or script.
|
||||
position_info[flags.scope_type == ScopeType::FUNCTION_SCOPE ||
|
||||
flags.scope_type == ScopeType::SCRIPT_SCOPE ||
|
||||
flags.scope_type == ScopeType::EVAL_SCOPE ||
|
||||
flags.scope_type == ScopeType::MODULE_SCOPE
|
||||
? 1 : 0]: PositionInfo;
|
||||
|
||||
outer_scope_info[flags.has_outer_scope_info ? 1 : 0]: ScopeInfo|TheHole;
|
||||
|
||||
// List of stack allocated local variables. Used by debug evaluate to properly
|
||||
// abort variable lookup when a name clashes with a stack allocated local that
|
||||
// can't be materialized.
|
||||
locals_block_list[flags.has_locals_block_list ? 1 : 0]: HashTable;
|
||||
|
||||
// For a module scope, this part contains the SourceTextModuleInfo, the
|
||||
// number of MODULE-allocated variables, and the metadata of those
|
||||
// variables. For non-module scopes it is empty.
|
||||
module_info[flags.scope_type == ScopeType::MODULE_SCOPE ? 1 : 0]:
|
||||
SourceTextModuleInfo;
|
||||
const module_variable_count[flags.scope_type == ScopeType::MODULE_SCOPE ? 1 : 0]:
|
||||
Smi;
|
||||
module_variables[flags.scope_type == ScopeType::MODULE_SCOPE ? module_variable_count[0] : 0]:
|
||||
ModuleVariable;
|
||||
}
|
||||
|
@ -636,7 +636,7 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject object) {
|
||||
} else if (object.IsContext()) {
|
||||
return AddEntry(object, HeapEntry::kObject, "system / Context");
|
||||
} else if (object.IsFixedArray() || object.IsFixedDoubleArray() ||
|
||||
object.IsByteArray()) {
|
||||
object.IsByteArray() || object.IsScopeInfo()) {
|
||||
return AddEntry(object, HeapEntry::kArray, "");
|
||||
} else if (object.IsHeapNumber()) {
|
||||
return AddEntry(object, HeapEntry::kHeapNumber, "number");
|
||||
|
@ -21,22 +21,6 @@ base::Optional<Stack<std::string>> CCGenerator::EmitGraph(
|
||||
parameters.Peek(i));
|
||||
}
|
||||
|
||||
// C++ doesn't have parameterized labels like CSA, so we must pre-declare all
|
||||
// phi values so they're in scope for both the blocks that define them and the
|
||||
// blocks that read them.
|
||||
for (Block* block : cfg_.blocks()) {
|
||||
if (block->IsDead()) continue;
|
||||
|
||||
DCHECK_EQ(block->InputTypes().Size(), block->InputDefinitions().Size());
|
||||
for (BottomOffset i = {0}; i < block->InputTypes().AboveTop(); ++i) {
|
||||
DefinitionLocation input_def = block->InputDefinitions().Peek(i);
|
||||
if (block->InputDefinitions().Peek(i).IsPhiFromBlock(block)) {
|
||||
out() << " " << block->InputTypes().Peek(i)->GetRuntimeType() << " "
|
||||
<< DefinitionToVariable(input_def) << ";\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Redirect the output of non-declarations into a buffer and only output
|
||||
// declarations right away.
|
||||
std::stringstream out_buffer;
|
||||
@ -198,7 +182,16 @@ void CCGenerator::EmitInstruction(const CallIntrinsicInstruction& instruction,
|
||||
if (return_type->IsConstexpr()) {
|
||||
ReportError("%FromConstexpr must return a non-constexpr type");
|
||||
}
|
||||
// Nothing to do here; constexpr expressions are already valid C++.
|
||||
if (return_type->IsSubtypeOf(TypeOracle::GetSmiType())) {
|
||||
if (is_cc_debug_) {
|
||||
out() << "Internals::IntToSmi";
|
||||
} else {
|
||||
out() << "Smi::FromInt";
|
||||
}
|
||||
}
|
||||
// Wrap the raw constexpr value in a static_cast to ensure that
|
||||
// enums get properly casted to their backing integral value.
|
||||
out() << "(CastToUnderlyingTypeIfEnum";
|
||||
} else {
|
||||
ReportError("no built in intrinsic with name " +
|
||||
instruction.intrinsic->ExternalName());
|
||||
@ -206,6 +199,9 @@ void CCGenerator::EmitInstruction(const CallIntrinsicInstruction& instruction,
|
||||
|
||||
out() << "(";
|
||||
PrintCommaSeparatedList(out(), args);
|
||||
if (instruction.intrinsic->ExternalName() == "%FromConstexpr") {
|
||||
out() << ")";
|
||||
}
|
||||
out() << ");\n";
|
||||
}
|
||||
|
||||
@ -247,10 +243,10 @@ void CCGenerator::EmitInstruction(const CallCsaMacroInstruction& instruction,
|
||||
|
||||
if (is_cc_debug_) {
|
||||
out() << instruction.macro->CCDebugName() << "(accessor";
|
||||
if (!args.empty()) out() << ", ";
|
||||
} else {
|
||||
out() << instruction.macro->CCName() << "(isolate";
|
||||
out() << instruction.macro->CCName() << "(";
|
||||
}
|
||||
if (!args.empty()) out() << ", ";
|
||||
PrintCommaSeparatedList(out(), args);
|
||||
if (is_cc_debug_) {
|
||||
out() << "));\n";
|
||||
@ -384,8 +380,23 @@ void CCGenerator::EmitInstruction(const LoadReferenceInstruction& instruction,
|
||||
<< result_name << ");\n";
|
||||
out() << " " << result_name << " = ";
|
||||
if (instruction.type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
|
||||
out() << "TaggedField<" << result_type << ">::load(isolate, " << object
|
||||
<< ", static_cast<int>(" << offset << "));\n";
|
||||
// Currently, all of the tagged loads we emit are for smi values, so there
|
||||
// is no point in providing an IsolateRoot. If at some point we start
|
||||
// emitting loads for tagged fields which might be HeapObjects, then we
|
||||
// should plumb an IsolateRoot through the generated functions that need
|
||||
// it.
|
||||
if (!instruction.type->IsSubtypeOf(TypeOracle::GetSmiType())) {
|
||||
Error(
|
||||
"Not supported in C++ output: LoadReference on non-smi tagged "
|
||||
"value");
|
||||
}
|
||||
|
||||
// References and slices can cause some values to have the Torque type
|
||||
// HeapObject|TaggedZeroPattern, which is output as "Object". TaggedField
|
||||
// requires HeapObject, so we need a cast.
|
||||
out() << "TaggedField<" << result_type
|
||||
<< ">::load(*static_cast<HeapObject*>(&" << object
|
||||
<< "), static_cast<int>(" << offset << "));\n";
|
||||
} else {
|
||||
out() << "(" << object << ").ReadField<" << result_type << ">(" << offset
|
||||
<< ");\n";
|
||||
@ -438,13 +449,17 @@ void CCGenerator::EmitInstruction(const LoadBitFieldInstruction& instruction,
|
||||
Type::MatchUnaryGeneric(struct_type, TypeOracle::GetSmiTaggedGeneric());
|
||||
if (smi_tagged_type) {
|
||||
// Get the untagged value and its type.
|
||||
bit_field_struct = bit_field_struct + ".value()";
|
||||
if (is_cc_debug_) {
|
||||
bit_field_struct = "Internals::SmiValue(" + bit_field_struct + ")";
|
||||
} else {
|
||||
bit_field_struct = bit_field_struct + ".value()";
|
||||
}
|
||||
struct_type = *smi_tagged_type;
|
||||
}
|
||||
|
||||
out() << " " << result_name << " = "
|
||||
out() << " " << result_name << " = CastToUnderlyingTypeIfEnum("
|
||||
<< GetBitFieldSpecialization(struct_type, instruction.bit_field)
|
||||
<< "::decode(" << bit_field_struct << ");\n";
|
||||
<< "::decode(" << bit_field_struct << "));\n";
|
||||
}
|
||||
|
||||
void CCGenerator::EmitInstruction(const StoreBitFieldInstruction& instruction,
|
||||
|
@ -33,6 +33,15 @@ std::vector<T*> FilterDeclarables(const std::vector<Declarable*> list) {
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::string UnwrapTNodeTypeName(const std::string& generates) {
|
||||
if (generates.length() < 7 || generates.substr(0, 6) != "TNode<" ||
|
||||
generates.substr(generates.length() - 1, 1) != ">") {
|
||||
ReportError("generated type \"", generates,
|
||||
"\" should be of the form \"TNode<...>\"");
|
||||
}
|
||||
return generates.substr(6, generates.length() - 7);
|
||||
}
|
||||
|
||||
class Declarations {
|
||||
public:
|
||||
static std::vector<Declarable*> TryLookup(const QualifiedName& name) {
|
||||
|
@ -1774,13 +1774,10 @@ std::vector<std::string> ImplementationVisitor::GenerateFunctionDeclaration(
|
||||
o << " " << macro_prefix << name << "(";
|
||||
|
||||
bool first = true;
|
||||
if (output_type_ == OutputType::kCC) {
|
||||
first = false;
|
||||
o << "Isolate* isolate";
|
||||
} else if (output_type_ == OutputType::kCCDebug) {
|
||||
if (output_type_ == OutputType::kCCDebug) {
|
||||
first = false;
|
||||
o << "d::MemoryAccessor accessor";
|
||||
} else if (pass_code_assembler_state) {
|
||||
} else if (output_type_ == OutputType::kCSA && pass_code_assembler_state) {
|
||||
first = false;
|
||||
o << "compiler::CodeAssemblerState* state_";
|
||||
}
|
||||
@ -3459,6 +3456,7 @@ class FieldOffsetsGenerator {
|
||||
explicit FieldOffsetsGenerator(const ClassType* type) : type_(type) {}
|
||||
|
||||
virtual void WriteField(const Field& f, const std::string& size_string) = 0;
|
||||
virtual void WriteFieldOffsetGetter(const Field& f) = 0;
|
||||
virtual void WriteMarker(const std::string& marker) = 0;
|
||||
|
||||
virtual ~FieldOffsetsGenerator() { CHECK(is_finished_); }
|
||||
@ -3480,7 +3478,11 @@ class FieldOffsetsGenerator {
|
||||
size_t field_size;
|
||||
std::tie(field_size, size_string) = f.GetFieldSizeInformation();
|
||||
}
|
||||
WriteField(f, size_string);
|
||||
if (f.offset.has_value()) {
|
||||
WriteField(f, size_string);
|
||||
} else {
|
||||
WriteFieldOffsetGetter(f);
|
||||
}
|
||||
}
|
||||
|
||||
void Finish() {
|
||||
@ -3586,6 +3588,9 @@ class MacroFieldOffsetsGenerator : public FieldOffsetsGenerator {
|
||||
out_ << "V(k" << CamelifyString(f.name_and_type.name) << "Offset, "
|
||||
<< size_string << ") \\\n";
|
||||
}
|
||||
void WriteFieldOffsetGetter(const Field& f) override {
|
||||
// Can't do anything here.
|
||||
}
|
||||
void WriteMarker(const std::string& marker) override {
|
||||
out_ << "V(" << marker << ", 0) \\\n";
|
||||
}
|
||||
@ -3713,10 +3718,13 @@ namespace {
|
||||
|
||||
class ClassFieldOffsetGenerator : public FieldOffsetsGenerator {
|
||||
public:
|
||||
ClassFieldOffsetGenerator(std::ostream& header, const ClassType* type)
|
||||
ClassFieldOffsetGenerator(std::ostream& header, std::ostream& inline_header,
|
||||
const ClassType* type, std::string gen_name_T)
|
||||
: FieldOffsetsGenerator(type),
|
||||
hdr_(header),
|
||||
previous_field_end_("P::kHeaderSize") {}
|
||||
inl_(inline_header),
|
||||
previous_field_end_("P::kHeaderSize"),
|
||||
gen_name_T_(gen_name_T) {}
|
||||
void WriteField(const Field& f, const std::string& size_string) override {
|
||||
std::string field = "k" + CamelifyString(f.name_and_type.name) + "Offset";
|
||||
std::string field_end = field + "End";
|
||||
@ -3726,6 +3734,22 @@ class ClassFieldOffsetGenerator : public FieldOffsetsGenerator {
|
||||
<< size_string << " - 1;\n";
|
||||
previous_field_end_ = field_end + " + 1";
|
||||
}
|
||||
void WriteFieldOffsetGetter(const Field& f) override {
|
||||
// A static constexpr int is more convenient than a getter if the offset is
|
||||
// known.
|
||||
DCHECK(!f.offset.has_value());
|
||||
|
||||
std::string function_name = CamelifyString(f.name_and_type.name) + "Offset";
|
||||
|
||||
hdr_ << " inline int " << function_name << "() const;\n";
|
||||
inl_ << "template <class D, class P>\n";
|
||||
inl_ << "int " << gen_name_T_ << "::" << function_name << "() const {\n";
|
||||
// Item 1 in a flattened slice is the offset.
|
||||
inl_ << " return static_cast<int>(std::get<1>("
|
||||
<< Callable::PrefixNameForCCOutput(type_->GetSliceMacroName(f))
|
||||
<< "(*static_cast<const D*>(this))));\n";
|
||||
inl_ << "}\n\n";
|
||||
}
|
||||
void WriteMarker(const std::string& marker) override {
|
||||
hdr_ << " static constexpr int " << marker << " = " << previous_field_end_
|
||||
<< ";\n";
|
||||
@ -3733,7 +3757,9 @@ class ClassFieldOffsetGenerator : public FieldOffsetsGenerator {
|
||||
|
||||
private:
|
||||
std::ostream& hdr_;
|
||||
std::ostream& inl_;
|
||||
std::string previous_field_end_;
|
||||
std::string gen_name_T_;
|
||||
};
|
||||
|
||||
class CppClassGenerator {
|
||||
@ -3764,6 +3790,8 @@ class CppClassGenerator {
|
||||
|
||||
void GenerateClassCasts();
|
||||
|
||||
std::string GetFieldOffsetForAccessor(const Field& f);
|
||||
|
||||
const ClassType* type_;
|
||||
const ClassType* super_;
|
||||
const std::string name_;
|
||||
@ -3852,7 +3880,7 @@ void CppClassGenerator::GenerateClass() {
|
||||
}
|
||||
|
||||
hdr_ << "\n";
|
||||
ClassFieldOffsetGenerator g(hdr_, type_);
|
||||
ClassFieldOffsetGenerator g(hdr_, inl_, type_, gen_name_T_);
|
||||
for (auto f : type_->fields()) {
|
||||
CurrentSourcePosition::Scope scope(f.pos);
|
||||
g.RecordOffsetFor(f);
|
||||
@ -3865,6 +3893,21 @@ void CppClassGenerator::GenerateClass() {
|
||||
if (!index_fields.has_value()) {
|
||||
hdr_ << " // SizeFor implementations not generated due to complex array "
|
||||
"lengths\n\n";
|
||||
|
||||
const Field& last_field = type_->LastField();
|
||||
std::string last_field_item_size =
|
||||
std::get<1>(*SizeOf(last_field.name_and_type.type));
|
||||
hdr_ << " inline int AllocatedSize();\n\n";
|
||||
inl_ << "template <class D, class P>\n";
|
||||
inl_ << "int " << gen_name_T_ << "::AllocatedSize() {\n";
|
||||
inl_ << " auto slice = "
|
||||
<< Callable::PrefixNameForCCOutput(
|
||||
type_->GetSliceMacroName(last_field))
|
||||
<< "(*static_cast<const D*>(this));\n";
|
||||
inl_ << " return static_cast<int>(std::get<1>(slice)) + "
|
||||
<< last_field_item_size
|
||||
<< " * static_cast<int>(std::get<2>(slice));\n";
|
||||
inl_ << "}\n\n";
|
||||
} else if (type_->ShouldGenerateBodyDescriptor() ||
|
||||
(!type_->IsAbstract() &&
|
||||
!type_->IsSubtypeOf(TypeOracle::GetJSObjectType()))) {
|
||||
@ -4001,11 +4044,18 @@ std::string GenerateRuntimeTypeCheck(const Type* type,
|
||||
void GenerateBoundsDCheck(std::ostream& os, const std::string& index,
|
||||
const ClassType* type, const Field& f) {
|
||||
os << " DCHECK_GE(" << index << ", 0);\n";
|
||||
std::string length_expression;
|
||||
if (base::Optional<NameAndType> array_length =
|
||||
ExtractSimpleFieldArraySize(*type, *f.index)) {
|
||||
os << " DCHECK_LT(" << index << ", this->" << array_length->name
|
||||
<< "());\n";
|
||||
length_expression = "this ->" + array_length->name + "()";
|
||||
} else {
|
||||
// The length is element 2 in the flattened field slice.
|
||||
length_expression =
|
||||
"static_cast<int>(std::get<2>(" +
|
||||
Callable::PrefixNameForCCOutput(type->GetSliceMacroName(f)) +
|
||||
"(*static_cast<const D*>(this))))";
|
||||
}
|
||||
os << " DCHECK_LT(" << index << ", " << length_expression << ");\n";
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@ -4038,6 +4088,13 @@ void CppClassGenerator::GenerateFieldAccessor(const Field& f) {
|
||||
.Position(f.pos);
|
||||
}
|
||||
|
||||
std::string CppClassGenerator::GetFieldOffsetForAccessor(const Field& f) {
|
||||
if (f.offset.has_value()) {
|
||||
return "k" + CamelifyString(f.name_and_type.name) + "Offset";
|
||||
}
|
||||
return CamelifyString(f.name_and_type.name) + "Offset()";
|
||||
}
|
||||
|
||||
void CppClassGenerator::GenerateFieldAccessorForUntagged(const Field& f) {
|
||||
DCHECK(!f.name_and_type.type->IsSubtypeOf(TypeOracle::GetTaggedType()));
|
||||
const Type* field_type = f.name_and_type.type;
|
||||
@ -4053,7 +4110,7 @@ void CppClassGenerator::GenerateFieldAccessorForUntagged(const Field& f) {
|
||||
}
|
||||
const std::string& name = f.name_and_type.name;
|
||||
const std::string type = constexpr_version->GetGeneratedTypeName();
|
||||
std::string offset = "k" + CamelifyString(name) + "Offset";
|
||||
std::string offset = GetFieldOffsetForAccessor(f);
|
||||
|
||||
// Generate declarations in header.
|
||||
if (f.index) {
|
||||
@ -4110,7 +4167,7 @@ void CppClassGenerator::GenerateFieldAccessorForSmi(const Field& f) {
|
||||
// Follow the convention to create Smi accessors with type int.
|
||||
const std::string type = "int";
|
||||
const std::string& name = f.name_and_type.name;
|
||||
const std::string offset = "k" + CamelifyString(name) + "Offset";
|
||||
const std::string offset = GetFieldOffsetForAccessor(f);
|
||||
|
||||
// Generate declarations in header.
|
||||
if (f.index) {
|
||||
@ -4131,7 +4188,7 @@ void CppClassGenerator::GenerateFieldAccessorForSmi(const Field& f) {
|
||||
if (f.index) {
|
||||
GenerateBoundsDCheck(inl_, "i", type_, f);
|
||||
inl_ << " int offset = " << offset << " + i * kTaggedSize;\n";
|
||||
inl_ << " return this->template ReadField<Smi>(offset).value();\n";
|
||||
inl_ << " return TaggedField<Smi>::load(*this, offset).value();\n";
|
||||
inl_ << "}\n";
|
||||
} else {
|
||||
inl_ << " return TaggedField<Smi, " << offset
|
||||
@ -4162,7 +4219,7 @@ void CppClassGenerator::GenerateFieldAccessorForTagged(const Field& f) {
|
||||
const Type* field_type = f.name_and_type.type;
|
||||
DCHECK(field_type->IsSubtypeOf(TypeOracle::GetTaggedType()));
|
||||
const std::string& name = f.name_and_type.name;
|
||||
std::string offset = "k" + CamelifyString(name) + "Offset";
|
||||
std::string offset = GetFieldOffsetForAccessor(f);
|
||||
bool strong_pointer = field_type->IsSubtypeOf(TypeOracle::GetObjectType());
|
||||
|
||||
std::string type = field_type->UnhandlifiedCppTypeName();
|
||||
@ -4710,7 +4767,7 @@ void GenerateClassFieldVerifier(const std::string& class_name,
|
||||
<< length << ") = "
|
||||
<< Callable::PrefixNameForCCOutput(
|
||||
class_type.GetSliceMacroName(f))
|
||||
<< "(isolate, o);\n";
|
||||
<< "(o);\n";
|
||||
|
||||
// Slices use intptr, but TaggedField<T>.load() uses int, so verify that
|
||||
// such a cast is valid.
|
||||
|
@ -13,26 +13,26 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class Isolate;
|
||||
|
||||
namespace TorqueRuntimeMacroShims {
|
||||
namespace CodeStubAssembler {
|
||||
|
||||
inline intptr_t ChangeInt32ToIntPtr(Isolate* isolate, int32_t i) { return i; }
|
||||
inline uintptr_t ChangeUint32ToWord(Isolate* isolate, uint32_t u) { return u; }
|
||||
inline intptr_t IntPtrAdd(Isolate* isolate, intptr_t a, intptr_t b) {
|
||||
return a + b;
|
||||
}
|
||||
inline intptr_t IntPtrMul(Isolate* isolate, intptr_t a, intptr_t b) {
|
||||
return a * b;
|
||||
}
|
||||
inline intptr_t Signed(Isolate* isolate, uintptr_t u) {
|
||||
return static_cast<intptr_t>(u);
|
||||
}
|
||||
inline bool BoolConstant(bool b) { return b; }
|
||||
inline intptr_t ChangeInt32ToIntPtr(int32_t i) { return i; }
|
||||
inline uintptr_t ChangeUint32ToWord(uint32_t u) { return u; }
|
||||
inline intptr_t IntPtrAdd(intptr_t a, intptr_t b) { return a + b; }
|
||||
inline intptr_t IntPtrMul(intptr_t a, intptr_t b) { return a * b; }
|
||||
inline intptr_t Signed(uintptr_t u) { return static_cast<intptr_t>(u); }
|
||||
template <typename Smi>
|
||||
inline int32_t SmiUntag(Isolate* isolate, Smi s) {
|
||||
inline int32_t SmiUntag(Smi s) {
|
||||
return s.value();
|
||||
}
|
||||
inline bool UintPtrLessThan(uintptr_t a, uintptr_t b) { return a < b; }
|
||||
inline uint32_t Unsigned(int32_t s) { return static_cast<uint32_t>(s); }
|
||||
#if V8_HOST_ARCH_64_BIT
|
||||
inline uintptr_t Unsigned(intptr_t s) { return static_cast<uintptr_t>(s); }
|
||||
#endif
|
||||
inline bool Word32Equal(uint32_t a, uint32_t b) { return a == b; }
|
||||
inline bool Word32NotEqual(uint32_t a, uint32_t b) { return a != b; }
|
||||
|
||||
} // namespace CodeStubAssembler
|
||||
} // namespace TorqueRuntimeMacroShims
|
||||
|
@ -983,7 +983,7 @@ base::Optional<ParseResult> MakeClassDeclaration(
|
||||
std::vector<Declaration*> result;
|
||||
|
||||
result.push_back(MakeNode<ClassDeclaration>(
|
||||
name, flags, extends, std::move(generates), std::move(methods), fields,
|
||||
name, flags, extends, generates, std::move(methods), fields,
|
||||
MakeInstanceTypeConstraints(annotations)));
|
||||
|
||||
Identifier* constexpr_name =
|
||||
@ -993,7 +993,8 @@ base::Optional<ParseResult> MakeClassDeclaration(
|
||||
AbstractTypeFlags abstract_type_flags(AbstractTypeFlag::kConstexpr);
|
||||
if (transient) abstract_type_flags |= AbstractTypeFlag::kTransient;
|
||||
TypeDeclaration* constexpr_decl = MakeNode<AbstractTypeDeclaration>(
|
||||
constexpr_name, abstract_type_flags, constexpr_extends, name->value);
|
||||
constexpr_name, abstract_type_flags, constexpr_extends,
|
||||
generates ? UnwrapTNodeTypeName(*generates) : name->value);
|
||||
constexpr_decl->pos = name->pos;
|
||||
result.push_back(constexpr_decl);
|
||||
|
||||
|
@ -63,12 +63,7 @@ std::string ComputeGeneratesType(base::Optional<std::string> opt_gen,
|
||||
if (!opt_gen) return "";
|
||||
const std::string& generates = *opt_gen;
|
||||
if (enforce_tnode_type) {
|
||||
if (generates.length() < 7 || generates.substr(0, 6) != "TNode<" ||
|
||||
generates.substr(generates.length() - 1, 1) != ">") {
|
||||
ReportError("generated type \"", generates,
|
||||
"\" should be of the form \"TNode<...>\"");
|
||||
}
|
||||
return generates.substr(6, generates.length() - 7);
|
||||
return UnwrapTNodeTypeName(generates);
|
||||
}
|
||||
return generates;
|
||||
}
|
||||
|
@ -576,6 +576,16 @@ class AggregateType : public Type {
|
||||
return {{name_, ""}};
|
||||
}
|
||||
|
||||
const Field& LastField() const {
|
||||
for (base::Optional<const AggregateType*> current = this;
|
||||
current.has_value();
|
||||
current = (*current)->parent()->AggregateSupertype()) {
|
||||
const std::vector<Field>& fields = (*current)->fields_;
|
||||
if (!fields.empty()) return fields[fields.size() - 1];
|
||||
}
|
||||
ReportError("Can't get last field of empty aggregate type");
|
||||
}
|
||||
|
||||
protected:
|
||||
AggregateType(Kind kind, const Type* parent, Namespace* nspace,
|
||||
const std::string& name,
|
||||
|
@ -446,7 +446,13 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
|
||||
builder.Return();
|
||||
|
||||
// Generate BytecodeArray.
|
||||
scope.SetScriptScopeInfo(factory->NewScopeInfo(1));
|
||||
Handle<ScopeInfo> scope_info =
|
||||
factory->NewScopeInfo(ScopeInfo::kVariablePartIndex);
|
||||
scope_info->set_flags(0);
|
||||
scope_info->set_context_local_count(0);
|
||||
scope_info->set_parameter_count(0);
|
||||
scope.SetScriptScopeInfo(scope_info);
|
||||
|
||||
ast_factory.Internalize(isolate());
|
||||
Handle<BytecodeArray> the_array = builder.ToBytecodeArray(isolate());
|
||||
CHECK_EQ(the_array->frame_size(),
|
||||
|
@ -47,6 +47,9 @@ namespace debug_helper_internal {
|
||||
namespace TorqueDebugMacroShims {
|
||||
namespace CodeStubAssembler {
|
||||
|
||||
inline Value<bool> BoolConstant(d::MemoryAccessor accessor, bool b) {
|
||||
return {d::MemoryAccessResult::kOk, b};
|
||||
}
|
||||
inline Value<intptr_t> ChangeInt32ToIntPtr(d::MemoryAccessor accessor,
|
||||
int32_t i) {
|
||||
return {d::MemoryAccessResult::kOk, i};
|
||||
@ -70,6 +73,26 @@ inline Value<int32_t> SmiUntag(d::MemoryAccessor accessor, uintptr_t s_t) {
|
||||
Smi s(s_t);
|
||||
return {d::MemoryAccessResult::kOk, s.value()};
|
||||
}
|
||||
inline Value<bool> UintPtrLessThan(d::MemoryAccessor accessor, uintptr_t a,
|
||||
uintptr_t b) {
|
||||
return {d::MemoryAccessResult::kOk, a < b};
|
||||
}
|
||||
inline Value<uint32_t> Unsigned(d::MemoryAccessor accessor, int32_t s) {
|
||||
return {d::MemoryAccessResult::kOk, static_cast<uint32_t>(s)};
|
||||
}
|
||||
#if V8_HOST_ARCH_64_BIT
|
||||
inline Value<uintptr_t> Unsigned(d::MemoryAccessor accessor, intptr_t s) {
|
||||
return {d::MemoryAccessResult::kOk, static_cast<uintptr_t>(s)};
|
||||
}
|
||||
#endif
|
||||
inline Value<bool> Word32Equal(d::MemoryAccessor accessor, uint32_t a,
|
||||
uint32_t b) {
|
||||
return {d::MemoryAccessResult::kOk, a == b};
|
||||
}
|
||||
inline Value<bool> Word32NotEqual(d::MemoryAccessor accessor, uint32_t a,
|
||||
uint32_t b) {
|
||||
return {d::MemoryAccessResult::kOk, a != b};
|
||||
}
|
||||
|
||||
} // namespace CodeStubAssembler
|
||||
} // namespace TorqueDebugMacroShims
|
||||
|
@ -89,12 +89,12 @@ INSTANCE_TYPES = {
|
||||
125: "SIMPLE_NUMBER_DICTIONARY_TYPE",
|
||||
126: "CLOSURE_FEEDBACK_CELL_ARRAY_TYPE",
|
||||
127: "OBJECT_BOILERPLATE_DESCRIPTION_TYPE",
|
||||
128: "SCOPE_INFO_TYPE",
|
||||
129: "SCRIPT_CONTEXT_TABLE_TYPE",
|
||||
130: "BYTE_ARRAY_TYPE",
|
||||
131: "BYTECODE_ARRAY_TYPE",
|
||||
132: "FIXED_DOUBLE_ARRAY_TYPE",
|
||||
133: "INTERNAL_CLASS_WITH_SMI_ELEMENTS_TYPE",
|
||||
128: "SCRIPT_CONTEXT_TABLE_TYPE",
|
||||
129: "BYTE_ARRAY_TYPE",
|
||||
130: "BYTECODE_ARRAY_TYPE",
|
||||
131: "FIXED_DOUBLE_ARRAY_TYPE",
|
||||
132: "INTERNAL_CLASS_WITH_SMI_ELEMENTS_TYPE",
|
||||
133: "SCOPE_INFO_TYPE",
|
||||
134: "SLOPPY_ARGUMENTS_ELEMENTS_TYPE",
|
||||
135: "AWAIT_CONTEXT_TYPE",
|
||||
136: "BLOCK_CONTEXT_TYPE",
|
||||
@ -245,12 +245,12 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x023cd): (66, "HeapNumberMap"),
|
||||
("read_only_space", 0x02401): (67, "TheHoleMap"),
|
||||
("read_only_space", 0x02461): (67, "BooleanMap"),
|
||||
("read_only_space", 0x02505): (130, "ByteArrayMap"),
|
||||
("read_only_space", 0x02505): (129, "ByteArrayMap"),
|
||||
("read_only_space", 0x0252d): (116, "FixedCOWArrayMap"),
|
||||
("read_only_space", 0x02555): (117, "HashTableMap"),
|
||||
("read_only_space", 0x0257d): (64, "SymbolMap"),
|
||||
("read_only_space", 0x025a5): (40, "OneByteStringMap"),
|
||||
("read_only_space", 0x025cd): (128, "ScopeInfoMap"),
|
||||
("read_only_space", 0x025cd): (133, "ScopeInfoMap"),
|
||||
("read_only_space", 0x025f5): (175, "SharedFunctionInfoMap"),
|
||||
("read_only_space", 0x0261d): (160, "CodeMap"),
|
||||
("read_only_space", 0x02645): (159, "CellMap"),
|
||||
@ -264,16 +264,16 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x02805): (67, "TerminationExceptionMap"),
|
||||
("read_only_space", 0x0286d): (67, "OptimizedOutMap"),
|
||||
("read_only_space", 0x028cd): (67, "StaleRegisterMap"),
|
||||
("read_only_space", 0x0292d): (129, "ScriptContextTableMap"),
|
||||
("read_only_space", 0x0292d): (128, "ScriptContextTableMap"),
|
||||
("read_only_space", 0x02955): (126, "ClosureFeedbackCellArrayMap"),
|
||||
("read_only_space", 0x0297d): (164, "FeedbackMetadataArrayMap"),
|
||||
("read_only_space", 0x029a5): (116, "ArrayListMap"),
|
||||
("read_only_space", 0x029cd): (65, "BigIntMap"),
|
||||
("read_only_space", 0x029f5): (127, "ObjectBoilerplateDescriptionMap"),
|
||||
("read_only_space", 0x02a1d): (131, "BytecodeArrayMap"),
|
||||
("read_only_space", 0x02a1d): (130, "BytecodeArrayMap"),
|
||||
("read_only_space", 0x02a45): (161, "CodeDataContainerMap"),
|
||||
("read_only_space", 0x02a6d): (162, "CoverageInfoMap"),
|
||||
("read_only_space", 0x02a95): (132, "FixedDoubleArrayMap"),
|
||||
("read_only_space", 0x02a95): (131, "FixedDoubleArrayMap"),
|
||||
("read_only_space", 0x02abd): (119, "GlobalDictionaryMap"),
|
||||
("read_only_space", 0x02ae5): (97, "ManyClosuresCellMap"),
|
||||
("read_only_space", 0x02b0d): (116, "ModuleInfoMap"),
|
||||
@ -368,7 +368,7 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x05afd): (146, "ExportedSubClassMap"),
|
||||
("read_only_space", 0x05b25): (68, "AbstractInternalClassSubclass1Map"),
|
||||
("read_only_space", 0x05b4d): (69, "AbstractInternalClassSubclass2Map"),
|
||||
("read_only_space", 0x05b75): (133, "InternalClassWithSmiElementsMap"),
|
||||
("read_only_space", 0x05b75): (132, "InternalClassWithSmiElementsMap"),
|
||||
("read_only_space", 0x05b9d): (169, "InternalClassWithStructElementsMap"),
|
||||
("read_only_space", 0x05bc5): (147, "ExportedSubClass2Map"),
|
||||
("read_only_space", 0x05bed): (178, "SortStateMap"),
|
||||
|
Loading…
Reference in New Issue
Block a user