summaryrefslogtreecommitdiff
path: root/deps/v8/src/objects
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/objects')
-rw-r--r--deps/v8/src/objects/OWNERS3
-rw-r--r--deps/v8/src/objects/api-callbacks-inl.h8
-rw-r--r--deps/v8/src/objects/api-callbacks.h16
-rw-r--r--deps/v8/src/objects/arguments-inl.h10
-rw-r--r--deps/v8/src/objects/arguments.h4
-rw-r--r--deps/v8/src/objects/bigint.cc183
-rw-r--r--deps/v8/src/objects/bigint.h10
-rw-r--r--deps/v8/src/objects/code-inl.h50
-rw-r--r--deps/v8/src/objects/code.cc22
-rw-r--r--deps/v8/src/objects/code.h50
-rw-r--r--deps/v8/src/objects/compressed-slots-inl.h54
-rw-r--r--deps/v8/src/objects/compressed-slots.h29
-rw-r--r--deps/v8/src/objects/contexts-inl.h8
-rw-r--r--deps/v8/src/objects/contexts.cc40
-rw-r--r--deps/v8/src/objects/contexts.h52
-rw-r--r--deps/v8/src/objects/descriptor-array-inl.h114
-rw-r--r--deps/v8/src/objects/descriptor-array.h45
-rw-r--r--deps/v8/src/objects/dictionary-inl.h37
-rw-r--r--deps/v8/src/objects/dictionary.h11
-rw-r--r--deps/v8/src/objects/elements.cc251
-rw-r--r--deps/v8/src/objects/elements.h11
-rw-r--r--deps/v8/src/objects/embedder-data-slot-inl.h6
-rw-r--r--deps/v8/src/objects/feedback-vector-inl.h19
-rw-r--r--deps/v8/src/objects/feedback-vector.cc73
-rw-r--r--deps/v8/src/objects/feedback-vector.h14
-rw-r--r--deps/v8/src/objects/field-index-inl.h12
-rw-r--r--deps/v8/src/objects/field-index.h6
-rw-r--r--deps/v8/src/objects/fixed-array-inl.h78
-rw-r--r--deps/v8/src/objects/fixed-array.h45
-rw-r--r--deps/v8/src/objects/free-space-inl.h36
-rw-r--r--deps/v8/src/objects/free-space.h3
-rw-r--r--deps/v8/src/objects/hash-table-inl.h20
-rw-r--r--deps/v8/src/objects/hash-table.h9
-rw-r--r--deps/v8/src/objects/heap-number-inl.h4
-rw-r--r--deps/v8/src/objects/heap-object-inl.h14
-rw-r--r--deps/v8/src/objects/heap-object.h58
-rw-r--r--deps/v8/src/objects/instance-type.h40
-rw-r--r--deps/v8/src/objects/intl-objects.cc273
-rw-r--r--deps/v8/src/objects/intl-objects.h28
-rw-r--r--deps/v8/src/objects/intl-objects.tq24
-rw-r--r--deps/v8/src/objects/js-array-buffer-inl.h4
-rw-r--r--deps/v8/src/objects/js-array-buffer.h6
-rw-r--r--deps/v8/src/objects/js-array-inl.h7
-rw-r--r--deps/v8/src/objects/js-array.h6
-rw-r--r--deps/v8/src/objects/js-break-iterator-inl.h12
-rw-r--r--deps/v8/src/objects/js-break-iterator.cc20
-rw-r--r--deps/v8/src/objects/js-break-iterator.h32
-rw-r--r--deps/v8/src/objects/js-collator-inl.h2
-rw-r--r--deps/v8/src/objects/js-collator.cc29
-rw-r--r--deps/v8/src/objects/js-collator.h14
-rw-r--r--deps/v8/src/objects/js-collection-iterator.h1
-rw-r--r--deps/v8/src/objects/js-collection.h4
-rw-r--r--deps/v8/src/objects/js-date-time-format.cc221
-rw-r--r--deps/v8/src/objects/js-date-time-format.h6
-rw-r--r--deps/v8/src/objects/js-list-format-inl.h4
-rw-r--r--deps/v8/src/objects/js-list-format.cc64
-rw-r--r--deps/v8/src/objects/js-list-format.h18
-rw-r--r--deps/v8/src/objects/js-locale.cc13
-rw-r--r--deps/v8/src/objects/js-locale.h9
-rw-r--r--deps/v8/src/objects/js-number-format-inl.h11
-rw-r--r--deps/v8/src/objects/js-number-format.cc326
-rw-r--r--deps/v8/src/objects/js-number-format.h37
-rw-r--r--deps/v8/src/objects/js-objects-inl.h351
-rw-r--r--deps/v8/src/objects/js-objects.cc320
-rw-r--r--deps/v8/src/objects/js-objects.h263
-rw-r--r--deps/v8/src/objects/js-plural-rules-inl.h7
-rw-r--r--deps/v8/src/objects/js-plural-rules.cc229
-rw-r--r--deps/v8/src/objects/js-plural-rules.h20
-rw-r--r--deps/v8/src/objects/js-proxy-inl.h7
-rw-r--r--deps/v8/src/objects/js-proxy.h19
-rw-r--r--deps/v8/src/objects/js-regexp.h57
-rw-r--r--deps/v8/src/objects/js-relative-time-format-inl.h4
-rw-r--r--deps/v8/src/objects/js-relative-time-format.cc39
-rw-r--r--deps/v8/src/objects/js-relative-time-format.h19
-rw-r--r--deps/v8/src/objects/js-segment-iterator-inl.h2
-rw-r--r--deps/v8/src/objects/js-segment-iterator.cc21
-rw-r--r--deps/v8/src/objects/js-segmenter-inl.h2
-rw-r--r--deps/v8/src/objects/js-segmenter.cc31
-rw-r--r--deps/v8/src/objects/js-segmenter.h13
-rw-r--r--deps/v8/src/objects/js-weak-refs-inl.h14
-rw-r--r--deps/v8/src/objects/js-weak-refs.h68
-rw-r--r--deps/v8/src/objects/keys.cc5
-rw-r--r--deps/v8/src/objects/layout-descriptor-inl.h4
-rw-r--r--deps/v8/src/objects/literal-objects-inl.h72
-rw-r--r--deps/v8/src/objects/literal-objects.cc75
-rw-r--r--deps/v8/src/objects/literal-objects.h19
-rw-r--r--deps/v8/src/objects/lookup-inl.h55
-rw-r--r--deps/v8/src/objects/lookup.cc487
-rw-r--r--deps/v8/src/objects/lookup.h10
-rw-r--r--deps/v8/src/objects/map-inl.h156
-rw-r--r--deps/v8/src/objects/map-updater.cc27
-rw-r--r--deps/v8/src/objects/map-updater.h5
-rw-r--r--deps/v8/src/objects/map.cc185
-rw-r--r--deps/v8/src/objects/map.h91
-rw-r--r--deps/v8/src/objects/maybe-object.h4
-rw-r--r--deps/v8/src/objects/module-inl.h97
-rw-r--r--deps/v8/src/objects/module.cc768
-rw-r--r--deps/v8/src/objects/module.h220
-rw-r--r--deps/v8/src/objects/name-inl.h31
-rw-r--r--deps/v8/src/objects/name.h37
-rw-r--r--deps/v8/src/objects/object-list-macros.h28
-rw-r--r--deps/v8/src/objects/object-macros-undef.h7
-rw-r--r--deps/v8/src/objects/object-macros.h185
-rw-r--r--deps/v8/src/objects/objects-body-descriptors-inl.h13
-rw-r--r--deps/v8/src/objects/objects-definitions.h35
-rw-r--r--deps/v8/src/objects/objects-inl.h378
-rw-r--r--deps/v8/src/objects/objects.cc252
-rw-r--r--deps/v8/src/objects/objects.h67
-rw-r--r--deps/v8/src/objects/oddball-inl.h6
-rw-r--r--deps/v8/src/objects/ordered-hash-table-inl.h4
-rw-r--r--deps/v8/src/objects/ordered-hash-table.cc6
-rw-r--r--deps/v8/src/objects/ordered-hash-table.h10
-rw-r--r--deps/v8/src/objects/property-array-inl.h35
-rw-r--r--deps/v8/src/objects/property-array.h6
-rw-r--r--deps/v8/src/objects/property-cell.h2
-rw-r--r--deps/v8/src/objects/property.cc3
-rw-r--r--deps/v8/src/objects/prototype-inl.h9
-rw-r--r--deps/v8/src/objects/scope-info.cc71
-rw-r--r--deps/v8/src/objects/scope-info.h23
-rw-r--r--deps/v8/src/objects/shared-function-info-inl.h22
-rw-r--r--deps/v8/src/objects/shared-function-info.h31
-rw-r--r--deps/v8/src/objects/slots.h12
-rw-r--r--deps/v8/src/objects/source-text-module.cc661
-rw-r--r--deps/v8/src/objects/source-text-module.h220
-rw-r--r--deps/v8/src/objects/stack-frame-info-inl.h4
-rw-r--r--deps/v8/src/objects/stack-frame-info.cc313
-rw-r--r--deps/v8/src/objects/stack-frame-info.h35
-rw-r--r--deps/v8/src/objects/string-inl.h77
-rw-r--r--deps/v8/src/objects/string.cc46
-rw-r--r--deps/v8/src/objects/string.h91
-rw-r--r--deps/v8/src/objects/synthetic-module.cc108
-rw-r--r--deps/v8/src/objects/synthetic-module.h69
-rw-r--r--deps/v8/src/objects/tagged-field-inl.h162
-rw-r--r--deps/v8/src/objects/tagged-field.h76
-rw-r--r--deps/v8/src/objects/tagged-impl-inl.h44
-rw-r--r--deps/v8/src/objects/tagged-impl.h39
-rw-r--r--deps/v8/src/objects/tagged-value-inl.h31
-rw-r--r--deps/v8/src/objects/tagged-value.h6
-rw-r--r--deps/v8/src/objects/template-objects.cc4
-rw-r--r--deps/v8/src/objects/template-objects.h2
-rw-r--r--deps/v8/src/objects/templates-inl.h8
-rw-r--r--deps/v8/src/objects/templates.h2
-rw-r--r--deps/v8/src/objects/transitions-inl.h7
-rw-r--r--deps/v8/src/objects/transitions.cc2
-rw-r--r--deps/v8/src/objects/transitions.h2
-rw-r--r--deps/v8/src/objects/value-serializer.cc225
-rw-r--r--deps/v8/src/objects/value-serializer.h12
147 files changed, 5750 insertions, 4151 deletions
diff --git a/deps/v8/src/objects/OWNERS b/deps/v8/src/objects/OWNERS
new file mode 100644
index 0000000000..450423f878
--- /dev/null
+++ b/deps/v8/src/objects/OWNERS
@@ -0,0 +1,3 @@
+file://COMMON_OWNERS
+
+# COMPONENT: Blink>JavaScript>Runtime
diff --git a/deps/v8/src/objects/api-callbacks-inl.h b/deps/v8/src/objects/api-callbacks-inl.h
index 041247637a..c327a35746 100644
--- a/deps/v8/src/objects/api-callbacks-inl.h
+++ b/deps/v8/src/objects/api-callbacks-inl.h
@@ -13,6 +13,7 @@
#include "src/objects/js-objects-inl.h"
#include "src/objects/name.h"
#include "src/objects/templates.h"
+#include "torque-generated/class-definitions-tq-inl.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -23,12 +24,12 @@ namespace internal {
OBJECT_CONSTRUCTORS_IMPL(AccessCheckInfo, Struct)
OBJECT_CONSTRUCTORS_IMPL(AccessorInfo, Struct)
OBJECT_CONSTRUCTORS_IMPL(InterceptorInfo, Struct)
-OBJECT_CONSTRUCTORS_IMPL(CallHandlerInfo, Tuple3)
+
+TQ_OBJECT_CONSTRUCTORS_IMPL(CallHandlerInfo)
CAST_ACCESSOR(AccessorInfo)
CAST_ACCESSOR(AccessCheckInfo)
CAST_ACCESSOR(InterceptorInfo)
-CAST_ACCESSOR(CallHandlerInfo)
ACCESSORS(AccessorInfo, name, Name, kNameOffset)
SMI_ACCESSORS(AccessorInfo, flags, kFlagsOffset)
@@ -119,9 +120,6 @@ BOOL_ACCESSORS(InterceptorInfo, flags, non_masking, kNonMasking)
BOOL_ACCESSORS(InterceptorInfo, flags, is_named, kNamed)
BOOL_ACCESSORS(InterceptorInfo, flags, has_no_side_effect, kHasNoSideEffect)
-ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
-ACCESSORS(CallHandlerInfo, js_callback, Object, kJsCallbackOffset)
-ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
bool CallHandlerInfo::IsSideEffectFreeCallHandlerInfo() const {
ReadOnlyRoots roots = GetReadOnlyRoots();
diff --git a/deps/v8/src/objects/api-callbacks.h b/deps/v8/src/objects/api-callbacks.h
index 1d8b456a8e..518339f7d4 100644
--- a/deps/v8/src/objects/api-callbacks.h
+++ b/deps/v8/src/objects/api-callbacks.h
@@ -6,6 +6,7 @@
#define V8_OBJECTS_API_CALLBACKS_H_
#include "src/objects/struct.h"
+#include "torque-generated/class-definitions-tq.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -159,14 +160,9 @@ class InterceptorInfo : public Struct {
OBJECT_CONSTRUCTORS(InterceptorInfo, Struct);
};
-class CallHandlerInfo : public Tuple3 {
+class CallHandlerInfo
+ : public TorqueGeneratedCallHandlerInfo<CallHandlerInfo, Struct> {
public:
- DECL_ACCESSORS(callback, Object)
- DECL_ACCESSORS(js_callback, Object)
- DECL_ACCESSORS(data, Object)
-
- DECL_CAST(CallHandlerInfo)
-
inline bool IsSideEffectFreeCallHandlerInfo() const;
inline bool IsSideEffectCallHandlerInfo() const;
inline void SetNextCallHasNoSideEffect();
@@ -180,11 +176,7 @@ class CallHandlerInfo : public Tuple3 {
Address redirected_callback() const;
- static const int kCallbackOffset = kValue1Offset;
- static const int kJsCallbackOffset = kValue2Offset;
- static const int kDataOffset = kValue3Offset;
-
- OBJECT_CONSTRUCTORS(CallHandlerInfo, Tuple3);
+ TQ_OBJECT_CONSTRUCTORS(CallHandlerInfo)
};
} // namespace internal
diff --git a/deps/v8/src/objects/arguments-inl.h b/deps/v8/src/objects/arguments-inl.h
index c2ef59a896..2931c5b0a0 100644
--- a/deps/v8/src/objects/arguments-inl.h
+++ b/deps/v8/src/objects/arguments-inl.h
@@ -29,12 +29,14 @@ CAST_ACCESSOR(JSArgumentsObject)
SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot,
kAliasedContextSlotOffset)
-Context SloppyArgumentsElements::context() {
- return Context::cast(get(kContextIndex));
+DEF_GETTER(SloppyArgumentsElements, context, Context) {
+ return TaggedField<Context>::load(isolate, *this,
+ OffsetOfElementAt(kContextIndex));
}
-FixedArray SloppyArgumentsElements::arguments() {
- return FixedArray::cast(get(kArgumentsIndex));
+DEF_GETTER(SloppyArgumentsElements, arguments, FixedArray) {
+ return TaggedField<FixedArray>::load(isolate, *this,
+ OffsetOfElementAt(kArgumentsIndex));
}
void SloppyArgumentsElements::set_arguments(FixedArray arguments) {
diff --git a/deps/v8/src/objects/arguments.h b/deps/v8/src/objects/arguments.h
index a1d39f1f36..79d2e604bd 100644
--- a/deps/v8/src/objects/arguments.h
+++ b/deps/v8/src/objects/arguments.h
@@ -102,8 +102,8 @@ class SloppyArgumentsElements : public FixedArray {
static const int kArgumentsIndex = 1;
static const uint32_t kParameterMapStart = 2;
- inline Context context();
- inline FixedArray arguments();
+ DECL_GETTER(context, Context)
+ DECL_GETTER(arguments, FixedArray)
inline void set_arguments(FixedArray arguments);
inline uint32_t parameter_map_length();
inline Object get_mapped_entry(uint32_t entry);
diff --git a/deps/v8/src/objects/bigint.cc b/deps/v8/src/objects/bigint.cc
index 92b78f8821..b02c0f29d6 100644
--- a/deps/v8/src/objects/bigint.cc
+++ b/deps/v8/src/objects/bigint.cc
@@ -46,6 +46,8 @@ class MutableBigInt : public FreshlyAllocatedBigInt {
static MaybeHandle<BigInt> MakeImmutable(MaybeHandle<MutableBigInt> maybe);
static Handle<BigInt> MakeImmutable(Handle<MutableBigInt> result);
+ static void Canonicalize(MutableBigInt result);
+
// Allocation helpers.
static MaybeHandle<MutableBigInt> New(
Isolate* isolate, int length,
@@ -64,6 +66,10 @@ class MutableBigInt : public FreshlyAllocatedBigInt {
SLOW_DCHECK(bigint->IsBigInt());
return Handle<MutableBigInt>::cast(bigint);
}
+ static MutableBigInt cast(Object o) {
+ SLOW_DCHECK(o.IsBigInt());
+ return MutableBigInt(o.ptr());
+ }
static MutableBigInt unchecked_cast(Object o) {
return MutableBigInt(o.ptr());
}
@@ -87,8 +93,13 @@ class MutableBigInt : public FreshlyAllocatedBigInt {
static MaybeHandle<BigInt> AbsoluteAdd(Isolate* isolate, Handle<BigInt> x,
Handle<BigInt> y, bool result_sign);
+
+ static void AbsoluteAdd(MutableBigInt result, BigInt x, BigInt y);
+
static Handle<BigInt> AbsoluteSub(Isolate* isolate, Handle<BigInt> x,
Handle<BigInt> y, bool result_sign);
+ static void AbsoluteSub(MutableBigInt result, BigInt x, BigInt y);
+
static MaybeHandle<MutableBigInt> AbsoluteAddOne(
Isolate* isolate, Handle<BigIntBase> x, bool sign,
MutableBigInt result_storage = MutableBigInt());
@@ -120,6 +131,8 @@ class MutableBigInt : public FreshlyAllocatedBigInt {
static int AbsoluteCompare(Handle<BigIntBase> x, Handle<BigIntBase> y);
+ static int AbsoluteCompare(BigIntBase x, BigIntBase y);
+
static void MultiplyAccumulate(Handle<BigIntBase> multiplicand,
digit_t multiplier,
Handle<MutableBigInt> accumulator,
@@ -223,11 +236,24 @@ NEVER_READ_ONLY_SPACE_IMPL(MutableBigInt)
#include "src/objects/object-macros-undef.h"
+template <typename T>
+MaybeHandle<T> ThrowBigIntTooBig(Isolate* isolate) {
+ // If the result of a BigInt computation is truncated to 64 bit, Turbofan
+ // can sometimes truncate intermediate results already, which can prevent
+ // those from exceeding the maximum length, effectively preventing a
+ // RangeError from being thrown. As this is a performance optimization, this
+ // behavior is accepted. To prevent the correctness fuzzer from detecting this
+ // difference, we crash the program.
+ if (FLAG_correctness_fuzzer_suppressions) {
+ FATAL("Aborting on invalid BigInt length");
+ }
+ THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kBigIntTooBig), T);
+}
+
MaybeHandle<MutableBigInt> MutableBigInt::New(Isolate* isolate, int length,
AllocationType allocation) {
if (length > BigInt::kMaxLength) {
- THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kBigIntTooBig),
- MutableBigInt);
+ return ThrowBigIntTooBig<MutableBigInt>(isolate);
}
Handle<MutableBigInt> result =
Cast(isolate->factory()->NewBigInt(length, allocation));
@@ -347,32 +373,36 @@ MaybeHandle<BigInt> MutableBigInt::MakeImmutable(
}
Handle<BigInt> MutableBigInt::MakeImmutable(Handle<MutableBigInt> result) {
+ MutableBigInt::Canonicalize(*result);
+ return Handle<BigInt>::cast(result);
+}
+
+void MutableBigInt::Canonicalize(MutableBigInt result) {
// Check if we need to right-trim any leading zero-digits.
- int old_length = result->length();
+ int old_length = result.length();
int new_length = old_length;
- while (new_length > 0 && result->digit(new_length - 1) == 0) new_length--;
+ while (new_length > 0 && result.digit(new_length - 1) == 0) new_length--;
int to_trim = old_length - new_length;
if (to_trim != 0) {
- int size_delta = to_trim * kDigitSize;
- Address new_end = result->address() + BigInt::SizeFor(new_length);
- Heap* heap = result->GetHeap();
- if (!heap->IsLargeObject(*result)) {
+ int size_delta = to_trim * MutableBigInt::kDigitSize;
+ Address new_end = result.address() + BigInt::SizeFor(new_length);
+ Heap* heap = result.GetHeap();
+ if (!heap->IsLargeObject(result)) {
// We do not create a filler for objects in large object space.
// TODO(hpayer): We should shrink the large object page if the size
// of the object changed significantly.
heap->CreateFillerObjectAt(new_end, size_delta, ClearRecordedSlots::kNo);
}
- result->synchronized_set_length(new_length);
+ result.synchronized_set_length(new_length);
// Canonicalize -0n.
if (new_length == 0) {
- result->set_sign(false);
+ result.set_sign(false);
// TODO(jkummerow): If we cache a canonical 0n, return that here.
}
}
- DCHECK_IMPLIES(result->length() > 0,
- result->digit(result->length() - 1) != 0); // MSD is non-zero.
- return Handle<BigInt>(result.location());
+ DCHECK_IMPLIES(result.length() > 0,
+ result.digit(result.length() - 1) != 0); // MSD is non-zero.
}
Handle<BigInt> BigInt::Zero(Isolate* isolate) {
@@ -428,14 +458,12 @@ MaybeHandle<BigInt> BigInt::Exponentiate(Isolate* isolate, Handle<BigInt> base,
// results.
STATIC_ASSERT(kMaxLengthBits < std::numeric_limits<digit_t>::max());
if (exponent->length() > 1) {
- THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kBigIntTooBig),
- BigInt);
+ return ThrowBigIntTooBig<BigInt>(isolate);
}
digit_t exp_value = exponent->digit(0);
if (exp_value == 1) return base;
if (exp_value >= kMaxLengthBits) {
- THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kBigIntTooBig),
- BigInt);
+ return ThrowBigIntTooBig<BigInt>(isolate);
}
STATIC_ASSERT(kMaxLengthBits <= kMaxInt);
int n = static_cast<int>(exp_value);
@@ -1130,6 +1158,26 @@ void BigInt::BigIntShortPrint(std::ostream& os) {
// Internal helpers.
+void MutableBigInt::AbsoluteAdd(MutableBigInt result, BigInt x, BigInt y) {
+ DisallowHeapAllocation no_gc;
+ digit_t carry = 0;
+ int i = 0;
+ for (; i < y.length(); i++) {
+ digit_t new_carry = 0;
+ digit_t sum = digit_add(x.digit(i), y.digit(i), &new_carry);
+ sum = digit_add(sum, carry, &new_carry);
+ result.set_digit(i, sum);
+ carry = new_carry;
+ }
+ for (; i < x.length(); i++) {
+ digit_t new_carry = 0;
+ digit_t sum = digit_add(x.digit(i), carry, &new_carry);
+ result.set_digit(i, sum);
+ carry = new_carry;
+ }
+ result.set_digit(i, carry);
+}
+
MaybeHandle<BigInt> MutableBigInt::AbsoluteAdd(Isolate* isolate,
Handle<BigInt> x,
Handle<BigInt> y,
@@ -1146,22 +1194,9 @@ MaybeHandle<BigInt> MutableBigInt::AbsoluteAdd(Isolate* isolate,
if (!New(isolate, x->length() + 1).ToHandle(&result)) {
return MaybeHandle<BigInt>();
}
- digit_t carry = 0;
- int i = 0;
- for (; i < y->length(); i++) {
- digit_t new_carry = 0;
- digit_t sum = digit_add(x->digit(i), y->digit(i), &new_carry);
- sum = digit_add(sum, carry, &new_carry);
- result->set_digit(i, sum);
- carry = new_carry;
- }
- for (; i < x->length(); i++) {
- digit_t new_carry = 0;
- digit_t sum = digit_add(x->digit(i), carry, &new_carry);
- result->set_digit(i, sum);
- carry = new_carry;
- }
- result->set_digit(i, carry);
+
+ AbsoluteAdd(*result, *x, *y);
+
result->set_sign(result_sign);
return MakeImmutable(result);
}
@@ -1178,24 +1213,31 @@ Handle<BigInt> MutableBigInt::AbsoluteSub(Isolate* isolate, Handle<BigInt> x,
return result_sign == x->sign() ? x : BigInt::UnaryMinus(isolate, x);
}
Handle<MutableBigInt> result = New(isolate, x->length()).ToHandleChecked();
+
+ AbsoluteSub(*result, *x, *y);
+
+ result->set_sign(result_sign);
+ return MakeImmutable(result);
+}
+
+void MutableBigInt::AbsoluteSub(MutableBigInt result, BigInt x, BigInt y) {
+ DisallowHeapAllocation no_gc;
digit_t borrow = 0;
int i = 0;
- for (; i < y->length(); i++) {
+ for (; i < y.length(); i++) {
digit_t new_borrow = 0;
- digit_t difference = digit_sub(x->digit(i), y->digit(i), &new_borrow);
+ digit_t difference = digit_sub(x.digit(i), y.digit(i), &new_borrow);
difference = digit_sub(difference, borrow, &new_borrow);
- result->set_digit(i, difference);
+ result.set_digit(i, difference);
borrow = new_borrow;
}
- for (; i < x->length(); i++) {
+ for (; i < x.length(); i++) {
digit_t new_borrow = 0;
- digit_t difference = digit_sub(x->digit(i), borrow, &new_borrow);
- result->set_digit(i, difference);
+ digit_t difference = digit_sub(x.digit(i), borrow, &new_borrow);
+ result.set_digit(i, difference);
borrow = new_borrow;
}
DCHECK_EQ(0, borrow);
- result->set_sign(result_sign);
- return MakeImmutable(result);
}
// Adds 1 to the absolute value of {x} and sets the result's sign to {sign}.
@@ -1375,12 +1417,17 @@ Handle<MutableBigInt> MutableBigInt::AbsoluteXor(Isolate* isolate,
// Returns a positive value if abs(x) > abs(y), a negative value if
// abs(x) < abs(y), or zero if abs(x) == abs(y).
int MutableBigInt::AbsoluteCompare(Handle<BigIntBase> x, Handle<BigIntBase> y) {
- int diff = x->length() - y->length();
+ return MutableBigInt::AbsoluteCompare(*x, *y);
+}
+
+int MutableBigInt::AbsoluteCompare(BigIntBase x, BigIntBase y) {
+ DisallowHeapAllocation no_gc;
+ int diff = x.length() - y.length();
if (diff != 0) return diff;
- int i = x->length() - 1;
- while (i >= 0 && x->digit(i) == y->digit(i)) i--;
+ int i = x.length() - 1;
+ while (i >= 0 && x.digit(i) == y.digit(i)) i--;
if (i < 0) return 0;
- return x->digit(i) > y->digit(i) ? 1 : -1;
+ return x.digit(i) > y.digit(i) ? 1 : -1;
}
// Multiplies {multiplicand} with {multiplier} and adds the result to
@@ -1716,8 +1763,7 @@ MaybeHandle<BigInt> MutableBigInt::LeftShiftByAbsolute(Isolate* isolate,
Handle<BigIntBase> y) {
Maybe<digit_t> maybe_shift = ToShiftAmount(y);
if (maybe_shift.IsNothing()) {
- THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kBigIntTooBig),
- BigInt);
+ return ThrowBigIntTooBig<BigInt>(isolate);
}
digit_t shift = maybe_shift.FromJust();
int digit_shift = static_cast<int>(shift / kDigitBits);
@@ -1727,8 +1773,7 @@ MaybeHandle<BigInt> MutableBigInt::LeftShiftByAbsolute(Isolate* isolate,
(x->digit(length - 1) >> (kDigitBits - bits_shift)) != 0;
int result_length = length + digit_shift + grow;
if (result_length > kMaxLength) {
- THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kBigIntTooBig),
- BigInt);
+ return ThrowBigIntTooBig<BigInt>(isolate);
}
Handle<MutableBigInt> result;
if (!New(isolate, result_length).ToHandle(&result)) {
@@ -1887,8 +1932,7 @@ MaybeHandle<FreshlyAllocatedBigInt> BigInt::AllocateFor(
}
// All the overflow/maximum checks above fall through to here.
if (should_throw == kThrowOnError) {
- THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kBigIntTooBig),
- FreshlyAllocatedBigInt);
+ return ThrowBigIntTooBig<FreshlyAllocatedBigInt>(isolate);
} else {
return MaybeHandle<FreshlyAllocatedBigInt>();
}
@@ -2155,10 +2199,6 @@ MaybeHandle<String> MutableBigInt::ToStringGeneric(Isolate* isolate,
// the raw characters pointer (as the string might have moved).
chars = result->GetChars(no_gc);
}
- if (interrupt_check.InterruptRequested() &&
- isolate->stack_guard()->HandleInterrupts().IsException(isolate)) {
- return MaybeHandle<String>();
- }
}
} while (nonzero_digit > 0);
last_digit = rest->digit(0);
@@ -2250,8 +2290,7 @@ MaybeHandle<BigInt> BigInt::AsUintN(Isolate* isolate, uint64_t n,
// If {x} is negative, simulate two's complement representation.
if (x->sign()) {
if (n > kMaxLengthBits) {
- THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kBigIntTooBig),
- BigInt);
+ return ThrowBigIntTooBig<BigInt>(isolate);
}
return MutableBigInt::TruncateAndSubFromPowerOfTwo(
isolate, static_cast<int>(n), x, false);
@@ -2395,8 +2434,7 @@ MaybeHandle<BigInt> BigInt::FromWords64(Isolate* isolate, int sign_bit,
int words64_count,
const uint64_t* words) {
if (words64_count < 0 || words64_count > kMaxLength / (64 / kDigitBits)) {
- THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kBigIntTooBig),
- BigInt);
+ return ThrowBigIntTooBig<BigInt>(isolate);
}
if (words64_count == 0) return MutableBigInt::Zero(isolate);
STATIC_ASSERT(kDigitBits == 64 || kDigitBits == 32);
@@ -2674,5 +2712,32 @@ void BigInt::BigIntPrint(std::ostream& os) {
}
#endif // OBJECT_PRINT
+void MutableBigInt_AbsoluteAddAndCanonicalize(Address result_addr,
+ Address x_addr, Address y_addr) {
+ BigInt x = BigInt::cast(Object(x_addr));
+ BigInt y = BigInt::cast(Object(y_addr));
+ MutableBigInt result = MutableBigInt::cast(Object(result_addr));
+
+ MutableBigInt::AbsoluteAdd(result, x, y);
+ MutableBigInt::Canonicalize(result);
+}
+
+int32_t MutableBigInt_AbsoluteCompare(Address x_addr, Address y_addr) {
+ BigInt x = BigInt::cast(Object(x_addr));
+ BigInt y = BigInt::cast(Object(y_addr));
+
+ return MutableBigInt::AbsoluteCompare(x, y);
+}
+
+void MutableBigInt_AbsoluteSubAndCanonicalize(Address result_addr,
+ Address x_addr, Address y_addr) {
+ BigInt x = BigInt::cast(Object(x_addr));
+ BigInt y = BigInt::cast(Object(y_addr));
+ MutableBigInt result = MutableBigInt::cast(Object(result_addr));
+
+ MutableBigInt::AbsoluteSub(result, x, y);
+ MutableBigInt::Canonicalize(result);
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/bigint.h b/deps/v8/src/objects/bigint.h
index 3f5d35878b..a5ca514867 100644
--- a/deps/v8/src/objects/bigint.h
+++ b/deps/v8/src/objects/bigint.h
@@ -16,6 +16,12 @@
namespace v8 {
namespace internal {
+void MutableBigInt_AbsoluteAddAndCanonicalize(Address result_addr,
+ Address x_addr, Address y_addr);
+int32_t MutableBigInt_AbsoluteCompare(Address x_addr, Address y_addr);
+void MutableBigInt_AbsoluteSubAndCanonicalize(Address result_addr,
+ Address x_addr, Address y_addr);
+
class BigInt;
class ValueDeserializer;
class ValueSerializer;
@@ -66,6 +72,10 @@ class BigIntBase : public HeapObject {
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, BIGINT_FIELDS)
#undef BIGINT_FIELDS
+ static constexpr bool HasOptionalPadding() {
+ return FIELD_SIZE(kOptionalPaddingOffset) > 0;
+ }
+
private:
friend class ::v8::internal::BigInt; // MSVC wants full namespace.
friend class MutableBigInt;
diff --git a/deps/v8/src/objects/code-inl.h b/deps/v8/src/objects/code-inl.h
index 0877746d11..e6f00b0fb2 100644
--- a/deps/v8/src/objects/code-inl.h
+++ b/deps/v8/src/objects/code-inl.h
@@ -7,8 +7,8 @@
#include "src/objects/code.h"
+#include "src/base/memory.h"
#include "src/codegen/code-desc.h"
-#include "src/common/v8memory.h"
#include "src/execution/isolate.h"
#include "src/interpreter/bytecode-register.h"
#include "src/objects/dictionary.h"
@@ -29,7 +29,7 @@ OBJECT_CONSTRUCTORS_IMPL(BytecodeArray, FixedArrayBase)
OBJECT_CONSTRUCTORS_IMPL(AbstractCode, HeapObject)
OBJECT_CONSTRUCTORS_IMPL(DependentCode, WeakFixedArray)
OBJECT_CONSTRUCTORS_IMPL(CodeDataContainer, HeapObject)
-OBJECT_CONSTRUCTORS_IMPL(SourcePositionTableWithFrameCache, Struct)
+TQ_OBJECT_CONSTRUCTORS_IMPL(SourcePositionTableWithFrameCache)
NEVER_READ_ONLY_SPACE_IMPL(AbstractCode)
@@ -39,12 +39,6 @@ CAST_ACCESSOR(Code)
CAST_ACCESSOR(CodeDataContainer)
CAST_ACCESSOR(DependentCode)
CAST_ACCESSOR(DeoptimizationData)
-CAST_ACCESSOR(SourcePositionTableWithFrameCache)
-
-ACCESSORS(SourcePositionTableWithFrameCache, source_position_table, ByteArray,
- kSourcePositionTableOffset)
-ACCESSORS(SourcePositionTableWithFrameCache, stack_frame_cache,
- SimpleNumberDictionary, kStackFrameCacheOffset)
int AbstractCode::raw_instruction_size() {
if (IsCode()) {
@@ -331,7 +325,9 @@ int Code::SizeIncludingMetadata() const {
}
ByteArray Code::unchecked_relocation_info() const {
- return ByteArray::unchecked_cast(READ_FIELD(*this, kRelocationInfoOffset));
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return ByteArray::unchecked_cast(
+ TaggedField<HeapObject, kRelocationInfoOffset>::load(isolate, *this));
}
byte* Code::relocation_start() const {
@@ -575,7 +571,7 @@ Code Code::GetCodeFromTargetAddress(Address address) {
}
Code Code::GetObjectFromEntryAddress(Address location_of_address) {
- Address code_entry = Memory<Address>(location_of_address);
+ Address code_entry = base::Memory<Address>(location_of_address);
HeapObject code = HeapObject::FromAddress(code_entry - Code::kHeaderSize);
// Unchecked cast because we can't rely on the map currently
// not being a forwarding pointer.
@@ -622,32 +618,32 @@ void BytecodeArray::set(int index, byte value) {
WriteField<byte>(kHeaderSize + index * kCharSize, value);
}
-void BytecodeArray::set_frame_size(int frame_size) {
+void BytecodeArray::set_frame_size(int32_t frame_size) {
DCHECK_GE(frame_size, 0);
DCHECK(IsAligned(frame_size, kSystemPointerSize));
- WriteField<int>(kFrameSizeOffset, frame_size);
+ WriteField<int32_t>(kFrameSizeOffset, frame_size);
}
-int BytecodeArray::frame_size() const {
- return ReadField<int>(kFrameSizeOffset);
+int32_t BytecodeArray::frame_size() const {
+ return ReadField<int32_t>(kFrameSizeOffset);
}
int BytecodeArray::register_count() const {
- return frame_size() / kSystemPointerSize;
+ return static_cast<int>(frame_size()) / kSystemPointerSize;
}
-void BytecodeArray::set_parameter_count(int number_of_parameters) {
+void BytecodeArray::set_parameter_count(int32_t number_of_parameters) {
DCHECK_GE(number_of_parameters, 0);
// Parameter count is stored as the size on stack of the parameters to allow
// it to be used directly by generated code.
- WriteField<int>(kParameterSizeOffset,
+ WriteField<int32_t>(kParameterSizeOffset,
(number_of_parameters << kSystemPointerSizeLog2));
}
interpreter::Register BytecodeArray::incoming_new_target_or_generator_register()
const {
- int register_operand =
- ReadField<int>(kIncomingNewTargetOrGeneratorRegisterOffset);
+ int32_t register_operand =
+ ReadField<int32_t>(kIncomingNewTargetOrGeneratorRegisterOffset);
if (register_operand == 0) {
return interpreter::Register::invalid_value();
} else {
@@ -658,24 +654,24 @@ interpreter::Register BytecodeArray::incoming_new_target_or_generator_register()
void BytecodeArray::set_incoming_new_target_or_generator_register(
interpreter::Register incoming_new_target_or_generator_register) {
if (!incoming_new_target_or_generator_register.is_valid()) {
- WriteField<int>(kIncomingNewTargetOrGeneratorRegisterOffset, 0);
+ WriteField<int32_t>(kIncomingNewTargetOrGeneratorRegisterOffset, 0);
} else {
DCHECK(incoming_new_target_or_generator_register.index() <
register_count());
DCHECK_NE(0, incoming_new_target_or_generator_register.ToOperand());
- WriteField<int>(kIncomingNewTargetOrGeneratorRegisterOffset,
+ WriteField<int32_t>(kIncomingNewTargetOrGeneratorRegisterOffset,
incoming_new_target_or_generator_register.ToOperand());
}
}
int BytecodeArray::osr_loop_nesting_level() const {
- return ReadField<int8_t>(kOSRNestingLevelOffset);
+ return ReadField<int8_t>(kOsrNestingLevelOffset);
}
void BytecodeArray::set_osr_loop_nesting_level(int depth) {
DCHECK(0 <= depth && depth <= AbstractCode::kMaxLoopNestingMarker);
STATIC_ASSERT(AbstractCode::kMaxLoopNestingMarker < kMaxInt8);
- WriteField<int8_t>(kOSRNestingLevelOffset, depth);
+ WriteField<int8_t>(kOsrNestingLevelOffset, depth);
}
BytecodeArray::Age BytecodeArray::bytecode_age() const {
@@ -691,10 +687,10 @@ void BytecodeArray::set_bytecode_age(BytecodeArray::Age age) {
RELAXED_WRITE_INT8_FIELD(*this, kBytecodeAgeOffset, static_cast<int8_t>(age));
}
-int BytecodeArray::parameter_count() const {
+int32_t BytecodeArray::parameter_count() const {
// Parameter count is stored as the size on stack of the parameters to allow
// it to be used directly by generated code.
- return ReadField<int>(kParameterSizeOffset) >> kSystemPointerSizeLog2;
+ return ReadField<int32_t>(kParameterSizeOffset) >> kSystemPointerSizeLog2;
}
ACCESSORS(BytecodeArray, constant_pool, FixedArray, kConstantPoolOffset)
@@ -745,7 +741,9 @@ ByteArray BytecodeArray::SourcePositionTableIfCollected() const {
void BytecodeArray::ClearFrameCacheFromSourcePositionTable() {
Object maybe_table = source_position_table();
- if (maybe_table.IsUndefined() || maybe_table.IsByteArray()) return;
+ if (maybe_table.IsUndefined() || maybe_table.IsByteArray() ||
+ maybe_table.IsException())
+ return;
DCHECK(maybe_table.IsSourcePositionTableWithFrameCache());
set_source_position_table(SourcePositionTableWithFrameCache::cast(maybe_table)
.source_position_table());
diff --git a/deps/v8/src/objects/code.cc b/deps/v8/src/objects/code.cc
index 89180693a5..a51a8c5b79 100644
--- a/deps/v8/src/objects/code.cc
+++ b/deps/v8/src/objects/code.cc
@@ -352,7 +352,8 @@ bool Code::Inlines(SharedFunctionInfo sfi) {
Code::OptimizedCodeIterator::OptimizedCodeIterator(Isolate* isolate) {
isolate_ = isolate;
Object list = isolate->heap()->native_contexts_list();
- next_context_ = list.IsUndefined(isolate_) ? Context() : Context::cast(list);
+ next_context_ =
+ list.IsUndefined(isolate_) ? NativeContext() : NativeContext::cast(list);
}
Code Code::OptimizedCodeIterator::Next() {
@@ -366,8 +367,8 @@ Code Code::OptimizedCodeIterator::Next() {
next = next_context_.OptimizedCodeListHead();
Object next_context = next_context_.next_context_link();
next_context_ = next_context.IsUndefined(isolate_)
- ? Context()
- : Context::cast(next_context);
+ ? NativeContext()
+ : NativeContext::cast(next_context);
} else {
// Exhausted contexts.
return Code();
@@ -830,7 +831,8 @@ void BytecodeArray::Disassemble(std::ostream& os) {
os << reinterpret_cast<const void*>(current_address) << " @ "
<< std::setw(4) << iterator.current_offset() << " : ";
interpreter::BytecodeDecoder::Decode(
- os, reinterpret_cast<byte*>(current_address), parameter_count());
+ os, reinterpret_cast<byte*>(current_address),
+ static_cast<int>(parameter_count()));
if (interpreter::Bytecodes::IsJump(iterator.current_bytecode())) {
Address jump_target = base_address + iterator.GetJumpTargetOffset();
os << " (" << reinterpret_cast<void*>(jump_target) << " @ "
@@ -856,7 +858,7 @@ void BytecodeArray::Disassemble(std::ostream& os) {
os << "Constant pool (size = " << constant_pool().length() << ")\n";
#ifdef OBJECT_PRINT
if (constant_pool().length() > 0) {
- constant_pool().Print();
+ constant_pool().Print(os);
}
#endif
@@ -1084,5 +1086,15 @@ const char* DependentCode::DependencyGroupName(DependencyGroup group) {
UNREACHABLE();
}
+bool BytecodeArray::IsBytecodeEqual(const BytecodeArray other) const {
+ if (length() != other.length()) return false;
+
+ for (int i = 0; i < length(); ++i) {
+ if (get(i) != other.get(i)) return false;
+ }
+
+ return true;
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/code.h b/deps/v8/src/objects/code.h
index a950261103..2f85d4ac7b 100644
--- a/deps/v8/src/objects/code.h
+++ b/deps/v8/src/objects/code.h
@@ -476,7 +476,7 @@ class Code::OptimizedCodeIterator {
Code Next();
private:
- Context next_context_;
+ NativeContext next_context_;
Code current_code_;
Isolate* isolate_;
@@ -741,15 +741,15 @@ class BytecodeArray : public FixedArrayBase {
inline Address GetFirstBytecodeAddress();
// Accessors for frame size.
- inline int frame_size() const;
- inline void set_frame_size(int frame_size);
+ inline int32_t frame_size() const;
+ inline void set_frame_size(int32_t frame_size);
// Accessor for register count (derived from frame_size).
inline int register_count() const;
// Accessors for parameter count (including implicit 'this' receiver).
- inline int parameter_count() const;
- inline void set_parameter_count(int number_of_parameters);
+ inline int32_t parameter_count() const;
+ inline void set_parameter_count(int32_t number_of_parameters);
// Register used to pass the incoming new.target or generator object from the
// fucntion call.
@@ -828,28 +828,15 @@ class BytecodeArray : public FixedArrayBase {
// Compares only the bytecode array but not any of the header fields.
bool IsBytecodeEqual(const BytecodeArray other) const;
-// Layout description.
-#define BYTECODE_ARRAY_FIELDS(V) \
- /* Pointer fields. */ \
- V(kConstantPoolOffset, kTaggedSize) \
- V(kHandlerTableOffset, kTaggedSize) \
- V(kSourcePositionTableOffset, kTaggedSize) \
- V(kFrameSizeOffset, kIntSize) \
- V(kParameterSizeOffset, kIntSize) \
- V(kIncomingNewTargetOrGeneratorRegisterOffset, kIntSize) \
- V(kOSRNestingLevelOffset, kCharSize) \
- V(kBytecodeAgeOffset, kCharSize) \
- /* Total size. */ \
- V(kHeaderSize, 0)
-
+ // Layout description.
DEFINE_FIELD_OFFSET_CONSTANTS(FixedArrayBase::kHeaderSize,
- BYTECODE_ARRAY_FIELDS)
-#undef BYTECODE_ARRAY_FIELDS
+ TORQUE_GENERATED_BYTECODE_ARRAY_FIELDS)
+ static constexpr int kHeaderSize = kSize;
// InterpreterEntryTrampoline expects these fields to be next to each other
// and writes a 16-bit value to reset them.
STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset ==
- kOSRNestingLevelOffset + kCharSize);
+ kOsrNestingLevelOffset + kCharSize);
// Maximal memory consumption for a single BytecodeArray.
static const int kMaxSize = 512 * MB;
@@ -948,22 +935,11 @@ class DeoptimizationData : public FixedArray {
OBJECT_CONSTRUCTORS(DeoptimizationData, FixedArray);
};
-class SourcePositionTableWithFrameCache : public Struct {
+class SourcePositionTableWithFrameCache
+ : public TorqueGeneratedSourcePositionTableWithFrameCache<
+ SourcePositionTableWithFrameCache, Struct> {
public:
- DECL_ACCESSORS(source_position_table, ByteArray)
- DECL_ACCESSORS(stack_frame_cache, SimpleNumberDictionary)
-
- DECL_CAST(SourcePositionTableWithFrameCache)
-
- DECL_PRINTER(SourcePositionTableWithFrameCache)
- DECL_VERIFIER(SourcePositionTableWithFrameCache)
-
- // Layout description.
- DEFINE_FIELD_OFFSET_CONSTANTS(
- Struct::kHeaderSize,
- TORQUE_GENERATED_SOURCE_POSITION_TABLE_WITH_FRAME_CACHE_FIELDS)
-
- OBJECT_CONSTRUCTORS(SourcePositionTableWithFrameCache, Struct);
+ TQ_OBJECT_CONSTRUCTORS(SourcePositionTableWithFrameCache)
};
} // namespace internal
diff --git a/deps/v8/src/objects/compressed-slots-inl.h b/deps/v8/src/objects/compressed-slots-inl.h
index b08bc938e5..a93814fee2 100644
--- a/deps/v8/src/objects/compressed-slots-inl.h
+++ b/deps/v8/src/objects/compressed-slots-inl.h
@@ -22,6 +22,12 @@ namespace internal {
CompressedObjectSlot::CompressedObjectSlot(Object* object)
: SlotBase(reinterpret_cast<Address>(&object->ptr_)) {}
+bool CompressedObjectSlot::contains_value(Address raw_value) const {
+ AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location());
+ return static_cast<uint32_t>(value) ==
+ static_cast<uint32_t>(static_cast<Tagged_t>(raw_value));
+}
+
Object CompressedObjectSlot::operator*() const {
Tagged_t value = *location();
return Object(DecompressTaggedAny(address(), value));
@@ -61,54 +67,6 @@ Object CompressedObjectSlot::Release_CompareAndSwap(Object old,
}
//
-// CompressedMapWordSlot implementation.
-//
-
-bool CompressedMapWordSlot::contains_value(Address raw_value) const {
- AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location());
- return static_cast<uint32_t>(value) ==
- static_cast<uint32_t>(static_cast<Tagged_t>(raw_value));
-}
-
-Object CompressedMapWordSlot::operator*() const {
- Tagged_t value = *location();
- return Object(DecompressTaggedPointer(address(), value));
-}
-
-void CompressedMapWordSlot::store(Object value) const {
- *location() = CompressTagged(value.ptr());
-}
-
-Object CompressedMapWordSlot::Relaxed_Load() const {
- AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location());
- return Object(DecompressTaggedPointer(address(), value));
-}
-
-void CompressedMapWordSlot::Relaxed_Store(Object value) const {
- Tagged_t ptr = CompressTagged(value.ptr());
- AsAtomicTagged::Relaxed_Store(location(), ptr);
-}
-
-Object CompressedMapWordSlot::Acquire_Load() const {
- AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location());
- return Object(DecompressTaggedPointer(address(), value));
-}
-
-void CompressedMapWordSlot::Release_Store(Object value) const {
- Tagged_t ptr = CompressTagged(value.ptr());
- AsAtomicTagged::Release_Store(location(), ptr);
-}
-
-Object CompressedMapWordSlot::Release_CompareAndSwap(Object old,
- Object target) const {
- Tagged_t old_ptr = CompressTagged(old.ptr());
- Tagged_t target_ptr = CompressTagged(target.ptr());
- Tagged_t result =
- AsAtomicTagged::Release_CompareAndSwap(location(), old_ptr, target_ptr);
- return Object(DecompressTaggedPointer(address(), result));
-}
-
-//
// CompressedMaybeObjectSlot implementation.
//
diff --git a/deps/v8/src/objects/compressed-slots.h b/deps/v8/src/objects/compressed-slots.h
index 45df733caf..07660b1961 100644
--- a/deps/v8/src/objects/compressed-slots.h
+++ b/deps/v8/src/objects/compressed-slots.h
@@ -34,32 +34,6 @@ class CompressedObjectSlot : public SlotBase<CompressedObjectSlot, Tagged_t> {
explicit CompressedObjectSlot(SlotBase<T, TData, kSlotDataAlignment> slot)
: SlotBase(slot.address()) {}
- inline Object operator*() const;
- inline void store(Object value) const;
-
- inline Object Acquire_Load() const;
- inline Object Relaxed_Load() const;
- inline void Relaxed_Store(Object value) const;
- inline void Release_Store(Object value) const;
- inline Object Release_CompareAndSwap(Object old, Object target) const;
-};
-
-// A CompressedMapWordSlot instance describes a kTaggedSize-sized map-word field
-// ("slot") of heap objects holding a compressed tagged pointer or a Smi
-// representing forwaring pointer value.
-// This slot kind is similar to CompressedObjectSlot but decompression of
-// forwarding pointer is different.
-// Its address() is the address of the slot.
-// The slot's contents can be read and written using operator* and store().
-class CompressedMapWordSlot : public SlotBase<CompressedMapWordSlot, Tagged_t> {
- public:
- using TObject = Object;
-
- static constexpr bool kCanBeWeak = false;
-
- CompressedMapWordSlot() : SlotBase(kNullAddress) {}
- explicit CompressedMapWordSlot(Address ptr) : SlotBase(ptr) {}
-
// Compares memory representation of a value stored in the slot with given
// raw value without decompression.
inline bool contains_value(Address raw_value) const;
@@ -67,10 +41,9 @@ class CompressedMapWordSlot : public SlotBase<CompressedMapWordSlot, Tagged_t> {
inline Object operator*() const;
inline void store(Object value) const;
+ inline Object Acquire_Load() const;
inline Object Relaxed_Load() const;
inline void Relaxed_Store(Object value) const;
-
- inline Object Acquire_Load() const;
inline void Release_Store(Object value) const;
inline Object Release_CompareAndSwap(Object old, Object target) const;
};
diff --git a/deps/v8/src/objects/contexts-inl.h b/deps/v8/src/objects/contexts-inl.h
index bb861a1d1e..0c566dd081 100644
--- a/deps/v8/src/objects/contexts-inl.h
+++ b/deps/v8/src/objects/contexts-inl.h
@@ -52,9 +52,15 @@ SMI_ACCESSORS(Context, length, kLengthOffset)
CAST_ACCESSOR(NativeContext)
Object Context::get(int index) const {
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return get(isolate, index);
+}
+
+Object Context::get(Isolate* isolate, int index) const {
DCHECK_LT(static_cast<unsigned>(index),
static_cast<unsigned>(this->length()));
- return RELAXED_READ_FIELD(*this, OffsetOfElementAt(index));
+ return TaggedField<Object>::Relaxed_Load(isolate, *this,
+ OffsetOfElementAt(index));
}
void Context::set(int index, Object value) {
diff --git a/deps/v8/src/objects/contexts.cc b/deps/v8/src/objects/contexts.cc
index cddbcb98c0..861e06d87f 100644
--- a/deps/v8/src/objects/contexts.cc
+++ b/deps/v8/src/objects/contexts.cc
@@ -44,7 +44,7 @@ bool ScriptContextTable::Lookup(Isolate* isolate, ScriptContextTable table,
DCHECK(context.IsScriptContext());
int slot_index = ScopeInfo::ContextSlotIndex(
context.scope_info(), name, &result->mode, &result->init_flag,
- &result->maybe_assigned_flag);
+ &result->maybe_assigned_flag, &result->requires_brand_check);
if (slot_index >= 0) {
result->context_index = i;
@@ -105,12 +105,12 @@ ScopeInfo Context::scope_info() {
return ScopeInfo::cast(get(SCOPE_INFO_INDEX));
}
-Module Context::module() {
+SourceTextModule Context::module() {
Context current = *this;
while (!current.IsModuleContext()) {
current = current.previous();
}
- return Module::cast(current.extension());
+ return SourceTextModule::cast(current.extension());
}
JSGlobalObject Context::global_object() {
@@ -287,8 +287,10 @@ Handle<Object> Context::Lookup(Handle<Context> context, Handle<String> name,
VariableMode mode;
InitializationFlag flag;
MaybeAssignedFlag maybe_assigned_flag;
+ RequiresBrandCheckFlag requires_brand_check;
int slot_index = ScopeInfo::ContextSlotIndex(scope_info, *name, &mode,
- &flag, &maybe_assigned_flag);
+ &flag, &maybe_assigned_flag,
+ &requires_brand_check);
DCHECK(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS);
if (slot_index >= 0) {
if (FLAG_trace_contexts) {
@@ -338,8 +340,8 @@ Handle<Object> Context::Lookup(Handle<Context> context, Handle<String> name,
*index = cell_index;
*variable_mode = mode;
*init_flag = flag;
- *attributes = ModuleDescriptor::GetCellIndexKind(cell_index) ==
- ModuleDescriptor::kExport
+ *attributes = SourceTextModuleDescriptor::GetCellIndexKind(
+ cell_index) == SourceTextModuleDescriptor::kExport
? GetAttributesForMode(mode)
: READ_ONLY;
return handle(context->module(), isolate);
@@ -394,31 +396,26 @@ Handle<Object> Context::Lookup(Handle<Context> context, Handle<String> name,
return Handle<Object>::null();
}
-void Context::AddOptimizedCode(Code code) {
- DCHECK(IsNativeContext());
+void NativeContext::AddOptimizedCode(Code code) {
DCHECK(code.kind() == Code::OPTIMIZED_FUNCTION);
DCHECK(code.next_code_link().IsUndefined());
code.set_next_code_link(get(OPTIMIZED_CODE_LIST));
set(OPTIMIZED_CODE_LIST, code, UPDATE_WEAK_WRITE_BARRIER);
}
-void Context::SetOptimizedCodeListHead(Object head) {
- DCHECK(IsNativeContext());
+void NativeContext::SetOptimizedCodeListHead(Object head) {
set(OPTIMIZED_CODE_LIST, head, UPDATE_WEAK_WRITE_BARRIER);
}
-Object Context::OptimizedCodeListHead() {
- DCHECK(IsNativeContext());
+Object NativeContext::OptimizedCodeListHead() {
return get(OPTIMIZED_CODE_LIST);
}
-void Context::SetDeoptimizedCodeListHead(Object head) {
- DCHECK(IsNativeContext());
+void NativeContext::SetDeoptimizedCodeListHead(Object head) {
set(DEOPTIMIZED_CODE_LIST, head, UPDATE_WEAK_WRITE_BARRIER);
}
-Object Context::DeoptimizedCodeListHead() {
- DCHECK(IsNativeContext());
+Object NativeContext::DeoptimizedCodeListHead() {
return get(DEOPTIMIZED_CODE_LIST);
}
@@ -474,19 +471,14 @@ bool Context::IsBootstrappingOrValidParentContext(Object object,
#endif
-void Context::ResetErrorsThrown() {
- DCHECK(IsNativeContext());
- set_errors_thrown(Smi::FromInt(0));
-}
-
-void Context::IncrementErrorsThrown() {
- DCHECK(IsNativeContext());
+void NativeContext::ResetErrorsThrown() { set_errors_thrown(Smi::FromInt(0)); }
+void NativeContext::IncrementErrorsThrown() {
int previous_value = errors_thrown().value();
set_errors_thrown(Smi::FromInt(previous_value + 1));
}
-int Context::GetErrorsThrown() { return errors_thrown().value(); }
+int NativeContext::GetErrorsThrown() { return errors_thrown().value(); }
STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);
STATIC_ASSERT(NativeContext::kScopeInfoOffset ==
diff --git a/deps/v8/src/objects/contexts.h b/deps/v8/src/objects/contexts.h
index d83e351550..0c00aba08e 100644
--- a/deps/v8/src/objects/contexts.h
+++ b/deps/v8/src/objects/contexts.h
@@ -38,9 +38,6 @@ enum ContextLookupFlags {
// Factory::NewContext.
#define NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(V) \
- V(ASYNC_FUNCTION_PROMISE_CREATE_INDEX, JSFunction, \
- async_function_promise_create) \
- V(IS_ARRAYLIKE, JSFunction, is_arraylike) \
V(GENERATOR_NEXT_INTERNAL, JSFunction, generator_next_internal) \
V(MAKE_ERROR_INDEX, JSFunction, make_error) \
V(MAKE_RANGE_ERROR_INDEX, JSFunction, make_range_error) \
@@ -48,20 +45,10 @@ enum ContextLookupFlags {
V(MAKE_TYPE_ERROR_INDEX, JSFunction, make_type_error) \
V(MAKE_URI_ERROR_INDEX, JSFunction, make_uri_error) \
V(OBJECT_CREATE, JSFunction, object_create) \
- V(OBJECT_DEFINE_PROPERTIES, JSFunction, object_define_properties) \
- V(OBJECT_DEFINE_PROPERTY, JSFunction, object_define_property) \
- V(OBJECT_GET_PROTOTYPE_OF, JSFunction, object_get_prototype_of) \
- V(OBJECT_IS_EXTENSIBLE, JSFunction, object_is_extensible) \
- V(OBJECT_IS_FROZEN, JSFunction, object_is_frozen) \
- V(OBJECT_IS_SEALED, JSFunction, object_is_sealed) \
- V(OBJECT_KEYS, JSFunction, object_keys) \
V(REFLECT_APPLY_INDEX, JSFunction, reflect_apply) \
V(REFLECT_CONSTRUCT_INDEX, JSFunction, reflect_construct) \
- V(REFLECT_DEFINE_PROPERTY_INDEX, JSFunction, reflect_define_property) \
- V(REFLECT_DELETE_PROPERTY_INDEX, JSFunction, reflect_delete_property) \
V(MATH_FLOOR_INDEX, JSFunction, math_floor) \
V(MATH_POW_INDEX, JSFunction, math_pow) \
- V(NEW_PROMISE_CAPABILITY_INDEX, JSFunction, new_promise_capability) \
V(PROMISE_INTERNAL_CONSTRUCTOR_INDEX, JSFunction, \
promise_internal_constructor) \
V(IS_PROMISE_INDEX, JSFunction, is_promise) \
@@ -193,8 +180,10 @@ enum ContextLookupFlags {
V(JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_MAP_INDEX, Map, \
js_finalization_group_cleanup_iterator_map) \
V(JS_WEAK_MAP_FUN_INDEX, JSFunction, js_weak_map_fun) \
- V(JS_WEAK_REF_MAP_INDEX, Map, js_weak_ref_map) \
V(JS_WEAK_SET_FUN_INDEX, JSFunction, js_weak_set_fun) \
+ V(JS_WEAK_REF_FUNCTION_INDEX, JSFunction, js_weak_ref_fun) \
+ V(JS_FINALIZATION_GROUP_FUNCTION_INDEX, JSFunction, \
+ js_finalization_group_fun) \
V(MAP_CACHE_INDEX, Object, map_cache) \
V(MAP_KEY_ITERATOR_MAP_INDEX, Map, map_key_iterator_map) \
V(MAP_KEY_VALUE_ITERATOR_MAP_INDEX, Map, map_key_value_iterator_map) \
@@ -238,12 +227,14 @@ enum ContextLookupFlags {
V(REGEXP_EXEC_FUNCTION_INDEX, JSFunction, regexp_exec_function) \
V(REGEXP_FUNCTION_INDEX, JSFunction, regexp_function) \
V(REGEXP_LAST_MATCH_INFO_INDEX, RegExpMatchInfo, regexp_last_match_info) \
+ V(REGEXP_PROTOTYPE_INDEX, JSObject, regexp_prototype) \
V(REGEXP_PROTOTYPE_MAP_INDEX, Map, regexp_prototype_map) \
+ V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map) \
+ V(REGEXP_SPECIES_PROTECTOR_INDEX, PropertyCell, regexp_species_protector) \
V(INITIAL_REGEXP_STRING_ITERATOR_PROTOTYPE_MAP_INDEX, Map, \
initial_regexp_string_iterator_prototype_map) \
- V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map) \
- V(REGEXP_PROTOTYPE_INDEX, JSObject, regexp_prototype) \
V(SCRIPT_CONTEXT_TABLE_INDEX, ScriptContextTable, script_context_table) \
+ V(SCRIPT_EXECUTION_CALLBACK_INDEX, Object, script_execution_callback) \
V(SECURITY_TOKEN_INDEX, Object, security_token) \
V(SERIALIZED_OBJECTS, FixedArray, serialized_objects) \
V(SET_VALUE_ITERATOR_MAP_INDEX, Map, set_value_iterator_map) \
@@ -302,7 +293,6 @@ enum ContextLookupFlags {
V(SYMBOL_FUNCTION_INDEX, JSFunction, symbol_function) \
V(WASM_EXPORTED_FUNCTION_MAP_INDEX, Map, wasm_exported_function_map) \
V(WASM_EXCEPTION_CONSTRUCTOR_INDEX, JSFunction, wasm_exception_constructor) \
- V(WASM_FUNCTION_CONSTRUCTOR_INDEX, JSFunction, wasm_function_constructor) \
V(WASM_GLOBAL_CONSTRUCTOR_INDEX, JSFunction, wasm_global_constructor) \
V(WASM_INSTANCE_CONSTRUCTOR_INDEX, JSFunction, wasm_instance_constructor) \
V(WASM_MEMORY_CONSTRUCTOR_INDEX, JSFunction, wasm_memory_constructor) \
@@ -366,6 +356,7 @@ class ScriptContextTable : public FixedArray {
VariableMode mode;
InitializationFlag init_flag;
MaybeAssignedFlag maybe_assigned_flag;
+ RequiresBrandCheckFlag requires_brand_check;
};
inline int used() const;
@@ -453,6 +444,7 @@ class Context : public HeapObject {
// Setter and getter for elements.
V8_INLINE Object get(int index) const;
+ V8_INLINE Object get(Isolate* isolate, int index) const;
V8_INLINE void set(int index, Object value);
// Setter with explicit barrier mode.
V8_INLINE void set(int index, Object value, WriteBarrierMode mode);
@@ -531,10 +523,6 @@ class Context : public HeapObject {
static const int kNoContext = 0;
static const int kInvalidContext = 1;
- void ResetErrorsThrown();
- void IncrementErrorsThrown();
- int GetErrorsThrown();
-
// Direct slot access.
inline void set_scope_info(ScopeInfo scope_info);
@@ -553,7 +541,7 @@ class Context : public HeapObject {
// Find the module context (assuming there is one) and return the associated
// module object.
- Module module();
+ SourceTextModule module();
// Get the context where var declarations will be hoisted to, which
// may be the context itself.
@@ -591,14 +579,6 @@ class Context : public HeapObject {
inline bool HasSameSecurityTokenAs(Context that) const;
- // The native context also stores a list of all optimized code and a
- // list of all deoptimized code, which are needed by the deoptimizer.
- V8_EXPORT_PRIVATE void AddOptimizedCode(Code code);
- void SetOptimizedCodeListHead(Object head);
- Object OptimizedCodeListHead();
- void SetDeoptimizedCodeListHead(Object head);
- Object DeoptimizedCodeListHead();
-
Handle<Object> ErrorMessageForCodeGenerationFromStrings();
static int IntrinsicIndexForName(Handle<String> name);
@@ -703,6 +683,18 @@ class NativeContext : public Context {
class BodyDescriptor;
+ // The native context stores a list of all optimized code and a list of all
+ // deoptimized code, which are needed by the deoptimizer.
+ V8_EXPORT_PRIVATE void AddOptimizedCode(Code code);
+ void SetOptimizedCodeListHead(Object head);
+ Object OptimizedCodeListHead();
+ void SetDeoptimizedCodeListHead(Object head);
+ Object DeoptimizedCodeListHead();
+
+ void ResetErrorsThrown();
+ void IncrementErrorsThrown();
+ int GetErrorsThrown();
+
private:
STATIC_ASSERT(OffsetOfElementAt(EMBEDDER_DATA_INDEX) ==
Internals::kNativeContextEmbedderDataOffset);
diff --git a/deps/v8/src/objects/descriptor-array-inl.h b/deps/v8/src/objects/descriptor-array-inl.h
index 1cd64c1bf1..e2805d795a 100644
--- a/deps/v8/src/objects/descriptor-array-inl.h
+++ b/deps/v8/src/objects/descriptor-array-inl.h
@@ -25,13 +25,9 @@ namespace v8 {
namespace internal {
OBJECT_CONSTRUCTORS_IMPL(DescriptorArray, HeapObject)
-OBJECT_CONSTRUCTORS_IMPL(EnumCache, Struct)
+TQ_OBJECT_CONSTRUCTORS_IMPL(EnumCache)
CAST_ACCESSOR(DescriptorArray)
-CAST_ACCESSOR(EnumCache)
-
-ACCESSORS(EnumCache, keys, FixedArray, kKeysOffset)
-ACCESSORS(EnumCache, indices, FixedArray, kIndicesOffset)
ACCESSORS(DescriptorArray, enum_cache, EnumCache, kEnumCacheOffset)
RELAXED_INT16_ACCESSORS(DescriptorArray, number_of_all_descriptors,
@@ -106,17 +102,22 @@ ObjectSlot DescriptorArray::GetDescriptorSlot(int descriptor) {
return RawField(OffsetOfDescriptorAt(descriptor));
}
-ObjectSlot DescriptorArray::GetKeySlot(int descriptor) {
- DCHECK_LE(descriptor, number_of_all_descriptors());
- ObjectSlot slot = GetDescriptorSlot(descriptor) + kEntryKeyIndex;
- DCHECK((*slot).IsObject());
- return slot;
+Name DescriptorArray::GetKey(int descriptor_number) const {
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return GetKey(isolate, descriptor_number);
}
-Name DescriptorArray::GetKey(int descriptor_number) const {
- DCHECK(descriptor_number < number_of_descriptors());
- return Name::cast(
- get(ToKeyIndex(descriptor_number))->GetHeapObjectAssumeStrong());
+Name DescriptorArray::GetKey(Isolate* isolate, int descriptor_number) const {
+ DCHECK_LT(descriptor_number, number_of_descriptors());
+ int entry_offset = OffsetOfDescriptorAt(descriptor_number);
+ return Name::cast(EntryKeyField::Relaxed_Load(isolate, *this, entry_offset));
+}
+
+void DescriptorArray::SetKey(int descriptor_number, Name key) {
+ DCHECK_LT(descriptor_number, number_of_descriptors());
+ int entry_offset = OffsetOfDescriptorAt(descriptor_number);
+ EntryKeyField::Relaxed_Store(*this, entry_offset, key);
+ WRITE_BARRIER(*this, entry_offset + kEntryKeyOffset, key);
}
int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
@@ -124,38 +125,59 @@ int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
}
Name DescriptorArray::GetSortedKey(int descriptor_number) {
- return GetKey(GetSortedKeyIndex(descriptor_number));
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return GetSortedKey(isolate, descriptor_number);
}
-void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) {
- PropertyDetails details = GetDetails(descriptor_index);
- set(ToDetailsIndex(descriptor_index),
- MaybeObject::FromObject(details.set_pointer(pointer).AsSmi()));
+Name DescriptorArray::GetSortedKey(Isolate* isolate, int descriptor_number) {
+ return GetKey(isolate, GetSortedKeyIndex(descriptor_number));
}
-MaybeObjectSlot DescriptorArray::GetValueSlot(int descriptor) {
- DCHECK_LT(descriptor, number_of_descriptors());
- return MaybeObjectSlot(GetDescriptorSlot(descriptor) + kEntryValueIndex);
+void DescriptorArray::SetSortedKey(int descriptor_number, int pointer) {
+ PropertyDetails details = GetDetails(descriptor_number);
+ SetDetails(descriptor_number, details.set_pointer(pointer));
}
Object DescriptorArray::GetStrongValue(int descriptor_number) {
- DCHECK(descriptor_number < number_of_descriptors());
- return get(ToValueIndex(descriptor_number))->cast<Object>();
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return GetStrongValue(isolate, descriptor_number);
+}
+
+Object DescriptorArray::GetStrongValue(Isolate* isolate,
+ int descriptor_number) {
+ return GetValue(isolate, descriptor_number).cast<Object>();
}
-void DescriptorArray::SetValue(int descriptor_index, Object value) {
- set(ToValueIndex(descriptor_index), MaybeObject::FromObject(value));
+void DescriptorArray::SetValue(int descriptor_number, MaybeObject value) {
+ DCHECK_LT(descriptor_number, number_of_descriptors());
+ int entry_offset = OffsetOfDescriptorAt(descriptor_number);
+ EntryValueField::Relaxed_Store(*this, entry_offset, value);
+ WEAK_WRITE_BARRIER(*this, entry_offset + kEntryValueOffset, value);
}
MaybeObject DescriptorArray::GetValue(int descriptor_number) {
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return GetValue(isolate, descriptor_number);
+}
+
+MaybeObject DescriptorArray::GetValue(Isolate* isolate, int descriptor_number) {
DCHECK_LT(descriptor_number, number_of_descriptors());
- return get(ToValueIndex(descriptor_number));
+ int entry_offset = OffsetOfDescriptorAt(descriptor_number);
+ return EntryValueField::Relaxed_Load(isolate, *this, entry_offset);
}
PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
- DCHECK(descriptor_number < number_of_descriptors());
- MaybeObject details = get(ToDetailsIndex(descriptor_number));
- return PropertyDetails(details->ToSmi());
+ DCHECK_LT(descriptor_number, number_of_descriptors());
+ int entry_offset = OffsetOfDescriptorAt(descriptor_number);
+ Smi details = EntryDetailsField::Relaxed_Load(*this, entry_offset);
+ return PropertyDetails(details);
+}
+
+void DescriptorArray::SetDetails(int descriptor_number,
+ PropertyDetails details) {
+ DCHECK_LT(descriptor_number, number_of_descriptors());
+ int entry_offset = OffsetOfDescriptorAt(descriptor_number);
+ EntryDetailsField::Relaxed_Store(*this, entry_offset, details.AsSmi());
}
int DescriptorArray::GetFieldIndex(int descriptor_number) {
@@ -164,19 +186,22 @@ int DescriptorArray::GetFieldIndex(int descriptor_number) {
}
FieldType DescriptorArray::GetFieldType(int descriptor_number) {
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return GetFieldType(isolate, descriptor_number);
+}
+
+FieldType DescriptorArray::GetFieldType(Isolate* isolate,
+ int descriptor_number) {
DCHECK_EQ(GetDetails(descriptor_number).location(), kField);
- MaybeObject wrapped_type = GetValue(descriptor_number);
+ MaybeObject wrapped_type = GetValue(isolate, descriptor_number);
return Map::UnwrapFieldType(wrapped_type);
}
void DescriptorArray::Set(int descriptor_number, Name key, MaybeObject value,
PropertyDetails details) {
- // Range check.
- DCHECK(descriptor_number < number_of_descriptors());
- set(ToKeyIndex(descriptor_number), MaybeObject::FromObject(key));
- set(ToValueIndex(descriptor_number), value);
- set(ToDetailsIndex(descriptor_number),
- MaybeObject::FromObject(details.AsSmi()));
+ SetKey(descriptor_number, key);
+ SetDetails(descriptor_number, details);
+ SetValue(descriptor_number, value);
}
void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
@@ -211,21 +236,6 @@ void DescriptorArray::SwapSortedKeys(int first, int second) {
SetSortedKey(second, first_key);
}
-int DescriptorArray::length() const {
- return number_of_all_descriptors() * kEntrySize;
-}
-
-MaybeObject DescriptorArray::get(int index) const {
- DCHECK(index >= 0 && index < this->length());
- return RELAXED_READ_WEAK_FIELD(*this, offset(index));
-}
-
-void DescriptorArray::set(int index, MaybeObject value) {
- DCHECK(index >= 0 && index < this->length());
- RELAXED_WRITE_WEAK_FIELD(*this, offset(index), value);
- WEAK_WRITE_BARRIER(*this, offset(index), value);
-}
-
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/descriptor-array.h b/deps/v8/src/objects/descriptor-array.h
index 3c1fa98a37..0f17cd22ea 100644
--- a/deps/v8/src/objects/descriptor-array.h
+++ b/deps/v8/src/objects/descriptor-array.h
@@ -22,21 +22,11 @@ class Handle;
class Isolate;
// An EnumCache is a pair used to hold keys and indices caches.
-class EnumCache : public Struct {
+class EnumCache : public TorqueGeneratedEnumCache<EnumCache, Struct> {
public:
- DECL_ACCESSORS(keys, FixedArray)
- DECL_ACCESSORS(indices, FixedArray)
-
- DECL_CAST(EnumCache)
-
- DECL_PRINTER(EnumCache)
DECL_VERIFIER(EnumCache)
- // Layout description.
- DEFINE_FIELD_OFFSET_CONSTANTS(Struct::kHeaderSize,
- TORQUE_GENERATED_ENUM_CACHE_FIELDS)
-
- OBJECT_CONSTRUCTORS(EnumCache, Struct);
+ TQ_OBJECT_CONSTRUCTORS(EnumCache)
};
// A DescriptorArray is a custom array that holds instance descriptors.
@@ -73,14 +63,18 @@ class DescriptorArray : public HeapObject {
// Accessors for fetching instance descriptor at descriptor number.
inline Name GetKey(int descriptor_number) const;
+ inline Name GetKey(Isolate* isolate, int descriptor_number) const;
inline Object GetStrongValue(int descriptor_number);
- inline void SetValue(int descriptor_number, Object value);
+ inline Object GetStrongValue(Isolate* isolate, int descriptor_number);
inline MaybeObject GetValue(int descriptor_number);
+ inline MaybeObject GetValue(Isolate* isolate, int descriptor_number);
inline PropertyDetails GetDetails(int descriptor_number);
inline int GetFieldIndex(int descriptor_number);
inline FieldType GetFieldType(int descriptor_number);
+ inline FieldType GetFieldType(Isolate* isolate, int descriptor_number);
inline Name GetSortedKey(int descriptor_number);
+ inline Name GetSortedKey(Isolate* isolate, int descriptor_number);
inline int GetSortedKeyIndex(int descriptor_number);
inline void SetSortedKey(int pointer, int descriptor_number);
@@ -153,15 +147,13 @@ class DescriptorArray : public HeapObject {
int16_t number_of_marked_descriptors);
static constexpr int SizeFor(int number_of_all_descriptors) {
- return offset(number_of_all_descriptors * kEntrySize);
+ return OffsetOfDescriptorAt(number_of_all_descriptors);
}
static constexpr int OffsetOfDescriptorAt(int descriptor) {
- return offset(descriptor * kEntrySize);
+ return kHeaderSize + descriptor * kEntrySize * kTaggedSize;
}
inline ObjectSlot GetFirstPointerSlot();
inline ObjectSlot GetDescriptorSlot(int descriptor);
- inline ObjectSlot GetKeySlot(int descriptor);
- inline MaybeObjectSlot GetValueSlot(int descriptor);
static_assert(kEndOfStrongFieldsOffset == kStartOfWeakFieldsOffset,
"Weak fields follow strong fields.");
@@ -178,6 +170,10 @@ class DescriptorArray : public HeapObject {
static const int kEntryValueIndex = 2;
static const int kEntrySize = 3;
+ static const int kEntryKeyOffset = kEntryKeyIndex * kTaggedSize;
+ static const int kEntryDetailsOffset = kEntryDetailsIndex * kTaggedSize;
+ static const int kEntryValueOffset = kEntryValueIndex * kTaggedSize;
+
// Print all the descriptors.
void PrintDescriptors(std::ostream& os);
void PrintDescriptorDetails(std::ostream& os, int descriptor,
@@ -207,15 +203,16 @@ class DescriptorArray : public HeapObject {
return (descriptor_number * kEntrySize) + kEntryValueIndex;
}
+ using EntryKeyField = TaggedField<HeapObject, kEntryKeyOffset>;
+ using EntryDetailsField = TaggedField<Smi, kEntryDetailsOffset>;
+ using EntryValueField = TaggedField<MaybeObject, kEntryValueOffset>;
+
private:
DECL_INT16_ACCESSORS(filler16bits)
- // Low-level per-element accessors.
- static constexpr int offset(int index) {
- return kHeaderSize + index * kTaggedSize;
- }
- inline int length() const;
- inline MaybeObject get(int index) const;
- inline void set(int index, MaybeObject value);
+
+ inline void SetKey(int descriptor_number, Name key);
+ inline void SetValue(int descriptor_number, MaybeObject value);
+ inline void SetDetails(int descriptor_number, PropertyDetails details);
// Transfer a complete descriptor from the src descriptor array to this
// descriptor array.
diff --git a/deps/v8/src/objects/dictionary-inl.h b/deps/v8/src/objects/dictionary-inl.h
index a1692978f3..92c1d0940f 100644
--- a/deps/v8/src/objects/dictionary-inl.h
+++ b/deps/v8/src/objects/dictionary-inl.h
@@ -98,15 +98,27 @@ RootIndex GlobalDictionaryShape::GetMapRootIndex() {
return RootIndex::kGlobalDictionaryMap;
}
-Name NameDictionary::NameAt(int entry) { return Name::cast(KeyAt(entry)); }
+Name NameDictionary::NameAt(int entry) {
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return NameAt(isolate, entry);
+}
+
+Name NameDictionary::NameAt(Isolate* isolate, int entry) {
+ return Name::cast(KeyAt(isolate, entry));
+}
RootIndex NameDictionaryShape::GetMapRootIndex() {
return RootIndex::kNameDictionaryMap;
}
PropertyCell GlobalDictionary::CellAt(int entry) {
- DCHECK(KeyAt(entry).IsPropertyCell());
- return PropertyCell::cast(KeyAt(entry));
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return CellAt(isolate, entry);
+}
+
+PropertyCell GlobalDictionary::CellAt(Isolate* isolate, int entry) {
+ DCHECK(KeyAt(isolate, entry).IsPropertyCell(isolate));
+ return PropertyCell::cast(KeyAt(isolate, entry));
}
bool GlobalDictionaryShape::IsLive(ReadOnlyRoots roots, Object k) {
@@ -118,8 +130,23 @@ bool GlobalDictionaryShape::IsKey(ReadOnlyRoots roots, Object k) {
return IsLive(roots, k) && !PropertyCell::cast(k).value().IsTheHole(roots);
}
-Name GlobalDictionary::NameAt(int entry) { return CellAt(entry).name(); }
-Object GlobalDictionary::ValueAt(int entry) { return CellAt(entry).value(); }
+Name GlobalDictionary::NameAt(int entry) {
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return NameAt(isolate, entry);
+}
+
+Name GlobalDictionary::NameAt(Isolate* isolate, int entry) {
+ return CellAt(isolate, entry).name(isolate);
+}
+
+Object GlobalDictionary::ValueAt(int entry) {
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return ValueAt(isolate, entry);
+}
+
+Object GlobalDictionary::ValueAt(Isolate* isolate, int entry) {
+ return CellAt(isolate, entry).value(isolate);
+}
void GlobalDictionary::SetEntry(Isolate* isolate, int entry, Object key,
Object value, PropertyDetails details) {
diff --git a/deps/v8/src/objects/dictionary.h b/deps/v8/src/objects/dictionary.h
index ca709f34d8..fe6001f58c 100644
--- a/deps/v8/src/objects/dictionary.h
+++ b/deps/v8/src/objects/dictionary.h
@@ -32,7 +32,11 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Dictionary
using Key = typename Shape::Key;
// Returns the value at entry.
Object ValueAt(int entry) {
- return this->get(DerivedHashTable::EntryToIndex(entry) + 1);
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return ValueAt(isolate, entry);
+ }
+ Object ValueAt(Isolate* isolate, int entry) {
+ return this->get(isolate, DerivedHashTable::EntryToIndex(entry) + 1);
}
// Set the value for entry.
@@ -208,6 +212,8 @@ class V8_EXPORT_PRIVATE NameDictionary
static const int kInitialCapacity = 2;
inline Name NameAt(int entry);
+ inline Name NameAt(Isolate* isolate, int entry);
+
inline void set_hash(int hash);
inline int hash() const;
@@ -246,10 +252,13 @@ class V8_EXPORT_PRIVATE GlobalDictionary
DECL_CAST(GlobalDictionary)
inline Object ValueAt(int entry);
+ inline Object ValueAt(Isolate* isolate, int entry);
inline PropertyCell CellAt(int entry);
+ inline PropertyCell CellAt(Isolate* isolate, int entry);
inline void SetEntry(Isolate* isolate, int entry, Object key, Object value,
PropertyDetails details);
inline Name NameAt(int entry);
+ inline Name NameAt(Isolate* isolate, int entry);
inline void ValueAtPut(int entry, Object value);
OBJECT_CONSTRUCTORS(
diff --git a/deps/v8/src/objects/elements.cc b/deps/v8/src/objects/elements.cc
index e1232a0d5b..4bdfba052d 100644
--- a/deps/v8/src/objects/elements.cc
+++ b/deps/v8/src/objects/elements.cc
@@ -4,10 +4,10 @@
#include "src/objects/elements.h"
+#include "src/common/message-template.h"
#include "src/execution/arguments.h"
#include "src/execution/frames.h"
#include "src/execution/isolate-inl.h"
-#include "src/execution/message-template.h"
#include "src/heap/factory.h"
#include "src/heap/heap-inl.h" // For MaxNumberToStringCacheSize.
#include "src/heap/heap-write-barrier-inl.h"
@@ -141,6 +141,12 @@ WriteBarrierMode GetWriteBarrierMode(ElementsKind kind) {
return UPDATE_WRITE_BARRIER;
}
+// If kCopyToEndAndInitializeToHole is specified as the copy_size to
+// CopyElements, it copies all of elements from source after source_start to
+// destination array, padding any remaining uninitialized elements in the
+// destination array with the hole.
+constexpr int kCopyToEndAndInitializeToHole = -1;
+
void CopyObjectToObjectElements(Isolate* isolate, FixedArrayBase from_base,
ElementsKind from_kind, uint32_t from_start,
FixedArrayBase to_base, ElementsKind to_kind,
@@ -150,17 +156,14 @@ void CopyObjectToObjectElements(Isolate* isolate, FixedArrayBase from_base,
DisallowHeapAllocation no_allocation;
int copy_size = raw_copy_size;
if (raw_copy_size < 0) {
- DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd ||
- raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+ DCHECK_EQ(kCopyToEndAndInitializeToHole, raw_copy_size);
copy_size =
Min(from_base.length() - from_start, to_base.length() - to_start);
- if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
- int start = to_start + copy_size;
- int length = to_base.length() - start;
- if (length > 0) {
- MemsetTagged(FixedArray::cast(to_base).RawFieldOfElementAt(start),
- roots.the_hole_value(), length);
- }
+ int start = to_start + copy_size;
+ int length = to_base.length() - start;
+ if (length > 0) {
+ MemsetTagged(FixedArray::cast(to_base).RawFieldOfElementAt(start),
+ roots.the_hole_value(), length);
}
}
DCHECK((copy_size + static_cast<int>(to_start)) <= to_base.length() &&
@@ -179,24 +182,21 @@ void CopyObjectToObjectElements(Isolate* isolate, FixedArrayBase from_base,
write_barrier_mode);
}
-static void CopyDictionaryToObjectElements(
- Isolate* isolate, FixedArrayBase from_base, uint32_t from_start,
- FixedArrayBase to_base, ElementsKind to_kind, uint32_t to_start,
- int raw_copy_size) {
+void CopyDictionaryToObjectElements(Isolate* isolate, FixedArrayBase from_base,
+ uint32_t from_start, FixedArrayBase to_base,
+ ElementsKind to_kind, uint32_t to_start,
+ int raw_copy_size) {
DisallowHeapAllocation no_allocation;
NumberDictionary from = NumberDictionary::cast(from_base);
int copy_size = raw_copy_size;
if (raw_copy_size < 0) {
- DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd ||
- raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+ DCHECK_EQ(kCopyToEndAndInitializeToHole, raw_copy_size);
copy_size = from.max_number_key() + 1 - from_start;
- if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
- int start = to_start + copy_size;
- int length = to_base.length() - start;
- if (length > 0) {
- MemsetTagged(FixedArray::cast(to_base).RawFieldOfElementAt(start),
- ReadOnlyRoots(isolate).the_hole_value(), length);
- }
+ int start = to_start + copy_size;
+ int length = to_base.length() - start;
+ if (length > 0) {
+ MemsetTagged(FixedArray::cast(to_base).RawFieldOfElementAt(start),
+ ReadOnlyRoots(isolate).the_hole_value(), length);
}
}
DCHECK(to_base != from_base);
@@ -223,28 +223,23 @@ static void CopyDictionaryToObjectElements(
// NOTE: this method violates the handlified function signature convention:
// raw pointer parameters in the function that allocates.
// See ElementsAccessorBase::CopyElements() for details.
-static void CopyDoubleToObjectElements(Isolate* isolate,
- FixedArrayBase from_base,
- uint32_t from_start,
- FixedArrayBase to_base,
- uint32_t to_start, int raw_copy_size) {
+void CopyDoubleToObjectElements(Isolate* isolate, FixedArrayBase from_base,
+ uint32_t from_start, FixedArrayBase to_base,
+ uint32_t to_start, int raw_copy_size) {
int copy_size = raw_copy_size;
if (raw_copy_size < 0) {
DisallowHeapAllocation no_allocation;
- DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd ||
- raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+ DCHECK_EQ(kCopyToEndAndInitializeToHole, raw_copy_size);
copy_size =
Min(from_base.length() - from_start, to_base.length() - to_start);
- if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
- // Also initialize the area that will be copied over since HeapNumber
- // allocation below can cause an incremental marking step, requiring all
- // existing heap objects to be propertly initialized.
- int start = to_start;
- int length = to_base.length() - start;
- if (length > 0) {
- MemsetTagged(FixedArray::cast(to_base).RawFieldOfElementAt(start),
- ReadOnlyRoots(isolate).the_hole_value(), length);
- }
+ // Also initialize the area that will be copied over since HeapNumber
+ // allocation below can cause an incremental marking step, requiring all
+ // existing heap objects to be propertly initialized.
+ int start = to_start;
+ int length = to_base.length() - start;
+ if (length > 0) {
+ MemsetTagged(FixedArray::cast(to_base).RawFieldOfElementAt(start),
+ ReadOnlyRoots(isolate).the_hole_value(), length);
}
}
@@ -272,21 +267,17 @@ static void CopyDoubleToObjectElements(Isolate* isolate,
}
}
-static void CopyDoubleToDoubleElements(FixedArrayBase from_base,
- uint32_t from_start,
- FixedArrayBase to_base,
- uint32_t to_start, int raw_copy_size) {
+void CopyDoubleToDoubleElements(FixedArrayBase from_base, uint32_t from_start,
+ FixedArrayBase to_base, uint32_t to_start,
+ int raw_copy_size) {
DisallowHeapAllocation no_allocation;
int copy_size = raw_copy_size;
if (raw_copy_size < 0) {
- DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd ||
- raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+ DCHECK_EQ(kCopyToEndAndInitializeToHole, raw_copy_size);
copy_size =
Min(from_base.length() - from_start, to_base.length() - to_start);
- if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
- for (int i = to_start + copy_size; i < to_base.length(); ++i) {
- FixedDoubleArray::cast(to_base).set_the_hole(i);
- }
+ for (int i = to_start + copy_size; i < to_base.length(); ++i) {
+ FixedDoubleArray::cast(to_base).set_the_hole(i);
}
}
DCHECK((copy_size + static_cast<int>(to_start)) <= to_base.length() &&
@@ -312,19 +303,16 @@ static void CopyDoubleToDoubleElements(FixedArrayBase from_base,
#endif
}
-static void CopySmiToDoubleElements(FixedArrayBase from_base,
- uint32_t from_start, FixedArrayBase to_base,
- uint32_t to_start, int raw_copy_size) {
+void CopySmiToDoubleElements(FixedArrayBase from_base, uint32_t from_start,
+ FixedArrayBase to_base, uint32_t to_start,
+ int raw_copy_size) {
DisallowHeapAllocation no_allocation;
int copy_size = raw_copy_size;
if (raw_copy_size < 0) {
- DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd ||
- raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+ DCHECK_EQ(kCopyToEndAndInitializeToHole, raw_copy_size);
copy_size = from_base.length() - from_start;
- if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
- for (int i = to_start + copy_size; i < to_base.length(); ++i) {
- FixedDoubleArray::cast(to_base).set_the_hole(i);
- }
+ for (int i = to_start + copy_size; i < to_base.length(); ++i) {
+ FixedDoubleArray::cast(to_base).set_the_hole(i);
}
}
DCHECK((copy_size + static_cast<int>(to_start)) <= to_base.length() &&
@@ -344,25 +332,19 @@ static void CopySmiToDoubleElements(FixedArrayBase from_base,
}
}
-static void CopyPackedSmiToDoubleElements(FixedArrayBase from_base,
- uint32_t from_start,
- FixedArrayBase to_base,
- uint32_t to_start, int packed_size,
- int raw_copy_size) {
+void CopyPackedSmiToDoubleElements(FixedArrayBase from_base,
+ uint32_t from_start, FixedArrayBase to_base,
+ uint32_t to_start, int packed_size,
+ int raw_copy_size) {
DisallowHeapAllocation no_allocation;
int copy_size = raw_copy_size;
uint32_t to_end;
if (raw_copy_size < 0) {
- DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd ||
- raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+ DCHECK_EQ(kCopyToEndAndInitializeToHole, raw_copy_size);
copy_size = packed_size - from_start;
- if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
- to_end = to_base.length();
- for (uint32_t i = to_start + copy_size; i < to_end; ++i) {
- FixedDoubleArray::cast(to_base).set_the_hole(i);
- }
- } else {
- to_end = to_start + static_cast<uint32_t>(copy_size);
+ to_end = to_base.length();
+ for (uint32_t i = to_start + copy_size; i < to_end; ++i) {
+ FixedDoubleArray::cast(to_base).set_the_hole(i);
}
} else {
to_end = to_start + static_cast<uint32_t>(copy_size);
@@ -382,20 +364,16 @@ static void CopyPackedSmiToDoubleElements(FixedArrayBase from_base,
}
}
-static void CopyObjectToDoubleElements(FixedArrayBase from_base,
- uint32_t from_start,
- FixedArrayBase to_base,
- uint32_t to_start, int raw_copy_size) {
+void CopyObjectToDoubleElements(FixedArrayBase from_base, uint32_t from_start,
+ FixedArrayBase to_base, uint32_t to_start,
+ int raw_copy_size) {
DisallowHeapAllocation no_allocation;
int copy_size = raw_copy_size;
if (raw_copy_size < 0) {
- DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd ||
- raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+ DCHECK_EQ(kCopyToEndAndInitializeToHole, raw_copy_size);
copy_size = from_base.length() - from_start;
- if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
- for (int i = to_start + copy_size; i < to_base.length(); ++i) {
- FixedDoubleArray::cast(to_base).set_the_hole(i);
- }
+ for (int i = to_start + copy_size; i < to_base.length(); ++i) {
+ FixedDoubleArray::cast(to_base).set_the_hole(i);
}
}
DCHECK((copy_size + static_cast<int>(to_start)) <= to_base.length() &&
@@ -415,20 +393,17 @@ static void CopyObjectToDoubleElements(FixedArrayBase from_base,
}
}
-static void CopyDictionaryToDoubleElements(
- Isolate* isolate, FixedArrayBase from_base, uint32_t from_start,
- FixedArrayBase to_base, uint32_t to_start, int raw_copy_size) {
+void CopyDictionaryToDoubleElements(Isolate* isolate, FixedArrayBase from_base,
+ uint32_t from_start, FixedArrayBase to_base,
+ uint32_t to_start, int raw_copy_size) {
DisallowHeapAllocation no_allocation;
NumberDictionary from = NumberDictionary::cast(from_base);
int copy_size = raw_copy_size;
if (copy_size < 0) {
- DCHECK(copy_size == ElementsAccessor::kCopyToEnd ||
- copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+ DCHECK_EQ(kCopyToEndAndInitializeToHole, copy_size);
copy_size = from.max_number_key() + 1 - from_start;
- if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
- for (int i = to_start + copy_size; i < to_base.length(); ++i) {
- FixedDoubleArray::cast(to_base).set_the_hole(i);
- }
+ for (int i = to_start + copy_size; i < to_base.length(); ++i) {
+ FixedDoubleArray::cast(to_base).set_the_hole(i);
}
}
if (copy_size == 0) return;
@@ -447,17 +422,16 @@ static void CopyDictionaryToDoubleElements(
}
}
-static void SortIndices(Isolate* isolate, Handle<FixedArray> indices,
- uint32_t sort_size) {
+void SortIndices(Isolate* isolate, Handle<FixedArray> indices,
+ uint32_t sort_size) {
// Use AtomicSlot wrapper to ensure that std::sort uses atomic load and
// store operations that are safe for concurrent marking.
AtomicSlot start(indices->GetFirstElementAddress());
AtomicSlot end(start + sort_size);
std::sort(start, end, [isolate](Tagged_t elementA, Tagged_t elementB) {
#ifdef V8_COMPRESS_POINTERS
- DEFINE_ROOT_VALUE(isolate);
- Object a(DecompressTaggedAny(ROOT_VALUE, elementA));
- Object b(DecompressTaggedAny(ROOT_VALUE, elementB));
+ Object a(DecompressTaggedAny(isolate, elementA));
+ Object b(DecompressTaggedAny(isolate, elementB));
#else
Object a(elementA);
Object b(elementB);
@@ -474,10 +448,9 @@ static void SortIndices(Isolate* isolate, Handle<FixedArray> indices,
ObjectSlot(end));
}
-static Maybe<bool> IncludesValueSlowPath(Isolate* isolate,
- Handle<JSObject> receiver,
- Handle<Object> value,
- uint32_t start_from, uint32_t length) {
+Maybe<bool> IncludesValueSlowPath(Isolate* isolate, Handle<JSObject> receiver,
+ Handle<Object> value, uint32_t start_from,
+ uint32_t length) {
bool search_for_hole = value->IsUndefined(isolate);
for (uint32_t k = start_from; k < length; ++k) {
LookupIterator it(isolate, receiver, k);
@@ -495,11 +468,9 @@ static Maybe<bool> IncludesValueSlowPath(Isolate* isolate,
return Just(false);
}
-static Maybe<int64_t> IndexOfValueSlowPath(Isolate* isolate,
- Handle<JSObject> receiver,
- Handle<Object> value,
- uint32_t start_from,
- uint32_t length) {
+Maybe<int64_t> IndexOfValueSlowPath(Isolate* isolate, Handle<JSObject> receiver,
+ Handle<Object> value, uint32_t start_from,
+ uint32_t length) {
for (uint32_t k = start_from; k < length; ++k) {
LookupIterator it(isolate, receiver, k);
if (!it.IsFound()) {
@@ -595,23 +566,6 @@ class ElementsAccessorBase : public InternalElementsAccessor {
return true;
}
- static void TryTransitionResultArrayToPacked(Handle<JSArray> array) {
- if (!IsHoleyElementsKind(kind())) return;
- Handle<FixedArrayBase> backing_store(array->elements(),
- array->GetIsolate());
- int length = Smi::ToInt(array->length());
- if (!Subclass::IsPackedImpl(*array, *backing_store, 0, length)) return;
-
- ElementsKind packed_kind = GetPackedElementsKind(kind());
- Handle<Map> new_map =
- JSObject::GetElementsTransitionMap(array, packed_kind);
- JSObject::MigrateToMap(array, new_map);
- if (FLAG_trace_elements_transitions) {
- JSObject::PrintElementsTransition(stdout, array, kind(), backing_store,
- packed_kind, backing_store);
- }
- }
-
bool HasElement(JSObject holder, uint32_t index, FixedArrayBase backing_store,
PropertyFilter filter) final {
return Subclass::HasElementImpl(holder.GetIsolate(), holder, index,
@@ -804,22 +758,14 @@ class ElementsAccessorBase : public InternalElementsAccessor {
static Handle<FixedArrayBase> ConvertElementsWithCapacity(
Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
ElementsKind from_kind, uint32_t capacity) {
- return ConvertElementsWithCapacity(
- object, old_elements, from_kind, capacity, 0, 0,
- ElementsAccessor::kCopyToEndAndInitializeToHole);
- }
-
- static Handle<FixedArrayBase> ConvertElementsWithCapacity(
- Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
- ElementsKind from_kind, uint32_t capacity, int copy_size) {
return ConvertElementsWithCapacity(object, old_elements, from_kind,
- capacity, 0, 0, copy_size);
+ capacity, 0, 0);
}
static Handle<FixedArrayBase> ConvertElementsWithCapacity(
Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
ElementsKind from_kind, uint32_t capacity, uint32_t src_index,
- uint32_t dst_index, int copy_size) {
+ uint32_t dst_index) {
Isolate* isolate = object->GetIsolate();
Handle<FixedArrayBase> new_elements;
if (IsDoubleElementsKind(kind())) {
@@ -834,14 +780,16 @@ class ElementsAccessorBase : public InternalElementsAccessor {
}
Subclass::CopyElementsImpl(isolate, *old_elements, src_index, *new_elements,
- from_kind, dst_index, packed_size, copy_size);
+ from_kind, dst_index, packed_size,
+ kCopyToEndAndInitializeToHole);
return new_elements;
}
static void TransitionElementsKindImpl(Handle<JSObject> object,
Handle<Map> to_map) {
- Handle<Map> from_map = handle(object->map(), object->GetIsolate());
+ Isolate* isolate = object->GetIsolate();
+ Handle<Map> from_map = handle(object->map(), isolate);
ElementsKind from_kind = from_map->elements_kind();
ElementsKind to_kind = to_map->elements_kind();
if (IsHoleyElementsKind(from_kind)) {
@@ -853,14 +801,12 @@ class ElementsAccessorBase : public InternalElementsAccessor {
DCHECK(IsFastElementsKind(to_kind));
DCHECK_NE(TERMINAL_FAST_ELEMENTS_KIND, from_kind);
- Handle<FixedArrayBase> from_elements(object->elements(),
- object->GetIsolate());
- if (object->elements() ==
- object->GetReadOnlyRoots().empty_fixed_array() ||
+ Handle<FixedArrayBase> from_elements(object->elements(), isolate);
+ if (object->elements() == ReadOnlyRoots(isolate).empty_fixed_array() ||
IsDoubleElementsKind(from_kind) == IsDoubleElementsKind(to_kind)) {
// No change is needed to the elements() buffer, the transition
// only requires a map change.
- JSObject::MigrateToMap(object, to_map);
+ JSObject::MigrateToMap(isolate, object, to_map);
} else {
DCHECK(
(IsSmiElementsKind(from_kind) && IsDoubleElementsKind(to_kind)) ||
@@ -871,9 +817,9 @@ class ElementsAccessorBase : public InternalElementsAccessor {
JSObject::SetMapAndElements(object, to_map, elements);
}
if (FLAG_trace_elements_transitions) {
- JSObject::PrintElementsTransition(
- stdout, object, from_kind, from_elements, to_kind,
- handle(object->elements(), object->GetIsolate()));
+ JSObject::PrintElementsTransition(stdout, object, from_kind,
+ from_elements, to_kind,
+ handle(object->elements(), isolate));
}
}
}
@@ -2394,7 +2340,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
// Copy over all objects to a new backing_store.
backing_store = Subclass::ConvertElementsWithCapacity(
receiver, backing_store, KindTraits::Kind, capacity, 0,
- copy_dst_index, ElementsAccessor::kCopyToEndAndInitializeToHole);
+ copy_dst_index);
receiver->set_elements(*backing_store);
} else if (add_position == AT_START) {
// If the backing store has enough capacity and we add elements to the
@@ -2639,7 +2585,7 @@ class FastSealedObjectElementsAccessor
"SlowCopyForSetLengthImpl");
new_map->set_is_extensible(false);
new_map->set_elements_kind(DICTIONARY_ELEMENTS);
- JSObject::MigrateToMap(array, new_map);
+ JSObject::MigrateToMap(isolate, array, new_map);
if (!new_element_dictionary.is_null()) {
array->set_elements(*new_element_dictionary);
@@ -2955,7 +2901,7 @@ class TypedElementsAccessor
// fields (external pointers, doubles and BigInt data) are only
// kTaggedSize aligned so we have to use unaligned pointer friendly way of
// accessing them in order to avoid undefined behavior in C++ code.
- WriteUnalignedValue<ElementType>(
+ base::WriteUnalignedValue<ElementType>(
reinterpret_cast<Address>(data_ptr + entry), value);
} else {
data_ptr[entry] = value;
@@ -2995,7 +2941,7 @@ class TypedElementsAccessor
// fields (external pointers, doubles and BigInt data) are only
// kTaggedSize aligned so we have to use unaligned pointer friendly way of
// accessing them in order to avoid undefined behavior in C++ code.
- result = ReadUnalignedValue<ElementType>(
+ result = base::ReadUnalignedValue<ElementType>(
reinterpret_cast<Address>(data_ptr + entry));
} else {
result = data_ptr[entry];
@@ -3664,10 +3610,7 @@ Handle<Object> TypedElementsAccessor<UINT32_ELEMENTS, uint32_t>::ToHandle(
// static
template <>
float TypedElementsAccessor<FLOAT32_ELEMENTS, float>::FromScalar(double value) {
- using limits = std::numeric_limits<float>;
- if (value > limits::max()) return limits::infinity();
- if (value < limits::lowest()) return -limits::infinity();
- return static_cast<float>(value);
+ return DoubleToFloat32(value);
}
// static
@@ -4377,7 +4320,7 @@ class FastSloppyArgumentsElementsAccessor
ConvertElementsWithCapacity(object, old_arguments, from_kind, capacity);
Handle<Map> new_map = JSObject::GetElementsTransitionMap(
object, FAST_SLOPPY_ARGUMENTS_ELEMENTS);
- JSObject::MigrateToMap(object, new_map);
+ JSObject::MigrateToMap(isolate, object, new_map);
elements->set_arguments(FixedArray::cast(*arguments));
JSObject::ValidateElements(*object);
}
@@ -4549,8 +4492,8 @@ class StringWrapperElementsAccessor
private:
static String GetString(JSObject holder) {
- DCHECK(holder.IsJSValue());
- JSValue js_value = JSValue::cast(holder);
+ DCHECK(holder.IsJSPrimitiveWrapper());
+ JSPrimitiveWrapper js_value = JSPrimitiveWrapper::cast(holder);
DCHECK(js_value.value().IsString());
return String::cast(js_value.value());
}
diff --git a/deps/v8/src/objects/elements.h b/deps/v8/src/objects/elements.h
index 844cd2ed94..a72a6b068e 100644
--- a/deps/v8/src/objects/elements.h
+++ b/deps/v8/src/objects/elements.h
@@ -66,15 +66,6 @@ class ElementsAccessor {
// element that is non-deletable.
virtual void SetLength(Handle<JSArray> holder, uint32_t new_length) = 0;
- // If kCopyToEnd is specified as the copy_size to CopyElements, it copies all
- // of elements from source after source_start to the destination array.
- static const int kCopyToEnd = -1;
- // If kCopyToEndAndInitializeToHole is specified as the copy_size to
- // CopyElements, it copies all of elements from source after source_start to
- // destination array, padding any remaining uninitialized elements in the
- // destination array with the hole.
- static const int kCopyToEndAndInitializeToHole = -2;
-
// Copy all indices that have elements from |object| into the given
// KeyAccumulator. For Dictionary-based element-kinds we filter out elements
// whose PropertyAttribute match |filter|.
@@ -210,7 +201,7 @@ class ElementsAccessor {
uint32_t destination_start, int copy_size) = 0;
private:
- static ElementsAccessor** elements_accessors_;
+ V8_EXPORT_PRIVATE static ElementsAccessor** elements_accessors_;
DISALLOW_COPY_AND_ASSIGN(ElementsAccessor);
};
diff --git a/deps/v8/src/objects/embedder-data-slot-inl.h b/deps/v8/src/objects/embedder-data-slot-inl.h
index 6830a4d22e..78189ba381 100644
--- a/deps/v8/src/objects/embedder-data-slot-inl.h
+++ b/deps/v8/src/objects/embedder-data-slot-inl.h
@@ -7,7 +7,7 @@
#include "src/objects/embedder-data-slot.h"
-#include "src/common/v8memory.h"
+#include "src/base/memory.h"
#include "src/heap/heap-write-barrier-inl.h"
#include "src/objects/embedder-data-array.h"
#include "src/objects/js-objects-inl.h"
@@ -77,7 +77,7 @@ bool EmbedderDataSlot::ToAlignedPointer(void** out_pointer) const {
// fields (external pointers, doubles and BigInt data) are only kTaggedSize
// aligned so we have to use unaligned pointer friendly way of accessing them
// in order to avoid undefined behavior in C++ code.
- Address raw_value = ReadUnalignedValue<Address>(address());
+ Address raw_value = base::ReadUnalignedValue<Address>(address());
#else
Address raw_value = *location();
#endif
@@ -103,7 +103,7 @@ EmbedderDataSlot::RawData EmbedderDataSlot::load_raw(
// fields (external pointers, doubles and BigInt data) are only kTaggedSize
// aligned so we have to use unaligned pointer friendly way of accessing them
// in order to avoid undefined behavior in C++ code.
- return ReadUnalignedValue<Address>(address());
+ return base::ReadUnalignedValue<Address>(address());
#else
return *location();
#endif
diff --git a/deps/v8/src/objects/feedback-vector-inl.h b/deps/v8/src/objects/feedback-vector-inl.h
index 6b1fdcc1e5..9cdc03b5c2 100644
--- a/deps/v8/src/objects/feedback-vector-inl.h
+++ b/deps/v8/src/objects/feedback-vector-inl.h
@@ -155,13 +155,22 @@ FeedbackSlot FeedbackVector::ToSlot(int index) {
}
MaybeObject FeedbackVector::Get(FeedbackSlot slot) const {
- return get(GetIndex(slot));
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return Get(isolate, slot);
+}
+
+MaybeObject FeedbackVector::Get(Isolate* isolate, FeedbackSlot slot) const {
+ return get(isolate, GetIndex(slot));
}
MaybeObject FeedbackVector::get(int index) const {
- DCHECK_GE(index, 0);
- DCHECK_LT(index, this->length());
- int offset = kFeedbackSlotsOffset + index * kTaggedSize;
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return get(isolate, index);
+}
+
+MaybeObject FeedbackVector::get(Isolate* isolate, int index) const {
+ DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
+ int offset = OffsetOfElementAt(index);
return RELAXED_READ_WEAK_FIELD(*this, offset);
}
@@ -180,7 +189,7 @@ void FeedbackVector::Set(FeedbackSlot slot, MaybeObject value,
void FeedbackVector::set(int index, MaybeObject value, WriteBarrierMode mode) {
DCHECK_GE(index, 0);
DCHECK_LT(index, this->length());
- int offset = kFeedbackSlotsOffset + index * kTaggedSize;
+ int offset = OffsetOfElementAt(index);
RELAXED_WRITE_WEAK_FIELD(*this, offset, value);
CONDITIONAL_WEAK_WRITE_BARRIER(*this, offset, value, mode);
}
diff --git a/deps/v8/src/objects/feedback-vector.cc b/deps/v8/src/objects/feedback-vector.cc
index 0393a55f69..4f4826eab3 100644
--- a/deps/v8/src/objects/feedback-vector.cc
+++ b/deps/v8/src/objects/feedback-vector.cc
@@ -374,6 +374,7 @@ void FeedbackVector::EvictOptimizedCodeMarkedForDeoptimization(
}
bool FeedbackVector::ClearSlots(Isolate* isolate) {
+ if (!shared_function_info().HasFeedbackMetadata()) return false;
MaybeObject uninitialized_sentinel = MaybeObject::FromObject(
FeedbackVector::RawUninitializedSentinel(isolate));
@@ -943,6 +944,7 @@ int FeedbackNexus::ExtractMaps(MapHandles* maps) const {
IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
IsStoreInArrayLiteralICKind(kind()) || IsKeyedHasICKind(kind()));
+ DisallowHeapAllocation no_gc;
Isolate* isolate = GetIsolate();
MaybeObject feedback = GetFeedback();
bool is_named_feedback = IsPropertyNameFeedback(feedback);
@@ -986,19 +988,22 @@ int FeedbackNexus::ExtractMaps(MapHandles* maps) const {
return 0;
}
-MaybeObjectHandle FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
+int FeedbackNexus::ExtractMapsAndHandlers(MapHandles* maps,
+ MaybeObjectHandles* handlers) const {
DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
- IsKeyedHasICKind(kind()));
+ IsStoreInArrayLiteralICKind(kind()) || IsKeyedHasICKind(kind()));
- MaybeObject feedback = GetFeedback();
+ DisallowHeapAllocation no_gc;
Isolate* isolate = GetIsolate();
+ MaybeObject feedback = GetFeedback();
bool is_named_feedback = IsPropertyNameFeedback(feedback);
HeapObject heap_object;
if ((feedback->GetHeapObjectIfStrong(&heap_object) &&
heap_object.IsWeakFixedArray()) ||
is_named_feedback) {
+ int found = 0;
WeakFixedArray array;
if (is_named_feedback) {
array =
@@ -1011,36 +1016,39 @@ MaybeObjectHandle FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
for (int i = 0; i < array.length(); i += increment) {
DCHECK(array.Get(i)->IsWeakOrCleared());
if (array.Get(i)->GetHeapObjectIfWeak(&heap_object)) {
- Map array_map = Map::cast(heap_object);
- if (array_map == *map && !array.Get(i + increment - 1)->IsCleared()) {
- MaybeObject handler = array.Get(i + increment - 1);
+ MaybeObject handler = array.Get(i + 1);
+ if (!handler->IsCleared()) {
DCHECK(IC::IsHandler(handler));
- return handle(handler, isolate);
+ Map map = Map::cast(heap_object);
+ maps->push_back(handle(map, isolate));
+ handlers->push_back(handle(handler, isolate));
+ found++;
}
}
}
+ return found;
} else if (feedback->GetHeapObjectIfWeak(&heap_object)) {
- Map cell_map = Map::cast(heap_object);
- if (cell_map == *map && !GetFeedbackExtra()->IsCleared()) {
- MaybeObject handler = GetFeedbackExtra();
+ MaybeObject handler = GetFeedbackExtra();
+ if (!handler->IsCleared()) {
DCHECK(IC::IsHandler(handler));
- return handle(handler, isolate);
+ Map map = Map::cast(heap_object);
+ maps->push_back(handle(map, isolate));
+ handlers->push_back(handle(handler, isolate));
+ return 1;
}
}
- return MaybeObjectHandle();
+ return 0;
}
-bool FeedbackNexus::FindHandlers(MaybeObjectHandles* code_list,
- int length) const {
+MaybeObjectHandle FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
- IsStoreInArrayLiteralICKind(kind()) || IsKeyedHasICKind(kind()));
+ IsKeyedHasICKind(kind()));
MaybeObject feedback = GetFeedback();
Isolate* isolate = GetIsolate();
- int count = 0;
bool is_named_feedback = IsPropertyNameFeedback(feedback);
HeapObject heap_object;
if ((feedback->GetHeapObjectIfStrong(&heap_object) &&
@@ -1056,25 +1064,26 @@ bool FeedbackNexus::FindHandlers(MaybeObjectHandles* code_list,
const int increment = 2;
HeapObject heap_object;
for (int i = 0; i < array.length(); i += increment) {
- // Be sure to skip handlers whose maps have been cleared.
DCHECK(array.Get(i)->IsWeakOrCleared());
- if (array.Get(i)->GetHeapObjectIfWeak(&heap_object) &&
- !array.Get(i + increment - 1)->IsCleared()) {
- MaybeObject handler = array.Get(i + increment - 1);
- DCHECK(IC::IsHandler(handler));
- code_list->push_back(handle(handler, isolate));
- count++;
+ if (array.Get(i)->GetHeapObjectIfWeak(&heap_object)) {
+ Map array_map = Map::cast(heap_object);
+ if (array_map == *map && !array.Get(i + increment - 1)->IsCleared()) {
+ MaybeObject handler = array.Get(i + increment - 1);
+ DCHECK(IC::IsHandler(handler));
+ return handle(handler, isolate);
+ }
}
}
} else if (feedback->GetHeapObjectIfWeak(&heap_object)) {
- MaybeObject extra = GetFeedbackExtra();
- if (!extra->IsCleared()) {
- DCHECK(IC::IsHandler(extra));
- code_list->push_back(handle(extra, isolate));
- count++;
+ Map cell_map = Map::cast(heap_object);
+ if (cell_map == *map && !GetFeedbackExtra()->IsCleared()) {
+ MaybeObject handler = GetFeedbackExtra();
+ DCHECK(IC::IsHandler(handler));
+ return handle(handler, isolate);
}
}
- return count == length;
+
+ return MaybeObjectHandle();
}
Name FeedbackNexus::GetName() const {
@@ -1095,8 +1104,7 @@ KeyedAccessLoadMode FeedbackNexus::GetKeyedAccessLoadMode() const {
if (GetKeyType() == PROPERTY) return STANDARD_LOAD;
- ExtractMaps(&maps);
- FindHandlers(&handlers, static_cast<int>(maps.size()));
+ ExtractMapsAndHandlers(&maps, &handlers);
for (MaybeObjectHandle const& handler : handlers) {
KeyedAccessLoadMode mode = LoadHandler::GetKeyedAccessLoadMode(*handler);
if (mode != STANDARD_LOAD) return mode;
@@ -1179,8 +1187,7 @@ KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const {
if (GetKeyType() == PROPERTY) return mode;
- ExtractMaps(&maps);
- FindHandlers(&handlers, static_cast<int>(maps.size()));
+ ExtractMapsAndHandlers(&maps, &handlers);
for (const MaybeObjectHandle& maybe_code_handler : handlers) {
// The first handler that isn't the slow handler will have the bits we need.
Handle<Code> handler;
diff --git a/deps/v8/src/objects/feedback-vector.h b/deps/v8/src/objects/feedback-vector.h
index 89e0b9e6aa..af03bb4130 100644
--- a/deps/v8/src/objects/feedback-vector.h
+++ b/deps/v8/src/objects/feedback-vector.h
@@ -233,7 +233,9 @@ class FeedbackVector : public HeapObject {
// Conversion from an integer index to the underlying array to a slot.
static inline FeedbackSlot ToSlot(int index);
inline MaybeObject Get(FeedbackSlot slot) const;
+ inline MaybeObject Get(Isolate* isolate, FeedbackSlot slot) const;
inline MaybeObject get(int index) const;
+ inline MaybeObject get(Isolate* isolate, int index) const;
inline void Set(FeedbackSlot slot, MaybeObject value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline void set(int index, MaybeObject value,
@@ -322,11 +324,13 @@ class FeedbackVector : public HeapObject {
class BodyDescriptor;
- // Garbage collection support.
- static constexpr int SizeFor(int length) {
- return kFeedbackSlotsOffset + length * kTaggedSize;
+ static constexpr int OffsetOfElementAt(int index) {
+ return kFeedbackSlotsOffset + index * kTaggedSize;
}
+ // Garbage collection support.
+ static constexpr int SizeFor(int length) { return OffsetOfElementAt(length); }
+
private:
static void AddToVectorsForProfilingTools(Isolate* isolate,
Handle<FeedbackVector> vector);
@@ -561,6 +565,7 @@ class FeedbackMetadata : public HeapObject {
// Verify that an empty hash field looks like a tagged object, but can't
// possibly be confused with a pointer.
+// NOLINTNEXTLINE(runtime/references) (false positive)
STATIC_ASSERT((Name::kEmptyHashField & kHeapObjectTag) == kHeapObjectTag);
STATIC_ASSERT(Name::kEmptyHashField == 0x3);
// Verify that a set hash field will not look like a tagged object.
@@ -646,8 +651,9 @@ class V8_EXPORT_PRIVATE FeedbackNexus final {
Map GetFirstMap() const;
int ExtractMaps(MapHandles* maps) const;
+ int ExtractMapsAndHandlers(MapHandles* maps,
+ MaybeObjectHandles* handlers) const;
MaybeObjectHandle FindHandlerForMap(Handle<Map> map) const;
- bool FindHandlers(MaybeObjectHandles* code_list, int length = -1) const;
bool IsCleared() const {
InlineCacheState state = ic_state();
diff --git a/deps/v8/src/objects/field-index-inl.h b/deps/v8/src/objects/field-index-inl.h
index be60fb54a2..997cd68c32 100644
--- a/deps/v8/src/objects/field-index-inl.h
+++ b/deps/v8/src/objects/field-index-inl.h
@@ -19,7 +19,7 @@ FieldIndex FieldIndex::ForInObjectOffset(int offset, Encoding encoding) {
return FieldIndex(true, offset, encoding, 0, 0);
}
-FieldIndex FieldIndex::ForPropertyIndex(const Map map, int property_index,
+FieldIndex FieldIndex::ForPropertyIndex(Map map, int property_index,
Representation representation) {
DCHECK(map.instance_type() >= FIRST_NONSTRING_TYPE);
int inobject_properties = map.GetInObjectProperties();
@@ -60,9 +60,15 @@ int FieldIndex::GetLoadByFieldIndex() const {
return is_double() ? (result | 1) : result;
}
-FieldIndex FieldIndex::ForDescriptor(const Map map, int descriptor_index) {
+FieldIndex FieldIndex::ForDescriptor(Map map, int descriptor_index) {
+ Isolate* isolate = GetIsolateForPtrCompr(map);
+ return ForDescriptor(isolate, map, descriptor_index);
+}
+
+FieldIndex FieldIndex::ForDescriptor(Isolate* isolate, Map map,
+ int descriptor_index) {
PropertyDetails details =
- map.instance_descriptors().GetDetails(descriptor_index);
+ map.instance_descriptors(isolate).GetDetails(descriptor_index);
int field_index = details.field_index();
return ForPropertyIndex(map, field_index, details.representation());
}
diff --git a/deps/v8/src/objects/field-index.h b/deps/v8/src/objects/field-index.h
index f352ef6800..a6657634c8 100644
--- a/deps/v8/src/objects/field-index.h
+++ b/deps/v8/src/objects/field-index.h
@@ -24,10 +24,12 @@ class FieldIndex final {
FieldIndex() : bit_field_(0) {}
static inline FieldIndex ForPropertyIndex(
- const Map map, int index,
+ Map map, int index,
Representation representation = Representation::Tagged());
static inline FieldIndex ForInObjectOffset(int offset, Encoding encoding);
- static inline FieldIndex ForDescriptor(const Map map, int descriptor_index);
+ static inline FieldIndex ForDescriptor(Map map, int descriptor_index);
+ static inline FieldIndex ForDescriptor(Isolate* isolate, Map map,
+ int descriptor_index);
inline int GetLoadByFieldIndex() const;
diff --git a/deps/v8/src/objects/fixed-array-inl.h b/deps/v8/src/objects/fixed-array-inl.h
index 6d2b42edbf..79c29a6eeb 100644
--- a/deps/v8/src/objects/fixed-array-inl.h
+++ b/deps/v8/src/objects/fixed-array-inl.h
@@ -90,51 +90,57 @@ bool FixedArray::ContainsOnlySmisOrHoles() {
}
Object FixedArray::get(int index) const {
- DCHECK(index >= 0 && index < this->length());
- return RELAXED_READ_FIELD(*this, kHeaderSize + index * kTaggedSize);
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return get(isolate, index);
+}
+
+Object FixedArray::get(Isolate* isolate, int index) const {
+ DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
+ return TaggedField<Object>::Relaxed_Load(isolate, *this,
+ OffsetOfElementAt(index));
}
Handle<Object> FixedArray::get(FixedArray array, int index, Isolate* isolate) {
- return handle(array.get(index), isolate);
+ return handle(array.get(isolate, index), isolate);
}
bool FixedArray::is_the_hole(Isolate* isolate, int index) {
- return get(index).IsTheHole(isolate);
+ return get(isolate, index).IsTheHole(isolate);
}
void FixedArray::set(int index, Smi value) {
DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map());
- DCHECK_LT(index, this->length());
+ DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
DCHECK(Object(value).IsSmi());
- int offset = kHeaderSize + index * kTaggedSize;
+ int offset = OffsetOfElementAt(index);
RELAXED_WRITE_FIELD(*this, offset, value);
}
void FixedArray::set(int index, Object value) {
DCHECK_NE(GetReadOnlyRoots().fixed_cow_array_map(), map());
DCHECK(IsFixedArray());
- DCHECK_GE(index, 0);
- DCHECK_LT(index, this->length());
- int offset = kHeaderSize + index * kTaggedSize;
+ DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
+ int offset = OffsetOfElementAt(index);
RELAXED_WRITE_FIELD(*this, offset, value);
WRITE_BARRIER(*this, offset, value);
}
void FixedArray::set(int index, Object value, WriteBarrierMode mode) {
DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map());
- DCHECK_GE(index, 0);
- DCHECK_LT(index, this->length());
- int offset = kHeaderSize + index * kTaggedSize;
+ DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
+ int offset = OffsetOfElementAt(index);
RELAXED_WRITE_FIELD(*this, offset, value);
CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode);
}
+// static
void FixedArray::NoWriteBarrierSet(FixedArray array, int index, Object value) {
DCHECK_NE(array.map(), array.GetReadOnlyRoots().fixed_cow_array_map());
- DCHECK_GE(index, 0);
- DCHECK_LT(index, array.length());
+ DCHECK_LT(static_cast<unsigned>(index),
+ static_cast<unsigned>(array.length()));
DCHECK(!ObjectInYoungGeneration(value));
- RELAXED_WRITE_FIELD(array, kHeaderSize + index * kTaggedSize, value);
+ int offset = OffsetOfElementAt(index);
+ RELAXED_WRITE_FIELD(array, offset, value);
}
void FixedArray::set_undefined(int index) {
@@ -323,7 +329,7 @@ uint64_t FixedDoubleArray::get_representation(int index) {
DCHECK(index >= 0 && index < this->length());
int offset = kHeaderSize + index * kDoubleSize;
// Bug(v8:8875): Doubles may be unaligned.
- return ReadUnalignedValue<uint64_t>(field_address(offset));
+ return base::ReadUnalignedValue<uint64_t>(field_address(offset));
}
Handle<Object> FixedDoubleArray::get(FixedDoubleArray array, int index,
@@ -355,7 +361,7 @@ void FixedDoubleArray::set_the_hole(int index) {
DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() &&
map() != GetReadOnlyRoots().fixed_array_map());
int offset = kHeaderSize + index * kDoubleSize;
- WriteUnalignedValue<uint64_t>(field_address(offset), kHoleNanInt64);
+ base::WriteUnalignedValue<uint64_t>(field_address(offset), kHoleNanInt64);
}
bool FixedDoubleArray::is_the_hole(Isolate* isolate, int index) {
@@ -382,8 +388,14 @@ void FixedDoubleArray::FillWithHoles(int from, int to) {
}
MaybeObject WeakFixedArray::Get(int index) const {
- DCHECK(index >= 0 && index < this->length());
- return RELAXED_READ_WEAK_FIELD(*this, OffsetOfElementAt(index));
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return Get(isolate, index);
+}
+
+MaybeObject WeakFixedArray::Get(Isolate* isolate, int index) const {
+ DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
+ return TaggedField<MaybeObject>::Relaxed_Load(isolate, *this,
+ OffsetOfElementAt(index));
}
void WeakFixedArray::Set(int index, MaybeObject value) {
@@ -424,8 +436,14 @@ void WeakFixedArray::CopyElements(Isolate* isolate, int dst_index,
}
MaybeObject WeakArrayList::Get(int index) const {
- DCHECK(index >= 0 && index < this->capacity());
- return RELAXED_READ_WEAK_FIELD(*this, OffsetOfElementAt(index));
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return Get(isolate, index);
+}
+
+MaybeObject WeakArrayList::Get(Isolate* isolate, int index) const {
+ DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(capacity()));
+ return TaggedField<MaybeObject>::Relaxed_Load(isolate, *this,
+ OffsetOfElementAt(index));
}
void WeakArrayList::Set(int index, MaybeObject value, WriteBarrierMode mode) {
@@ -478,6 +496,10 @@ Object ArrayList::Get(int index) const {
return FixedArray::cast(*this).get(kFirstIndex + index);
}
+Object ArrayList::Get(Isolate* isolate, int index) const {
+ return FixedArray::cast(*this).get(isolate, kFirstIndex + index);
+}
+
ObjectSlot ArrayList::Slot(int index) {
return RawField(OffsetOfElementAt(kFirstIndex + index));
}
@@ -538,6 +560,16 @@ void ByteArray::set_uint32(int index, uint32_t value) {
WriteField<uint32_t>(kHeaderSize + index * kUInt32Size, value);
}
+uint32_t ByteArray::get_uint32_relaxed(int index) const {
+ DCHECK(index >= 0 && index < this->length() / kUInt32Size);
+ return RELAXED_READ_UINT32_FIELD(*this, kHeaderSize + index * kUInt32Size);
+}
+
+void ByteArray::set_uint32_relaxed(int index, uint32_t value) {
+ DCHECK(index >= 0 && index < this->length() / kUInt32Size);
+ RELAXED_WRITE_UINT32_FIELD(*this, kHeaderSize + index * kUInt32Size, value);
+}
+
void ByteArray::clear_padding() {
int data_size = length() + kHeaderSize;
memset(reinterpret_cast<void*>(address() + data_size), 0, Size() - data_size);
@@ -589,6 +621,10 @@ Object TemplateList::get(int index) const {
return FixedArray::cast(*this).get(kFirstElementIndex + index);
}
+Object TemplateList::get(Isolate* isolate, int index) const {
+ return FixedArray::cast(*this).get(isolate, kFirstElementIndex + index);
+}
+
void TemplateList::set(int index, Object value) {
FixedArray::cast(*this).set(kFirstElementIndex + index, value);
}
diff --git a/deps/v8/src/objects/fixed-array.h b/deps/v8/src/objects/fixed-array.h
index 02f26502b2..ca6f06e83c 100644
--- a/deps/v8/src/objects/fixed-array.h
+++ b/deps/v8/src/objects/fixed-array.h
@@ -72,16 +72,15 @@ enum FixedArraySubInstanceType {
class FixedArrayBase : public HeapObject {
public:
// [length]: length of the array.
- inline int length() const;
- inline void set_length(int value);
+ DECL_INT_ACCESSORS(length)
// Get and set the length using acquire loads and release stores.
- inline int synchronized_length() const;
- inline void synchronized_set_length(int value);
+ DECL_SYNCHRONIZED_INT_ACCESSORS(length)
inline Object unchecked_synchronized_length() const;
DECL_CAST(FixedArrayBase)
+ DECL_VERIFIER(FixedArrayBase)
static int GetMaxLengthForNewSpaceAllocation(ElementsKind kind);
@@ -113,6 +112,8 @@ class FixedArray : public FixedArrayBase {
public:
// Setter and getter for elements.
inline Object get(int index) const;
+ inline Object get(Isolate* isolate, int index) const;
+
static inline Handle<Object> get(FixedArray array, int index,
Isolate* isolate);
@@ -267,6 +268,7 @@ class WeakFixedArray : public HeapObject {
DECL_CAST(WeakFixedArray)
inline MaybeObject Get(int index) const;
+ inline MaybeObject Get(Isolate* isolate, int index) const;
// Setter that uses write barrier.
inline void Set(int index, MaybeObject value);
@@ -281,8 +283,7 @@ class WeakFixedArray : public HeapObject {
DECL_INT_ACCESSORS(length)
// Get and set the length using acquire loads and release stores.
- inline int synchronized_length() const;
- inline void synchronized_set_length(int value);
+ DECL_SYNCHRONIZED_INT_ACCESSORS(length)
// Gives access to raw memory which stores the array's data.
inline MaybeObjectSlot data_start();
@@ -336,6 +337,7 @@ class WeakArrayList : public HeapObject {
const MaybeObjectHandle& value);
inline MaybeObject Get(int index) const;
+ inline MaybeObject Get(Isolate* isolate, int index) const;
// Set the element at index to obj. The underlying array must be large enough.
// If you need to grow the WeakArrayList, use the static AddToEnd() method
@@ -359,19 +361,12 @@ class WeakArrayList : public HeapObject {
DECL_INT_ACCESSORS(length)
// Get and set the capacity using acquire loads and release stores.
- inline int synchronized_capacity() const;
- inline void synchronized_set_capacity(int value);
-
+ DECL_SYNCHRONIZED_INT_ACCESSORS(capacity)
// Layout description.
-#define WEAK_ARRAY_LIST_FIELDS(V) \
- V(kCapacityOffset, kTaggedSize) \
- V(kLengthOffset, kTaggedSize) \
- /* Header size. */ \
- V(kHeaderSize, 0)
-
- DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, WEAK_ARRAY_LIST_FIELDS)
-#undef WEAK_ARRAY_LIST_FIELDS
+ DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
+ TORQUE_GENERATED_WEAK_ARRAY_LIST_FIELDS)
+ static constexpr int kHeaderSize = kSize;
using BodyDescriptor = WeakArrayBodyDescriptor;
@@ -442,6 +437,7 @@ class ArrayList : public FixedArray {
// storage capacity, i.e., length().
inline void SetLength(int length);
inline Object Get(int index) const;
+ inline Object Get(Isolate* isolate, int index) const;
inline ObjectSlot Slot(int index);
// Set the element at index to obj. The underlying array must be large enough.
@@ -492,6 +488,9 @@ class ByteArray : public FixedArrayBase {
inline uint32_t get_uint32(int index) const;
inline void set_uint32(int index, uint32_t value);
+ inline uint32_t get_uint32_relaxed(int index) const;
+ inline void set_uint32_relaxed(int index, uint32_t value);
+
// Clear uninitialized padding space. This ensures that the snapshot content
// is deterministic.
inline void clear_padding();
@@ -552,9 +551,9 @@ class PodArray : public ByteArray {
static Handle<PodArray<T>> New(
Isolate* isolate, int length,
AllocationType allocation = AllocationType::kYoung);
- void copy_out(int index, T* result) {
+ void copy_out(int index, T* result, int length) {
ByteArray::copy_out(index * sizeof(T), reinterpret_cast<byte*>(result),
- sizeof(T));
+ length * sizeof(T));
}
void copy_in(int index, const T* buffer, int length) {
@@ -562,9 +561,14 @@ class PodArray : public ByteArray {
length * sizeof(T));
}
+ bool matches(const T* buffer, int length) {
+ DCHECK_LE(length, this->length());
+ return memcmp(GetDataStartAddress(), buffer, length * sizeof(T)) == 0;
+ }
+
T get(int index) {
T result;
- copy_out(index, &result);
+ copy_out(index, &result, 1);
return result;
}
@@ -581,6 +585,7 @@ class TemplateList : public FixedArray {
static Handle<TemplateList> New(Isolate* isolate, int size);
inline int length() const;
inline Object get(int index) const;
+ inline Object get(Isolate* isolate, int index) const;
inline void set(int index, Object value);
static Handle<TemplateList> Add(Isolate* isolate, Handle<TemplateList> list,
Handle<Object> value);
diff --git a/deps/v8/src/objects/free-space-inl.h b/deps/v8/src/objects/free-space-inl.h
index bea8257515..848b8202ae 100644
--- a/deps/v8/src/objects/free-space-inl.h
+++ b/deps/v8/src/objects/free-space-inl.h
@@ -26,29 +26,14 @@ RELAXED_SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
int FreeSpace::Size() { return size(); }
FreeSpace FreeSpace::next() {
-#ifdef DEBUG
- Heap* heap = GetHeapFromWritableObject(*this);
- Object free_space_map =
- Isolate::FromHeap(heap)->root(RootIndex::kFreeSpaceMap);
- DCHECK_IMPLIES(!map_slot().contains_value(free_space_map.ptr()),
- !heap->deserialization_complete() &&
- map_slot().contains_value(kNullAddress));
-#endif
- DCHECK_LE(kNextOffset + kTaggedSize, relaxed_read_size());
- return FreeSpace::unchecked_cast(*ObjectSlot(address() + kNextOffset));
+ DCHECK(IsValid());
+ return FreeSpace::unchecked_cast(
+ TaggedField<Object, kNextOffset>::load(*this));
}
void FreeSpace::set_next(FreeSpace next) {
-#ifdef DEBUG
- Heap* heap = GetHeapFromWritableObject(*this);
- Object free_space_map =
- Isolate::FromHeap(heap)->root(RootIndex::kFreeSpaceMap);
- DCHECK_IMPLIES(!map_slot().contains_value(free_space_map.ptr()),
- !heap->deserialization_complete() &&
- map_slot().contains_value(kNullAddress));
-#endif
- DCHECK_LE(kNextOffset + kTaggedSize, relaxed_read_size());
- ObjectSlot(address() + kNextOffset).Relaxed_Store(next);
+ DCHECK(IsValid());
+ RELAXED_WRITE_FIELD(*this, kNextOffset, next);
}
FreeSpace FreeSpace::cast(HeapObject o) {
@@ -61,6 +46,17 @@ FreeSpace FreeSpace::unchecked_cast(const Object o) {
return bit_cast<FreeSpace>(o);
}
+bool FreeSpace::IsValid() {
+ Heap* heap = GetHeapFromWritableObject(*this);
+ Object free_space_map =
+ Isolate::FromHeap(heap)->root(RootIndex::kFreeSpaceMap);
+ CHECK_IMPLIES(!map_slot().contains_value(free_space_map.ptr()),
+ !heap->deserialization_complete() &&
+ map_slot().contains_value(kNullAddress));
+ CHECK_LE(kNextOffset + kTaggedSize, relaxed_read_size());
+ return true;
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/free-space.h b/deps/v8/src/objects/free-space.h
index 38f5794646..5714727036 100644
--- a/deps/v8/src/objects/free-space.h
+++ b/deps/v8/src/objects/free-space.h
@@ -44,6 +44,9 @@ class FreeSpace : public HeapObject {
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
TORQUE_GENERATED_FREE_SPACE_FIELDS)
+ private:
+ inline bool IsValid();
+
OBJECT_CONSTRUCTORS(FreeSpace, HeapObject);
};
diff --git a/deps/v8/src/objects/hash-table-inl.h b/deps/v8/src/objects/hash-table-inl.h
index 77453721ae..b807851d85 100644
--- a/deps/v8/src/objects/hash-table-inl.h
+++ b/deps/v8/src/objects/hash-table-inl.h
@@ -71,14 +71,19 @@ void EphemeronHashTable::set_key(int index, Object value,
}
int HashTableBase::NumberOfElements() const {
- return Smi::ToInt(get(kNumberOfElementsIndex));
+ int offset = OffsetOfElementAt(kNumberOfElementsIndex);
+ return TaggedField<Smi>::load(*this, offset).value();
}
int HashTableBase::NumberOfDeletedElements() const {
- return Smi::ToInt(get(kNumberOfDeletedElementsIndex));
+ int offset = OffsetOfElementAt(kNumberOfDeletedElementsIndex);
+ return TaggedField<Smi>::load(*this, offset).value();
}
-int HashTableBase::Capacity() const { return Smi::ToInt(get(kCapacityIndex)); }
+int HashTableBase::Capacity() const {
+ int offset = OffsetOfElementAt(kCapacityIndex);
+ return TaggedField<Smi>::load(*this, offset).value();
+}
void HashTableBase::ElementAdded() {
SetNumberOfElements(NumberOfElements() + 1);
@@ -165,6 +170,15 @@ bool HashTable<Derived, Shape>::ToKey(ReadOnlyRoots roots, int entry,
}
template <typename Derived, typename Shape>
+bool HashTable<Derived, Shape>::ToKey(Isolate* isolate, int entry,
+ Object* out_k) {
+ Object k = KeyAt(isolate, entry);
+ if (!IsKey(GetReadOnlyRoots(isolate), k)) return false;
+ *out_k = Shape::Unwrap(k);
+ return true;
+}
+
+template <typename Derived, typename Shape>
void HashTable<Derived, Shape>::set_key(int index, Object value) {
DCHECK(!IsEphemeronHashTable());
FixedArray::set(index, value);
diff --git a/deps/v8/src/objects/hash-table.h b/deps/v8/src/objects/hash-table.h
index 610dc9d28e..54d8ce0d2a 100644
--- a/deps/v8/src/objects/hash-table.h
+++ b/deps/v8/src/objects/hash-table.h
@@ -160,9 +160,16 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
static bool IsKey(ReadOnlyRoots roots, Object k);
inline bool ToKey(ReadOnlyRoots roots, int entry, Object* out_k);
+ inline bool ToKey(Isolate* isolate, int entry, Object* out_k);
// Returns the key at entry.
- Object KeyAt(int entry) { return get(EntryToIndex(entry) + kEntryKeyIndex); }
+ Object KeyAt(int entry) {
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return KeyAt(isolate, entry);
+ }
+ Object KeyAt(Isolate* isolate, int entry) {
+ return get(isolate, EntryToIndex(entry) + kEntryKeyIndex);
+ }
static const int kElementsStartIndex = kPrefixStartIndex + Shape::kPrefixSize;
static const int kEntrySize = Shape::kEntrySize;
diff --git a/deps/v8/src/objects/heap-number-inl.h b/deps/v8/src/objects/heap-number-inl.h
index 3986e9146c..3d70d71c89 100644
--- a/deps/v8/src/objects/heap-number-inl.h
+++ b/deps/v8/src/objects/heap-number-inl.h
@@ -31,11 +31,11 @@ void HeapNumberBase::set_value(double value) {
uint64_t HeapNumberBase::value_as_bits() const {
// Bug(v8:8875): HeapNumber's double may be unaligned.
- return ReadUnalignedValue<uint64_t>(field_address(kValueOffset));
+ return base::ReadUnalignedValue<uint64_t>(field_address(kValueOffset));
}
void HeapNumberBase::set_value_as_bits(uint64_t bits) {
- WriteUnalignedValue<uint64_t>(field_address(kValueOffset), bits);
+ base::WriteUnalignedValue<uint64_t>(field_address(kValueOffset), bits);
}
int HeapNumberBase::get_exponent() {
diff --git a/deps/v8/src/objects/heap-object-inl.h b/deps/v8/src/objects/heap-object-inl.h
index 3d5deeff63..88c0011bdf 100644
--- a/deps/v8/src/objects/heap-object-inl.h
+++ b/deps/v8/src/objects/heap-object-inl.h
@@ -7,10 +7,6 @@
#include "src/objects/heap-object.h"
-#include "src/heap/heap-write-barrier-inl.h"
-// TODO(jkummerow): Get rid of this by moving NROSO::GetIsolate elsewhere.
-#include "src/execution/isolate.h"
-
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -24,16 +20,6 @@ HeapObject::HeapObject(Address ptr, AllowInlineSmiStorage allow_smi)
IsHeapObject());
}
-// static
-Heap* NeverReadOnlySpaceObject::GetHeap(const HeapObject object) {
- return GetHeapFromWritableObject(object);
-}
-
-// static
-Isolate* NeverReadOnlySpaceObject::GetIsolate(const HeapObject object) {
- return Isolate::FromHeap(GetHeap(object));
-}
-
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/heap-object.h b/deps/v8/src/objects/heap-object.h
index 9ca51bdda1..ad5475c9e8 100644
--- a/deps/v8/src/objects/heap-object.h
+++ b/deps/v8/src/objects/heap-object.h
@@ -9,6 +9,7 @@
#include "src/roots/roots.h"
#include "src/objects/objects.h"
+#include "src/objects/tagged-field.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -22,27 +23,30 @@ class Heap;
// objects.
class HeapObject : public Object {
public:
- bool is_null() const { return ptr() == kNullAddress; }
+ bool is_null() const {
+ return static_cast<Tagged_t>(ptr()) == static_cast<Tagged_t>(kNullAddress);
+ }
// [map]: Contains a map which contains the object's reflective
// information.
- inline Map map() const;
+ DECL_GETTER(map, Map)
inline void set_map(Map value);
- inline MapWordSlot map_slot() const;
+ inline ObjectSlot map_slot() const;
// The no-write-barrier version. This is OK if the object is white and in
// new space, or if the value is an immortal immutable object, like the maps
// of primitive (non-JS) objects like strings, heap numbers etc.
inline void set_map_no_write_barrier(Map value);
- // Get the map using acquire load.
- inline Map synchronized_map() const;
- inline MapWord synchronized_map_word() const;
-
- // Set the map using release store
+ // Access the map using acquire load and release store.
+ DECL_GETTER(synchronized_map, Map)
inline void synchronized_set_map(Map value);
- inline void synchronized_set_map_word(MapWord map_word);
+
+ // Compare-and-swaps map word using release store, returns true if the map
+ // word was actually swapped.
+ inline bool synchronized_compare_and_swap_map_word(MapWord old_map_word,
+ MapWord new_map_word);
// Initialize the map immediately after the object is allocated.
// Do not use this outside Heap.
@@ -51,18 +55,29 @@ class HeapObject : public Object {
// During garbage collection, the map word of a heap object does not
// necessarily contain a map pointer.
- inline MapWord map_word() const;
+ DECL_GETTER(map_word, MapWord)
inline void set_map_word(MapWord map_word);
+ // Access the map word using acquire load and release store.
+ DECL_GETTER(synchronized_map_word, MapWord)
+ inline void synchronized_set_map_word(MapWord map_word);
+
// TODO(v8:7464): Once RO_SPACE is shared between isolates, this method can be
// removed as ReadOnlyRoots will be accessible from a global variable. For now
// this method exists to help remove GetIsolate/GetHeap from HeapObject, in a
// way that doesn't require passing Isolate/Heap down huge call chains or to
// places where it might not be safe to access it.
inline ReadOnlyRoots GetReadOnlyRoots() const;
+ // This version is intended to be used for the isolate values produced by
+ // i::GetIsolateForPtrCompr(HeapObject) function which may return nullptr.
+ inline ReadOnlyRoots GetReadOnlyRoots(Isolate* isolate) const;
-#define IS_TYPE_FUNCTION_DECL(Type) V8_INLINE bool Is##Type() const;
+#define IS_TYPE_FUNCTION_DECL(Type) \
+ V8_INLINE bool Is##Type() const; \
+ V8_INLINE bool Is##Type(Isolate* isolate) const;
HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
+ IS_TYPE_FUNCTION_DECL(HashTableBase)
+ IS_TYPE_FUNCTION_DECL(SmallOrderedHashTable)
#undef IS_TYPE_FUNCTION_DECL
bool IsExternal(Isolate* isolate) const;
@@ -74,13 +89,12 @@ class HeapObject : public Object {
V8_INLINE bool Is##Type(ReadOnlyRoots roots) const; \
V8_INLINE bool Is##Type() const;
ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
+ IS_TYPE_FUNCTION_DECL(NullOrUndefined, /* unused */)
#undef IS_TYPE_FUNCTION_DECL
- V8_INLINE bool IsNullOrUndefined(Isolate* isolate) const;
- V8_INLINE bool IsNullOrUndefined(ReadOnlyRoots roots) const;
- V8_INLINE bool IsNullOrUndefined() const;
-
-#define DECL_STRUCT_PREDICATE(NAME, Name, name) V8_INLINE bool Is##Name() const;
+#define DECL_STRUCT_PREDICATE(NAME, Name, name) \
+ V8_INLINE bool Is##Name() const; \
+ V8_INLINE bool Is##Name(Isolate* isolate) const;
STRUCT_LIST(DECL_STRUCT_PREDICATE)
#undef DECL_STRUCT_PREDICATE
@@ -189,6 +203,8 @@ class HeapObject : public Object {
STATIC_ASSERT(kMapOffset == Internals::kHeapObjectMapOffset);
+ using MapField = TaggedField<MapWord, HeapObject::kMapOffset>;
+
inline Address GetFieldAddress(int field_offset) const;
protected:
@@ -203,16 +219,6 @@ class HeapObject : public Object {
OBJECT_CONSTRUCTORS_IMPL(HeapObject, Object)
CAST_ACCESSOR(HeapObject)
-// Helper class for objects that can never be in RO space.
-class NeverReadOnlySpaceObject {
- public:
- // The Heap the object was allocated in. Used also to access Isolate.
- static inline Heap* GetHeap(const HeapObject object);
-
- // Convenience method to get current isolate.
- static inline Isolate* GetIsolate(const HeapObject object);
-};
-
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/instance-type.h b/deps/v8/src/objects/instance-type.h
index 559ed34784..79c953aa87 100644
--- a/deps/v8/src/objects/instance-type.h
+++ b/deps/v8/src/objects/instance-type.h
@@ -11,6 +11,8 @@
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
+#include "torque-generated/instance-types-tq.h"
+
namespace v8 {
namespace internal {
@@ -32,11 +34,16 @@ enum StringRepresentationTag {
};
const uint32_t kIsIndirectStringMask = 1 << 0;
const uint32_t kIsIndirectStringTag = 1 << 0;
+// NOLINTNEXTLINE(runtime/references) (false positive)
STATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0);
+// NOLINTNEXTLINE(runtime/references) (false positive)
STATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0);
+// NOLINTNEXTLINE(runtime/references) (false positive)
STATIC_ASSERT((kConsStringTag & kIsIndirectStringMask) == kIsIndirectStringTag);
+// NOLINTNEXTLINE(runtime/references) (false positive)
STATIC_ASSERT((kSlicedStringTag & kIsIndirectStringMask) ==
kIsIndirectStringTag);
+// NOLINTNEXTLINE(runtime/references) (false positive)
STATIC_ASSERT((kThinStringTag & kIsIndirectStringMask) == kIsIndirectStringTag);
// For strings, bit 3 indicates whether the string consists of two-byte
@@ -141,6 +148,7 @@ enum InstanceType : uint16_t {
ACCESSOR_PAIR_TYPE,
ALIASED_ARGUMENTS_ENTRY_TYPE,
ALLOCATION_MEMENTO_TYPE,
+ ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
ASM_WASM_DATA_TYPE,
ASYNC_GENERATOR_REQUEST_TYPE,
CLASS_POSITIONS_TYPE,
@@ -150,24 +158,23 @@ enum InstanceType : uint16_t {
FUNCTION_TEMPLATE_RARE_DATA_TYPE,
INTERCEPTOR_INFO_TYPE,
INTERPRETER_DATA_TYPE,
- MODULE_INFO_ENTRY_TYPE,
- MODULE_TYPE,
OBJECT_TEMPLATE_INFO_TYPE,
PROMISE_CAPABILITY_TYPE,
PROMISE_REACTION_TYPE,
PROTOTYPE_INFO_TYPE,
SCRIPT_TYPE,
SOURCE_POSITION_TABLE_WITH_FRAME_CACHE_TYPE,
+ SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE,
STACK_FRAME_INFO_TYPE,
STACK_TRACE_FRAME_TYPE,
TEMPLATE_OBJECT_DESCRIPTION_TYPE,
TUPLE2_TYPE,
TUPLE3_TYPE,
- ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
WASM_CAPI_FUNCTION_DATA_TYPE,
WASM_DEBUG_INFO_TYPE,
WASM_EXCEPTION_TAG_TYPE,
WASM_EXPORTED_FUNCTION_DATA_TYPE,
+ WASM_INDIRECT_FUNCTION_TABLE_TYPE,
WASM_JS_FUNCTION_DATA_TYPE,
CALLABLE_TASK_TYPE, // FIRST_MICROTASK_TYPE
@@ -177,6 +184,14 @@ enum InstanceType : uint16_t {
PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE,
FINALIZATION_GROUP_CLEANUP_JOB_TASK_TYPE, // LAST_MICROTASK_TYPE
+#define MAKE_TORQUE_INSTANCE_TYPE(V) V,
+ TORQUE_DEFINED_INSTANCE_TYPES(MAKE_TORQUE_INSTANCE_TYPE)
+#undef MAKE_TORQUE_INSTANCE_TYPE
+
+ // Modules
+ SOURCE_TEXT_MODULE_TYPE, // FIRST_MODULE_TYPE
+ SYNTHETIC_MODULE_TYPE, // LAST_MODULE_TYPE
+
ALLOCATION_SITE_TYPE,
EMBEDDER_DATA_ARRAY_TYPE,
// FixedArrays.
@@ -246,7 +261,7 @@ enum InstanceType : uint16_t {
// Like JS_API_OBJECT_TYPE, but requires access checks and/or has
// interceptors.
JS_SPECIAL_API_OBJECT_TYPE = 0x0410, // LAST_SPECIAL_RECEIVER_TYPE
- JS_VALUE_TYPE, // LAST_CUSTOM_ELEMENTS_RECEIVER
+ JS_PRIMITIVE_WRAPPER_TYPE, // LAST_CUSTOM_ELEMENTS_RECEIVER
// Like JS_OBJECT_TYPE, but created from API function.
JS_API_OBJECT_TYPE = 0x0420,
JS_OBJECT_TYPE,
@@ -332,6 +347,9 @@ enum InstanceType : uint16_t {
// Boundaries for testing if given HeapObject is a subclass of Microtask.
FIRST_MICROTASK_TYPE = CALLABLE_TASK_TYPE,
LAST_MICROTASK_TYPE = FINALIZATION_GROUP_CLEANUP_JOB_TASK_TYPE,
+ // Boundaries of module record types
+ FIRST_MODULE_TYPE = SOURCE_TEXT_MODULE_TYPE,
+ LAST_MODULE_TYPE = SYNTHETIC_MODULE_TYPE,
// Boundary for promotion to old space.
LAST_DATA_TYPE = FILLER_TYPE,
// Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
@@ -349,7 +367,7 @@ enum InstanceType : uint16_t {
// Boundary case for testing JSReceivers that may have elements while having
// an empty fixed array as elements backing store. This is true for string
// wrappers.
- LAST_CUSTOM_ELEMENTS_RECEIVER = JS_VALUE_TYPE,
+ LAST_CUSTOM_ELEMENTS_RECEIVER = JS_PRIMITIVE_WRAPPER_TYPE,
FIRST_SET_ITERATOR_TYPE = JS_SET_KEY_VALUE_ITERATOR_TYPE,
LAST_SET_ITERATOR_TYPE = JS_SET_VALUE_ITERATOR_TYPE,
@@ -364,6 +382,7 @@ enum InstanceType : uint16_t {
constexpr InstanceType LAST_STRING_TYPE =
static_cast<InstanceType>(FIRST_NONSTRING_TYPE - 1);
+// NOLINTNEXTLINE(runtime/references) (false positive)
STATIC_ASSERT((FIRST_NONSTRING_TYPE & kIsNotStringMask) != kStringTag);
STATIC_ASSERT(JS_OBJECT_TYPE == Internals::kJSObjectType);
STATIC_ASSERT(JS_API_OBJECT_TYPE == Internals::kJSApiObjectType);
@@ -420,12 +439,16 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
V(JSDataView, JS_DATA_VIEW_TYPE) \
V(JSDate, JS_DATE_TYPE) \
V(JSError, JS_ERROR_TYPE) \
+ V(JSFinalizationGroup, JS_FINALIZATION_GROUP_TYPE) \
+ V(JSFinalizationGroupCleanupIterator, \
+ JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE) \
V(JSFunction, JS_FUNCTION_TYPE) \
V(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE) \
V(JSGlobalProxy, JS_GLOBAL_PROXY_TYPE) \
V(JSMap, JS_MAP_TYPE) \
V(JSMessageObject, JS_MESSAGE_OBJECT_TYPE) \
V(JSModuleNamespace, JS_MODULE_NAMESPACE_TYPE) \
+ V(JSPrimitiveWrapper, JS_PRIMITIVE_WRAPPER_TYPE) \
V(JSPromise, JS_PROMISE_TYPE) \
V(JSProxy, JS_PROXY_TYPE) \
V(JSRegExp, JS_REGEXP_TYPE) \
@@ -434,10 +457,6 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
V(JSSet, JS_SET_TYPE) \
V(JSStringIterator, JS_STRING_ITERATOR_TYPE) \
V(JSTypedArray, JS_TYPED_ARRAY_TYPE) \
- V(JSValue, JS_VALUE_TYPE) \
- V(JSFinalizationGroup, JS_FINALIZATION_GROUP_TYPE) \
- V(JSFinalizationGroupCleanupIterator, \
- JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE) \
V(JSWeakMap, JS_WEAK_MAP_TYPE) \
V(JSWeakRef, JS_WEAK_REF_TYPE) \
V(JSWeakSet, JS_WEAK_SET_TYPE) \
@@ -462,9 +481,11 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
V(SmallOrderedHashMap, SMALL_ORDERED_HASH_MAP_TYPE) \
V(SmallOrderedHashSet, SMALL_ORDERED_HASH_SET_TYPE) \
V(SmallOrderedNameDictionary, SMALL_ORDERED_NAME_DICTIONARY_TYPE) \
+ V(SourceTextModule, SOURCE_TEXT_MODULE_TYPE) \
V(StoreHandler, STORE_HANDLER_TYPE) \
V(StringTable, STRING_TABLE_TYPE) \
V(Symbol, SYMBOL_TYPE) \
+ V(SyntheticModule, SYNTHETIC_MODULE_TYPE) \
V(TransitionArray, TRANSITION_ARRAY_TYPE) \
V(UncompiledDataWithoutPreparseData, \
UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE) \
@@ -505,6 +526,7 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
V(JSMapIterator, FIRST_MAP_ITERATOR_TYPE, LAST_MAP_ITERATOR_TYPE) \
V(JSSetIterator, FIRST_SET_ITERATOR_TYPE, LAST_SET_ITERATOR_TYPE) \
V(Microtask, FIRST_MICROTASK_TYPE, LAST_MICROTASK_TYPE) \
+ V(Module, FIRST_MODULE_TYPE, LAST_MODULE_TYPE) \
V(Name, FIRST_NAME_TYPE, LAST_NAME_TYPE) \
V(String, FIRST_STRING_TYPE, LAST_STRING_TYPE) \
V(WeakFixedArray, FIRST_WEAK_FIXED_ARRAY_TYPE, LAST_WEAK_FIXED_ARRAY_TYPE)
diff --git a/deps/v8/src/objects/intl-objects.cc b/deps/v8/src/objects/intl-objects.cc
index f2bc87ebac..dbf212aaf8 100644
--- a/deps/v8/src/objects/intl-objects.cc
+++ b/deps/v8/src/objects/intl-objects.cc
@@ -34,9 +34,11 @@
#include "unicode/formattedvalue.h"
#include "unicode/locid.h"
#include "unicode/normalizer2.h"
+#include "unicode/numberformatter.h"
#include "unicode/numfmt.h"
#include "unicode/numsys.h"
#include "unicode/timezone.h"
+#include "unicode/ures.h"
#include "unicode/ustring.h"
#include "unicode/uvernum.h" // U_ICU_VERSION_MAJOR_NUM
@@ -52,9 +54,8 @@ namespace v8 {
namespace internal {
namespace {
-inline bool IsASCIIUpper(uint16_t ch) { return ch >= 'A' && ch <= 'Z'; }
-const uint8_t kToLower[256] = {
+constexpr uint8_t kToLower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
@@ -79,20 +80,17 @@ const uint8_t kToLower[256] = {
0xFC, 0xFD, 0xFE, 0xFF,
};
-inline uint16_t ToLatin1Lower(uint16_t ch) {
+inline constexpr uint16_t ToLatin1Lower(uint16_t ch) {
return static_cast<uint16_t>(kToLower[ch]);
}
-inline uint16_t ToASCIIUpper(uint16_t ch) {
- return ch & ~((ch >= 'a' && ch <= 'z') << 5);
-}
-
// Does not work for U+00DF (sharp-s), U+00B5 (micron), U+00FF.
-inline uint16_t ToLatin1Upper(uint16_t ch) {
+inline constexpr uint16_t ToLatin1Upper(uint16_t ch) {
+#if V8_CAN_HAVE_DCHECK_IN_CONSTEXPR
DCHECK(ch != 0xDF && ch != 0xB5 && ch != 0xFF);
+#endif
return ch &
- ~(((ch >= 'a' && ch <= 'z') || (((ch & 0xE0) == 0xE0) && ch != 0xF7))
- << 5);
+ ~((IsAsciiLower(ch) || (((ch & 0xE0) == 0xE0) && ch != 0xF7)) << 5);
}
template <typename Char>
@@ -104,7 +102,7 @@ bool ToUpperFastASCII(const Vector<const Char>& src,
for (auto it = src.begin(); it != src.end(); ++it) {
uint16_t ch = static_cast<uint16_t>(*it);
ored |= ch;
- result->SeqOneByteStringSet(index++, ToASCIIUpper(ch));
+ result->SeqOneByteStringSet(index++, ToAsciiUpper(ch));
}
return !(ored & ~0x7F);
}
@@ -155,7 +153,7 @@ void ToUpperWithSharpS(const Vector<const Char>& src,
inline int FindFirstUpperOrNonAscii(String s, int length) {
for (int index = 0; index < length; ++index) {
uint16_t ch = s.Get(index);
- if (V8_UNLIKELY(IsASCIIUpper(ch) || ch & ~0x7F)) {
+ if (V8_UNLIKELY(IsAsciiUpper(ch) || ch & ~0x7F)) {
return index;
}
}
@@ -180,12 +178,11 @@ const UChar* GetUCharBufferFromFlat(const String::FlatContent& flat,
template <typename T>
MaybeHandle<T> New(Isolate* isolate, Handle<JSFunction> constructor,
Handle<Object> locales, Handle<Object> options) {
- Handle<JSObject> result;
+ Handle<Map> map;
ASSIGN_RETURN_ON_EXCEPTION(
- isolate, result,
- JSObject::New(constructor, constructor, Handle<AllocationSite>::null()),
- T);
- return T::Initialize(isolate, Handle<T>::cast(result), locales, options);
+ isolate, map,
+ JSFunction::GetDerivedMap(isolate, constructor, constructor), T);
+ return T::New(isolate, map, locales, options);
}
} // namespace
@@ -212,6 +209,24 @@ icu::UnicodeString Intl::ToICUUnicodeString(Isolate* isolate,
return icu::UnicodeString(uchar_buffer, length);
}
+icu::StringPiece Intl::ToICUStringPiece(Isolate* isolate,
+ Handle<String> string) {
+ DCHECK(string->IsFlat());
+ DisallowHeapAllocation no_gc;
+
+ const String::FlatContent& flat = string->GetFlatContent(no_gc);
+ if (!flat.IsOneByte()) return icu::StringPiece(nullptr, 0);
+
+ int32_t length = string->length();
+ const char* char_buffer =
+ reinterpret_cast<const char*>(flat.ToOneByteVector().begin());
+ if (!String::IsAscii(char_buffer, length)) {
+ return icu::StringPiece(nullptr, 0);
+ }
+
+ return icu::StringPiece(char_buffer, length);
+}
+
namespace {
MaybeHandle<String> LocaleConvertCase(Isolate* isolate, Handle<String> s,
bool is_to_upper, const char* lang) {
@@ -506,23 +521,59 @@ bool RemoveLocaleScriptTag(const std::string& icu_locale,
return true;
}
+bool ValidateResource(const icu::Locale locale, const char* path,
+ const char* key) {
+ bool result = false;
+ UErrorCode status = U_ZERO_ERROR;
+ UResourceBundle* bundle = ures_open(path, locale.getName(), &status);
+ if (bundle != nullptr && status == U_ZERO_ERROR) {
+ if (key == nullptr) {
+ result = true;
+ } else {
+ UResourceBundle* key_bundle =
+ ures_getByKey(bundle, key, nullptr, &status);
+ result = key_bundle != nullptr && (status == U_ZERO_ERROR);
+ ures_close(key_bundle);
+ }
+ }
+ ures_close(bundle);
+ if (!result) {
+ if ((locale.getCountry()[0] != '\0') && (locale.getScript()[0] != '\0')) {
+ // Fallback to try without country.
+ std::string without_country(locale.getLanguage());
+ without_country = without_country.append("-").append(locale.getScript());
+ return ValidateResource(without_country.c_str(), path, key);
+ } else if ((locale.getCountry()[0] != '\0') ||
+ (locale.getScript()[0] != '\0')) {
+ // Fallback to try with only language.
+ std::string language(locale.getLanguage());
+ return ValidateResource(language.c_str(), path, key);
+ }
+ }
+ return result;
+}
+
} // namespace
std::set<std::string> Intl::BuildLocaleSet(
- const icu::Locale* icu_available_locales, int32_t count) {
+ const icu::Locale* icu_available_locales, int32_t count, const char* path,
+ const char* validate_key) {
std::set<std::string> locales;
for (int32_t i = 0; i < count; ++i) {
std::string locale =
Intl::ToLanguageTag(icu_available_locales[i]).FromJust();
+ if (path != nullptr || validate_key != nullptr) {
+ if (!ValidateResource(icu_available_locales[i], path, validate_key)) {
+ continue;
+ }
+ }
locales.insert(locale);
-
std::string shortened_locale;
if (RemoveLocaleScriptTag(locale, &shortened_locale)) {
std::replace(shortened_locale.begin(), shortened_locale.end(), '_', '-');
locales.insert(shortened_locale);
}
}
-
return locales;
}
@@ -683,19 +734,10 @@ V8_WARN_UNUSED_RESULT Maybe<bool> Intl::GetBoolOption(
namespace {
-char AsciiToLower(char c) {
- if (c < 'A' || c > 'Z') {
- return c;
- }
- return c | (1 << 5);
-}
-
-bool IsLowerAscii(char c) { return c >= 'a' && c < 'z'; }
-
bool IsTwoLetterLanguage(const std::string& locale) {
// Two letters, both in range 'a'-'z'...
- return locale.length() == 2 && IsLowerAscii(locale[0]) &&
- IsLowerAscii(locale[1]);
+ return locale.length() == 2 && IsAsciiLower(locale[0]) &&
+ IsAsciiLower(locale[1]);
}
bool IsDeprecatedLanguage(const std::string& locale) {
@@ -770,7 +812,7 @@ Maybe<std::string> Intl::CanonicalizeLanguageTag(Isolate* isolate,
// Because per BCP 47 2.1.1 language tags are case-insensitive, lowercase
// the input before any more check.
- std::transform(locale.begin(), locale.end(), locale.begin(), AsciiToLower);
+ std::transform(locale.begin(), locale.end(), locale.begin(), ToAsciiLower);
// ICU maps a few grandfathered tags to what looks like a regular language
// tag even though IANA language tag registry does not have a preferred
@@ -1020,6 +1062,16 @@ Handle<Object> Intl::CompareStrings(Isolate* isolate,
UCollationResult result;
UErrorCode status = U_ZERO_ERROR;
+ icu::StringPiece string_piece1 = Intl::ToICUStringPiece(isolate, string1);
+ if (!string_piece1.empty()) {
+ icu::StringPiece string_piece2 = Intl::ToICUStringPiece(isolate, string2);
+ if (!string_piece2.empty()) {
+ result = icu_collator.compareUTF8(string_piece1, string_piece2, status);
+ DCHECK(U_SUCCESS(status));
+ return factory->NewNumberFromInt(result);
+ }
+ }
+
icu::UnicodeString string_val1 = Intl::ToICUUnicodeString(isolate, string1);
icu::UnicodeString string_val2 = Intl::ToICUUnicodeString(isolate, string2);
result = icu_collator.compare(string_val1, string_val2, status);
@@ -1116,10 +1168,12 @@ Maybe<int> DefaultNumberOption(Isolate* isolate, Handle<Object> value, int min,
return Just(FastD2I(floor(value_num->Number())));
}
+} // namespace
+
// ecma402/#sec-getnumberoption
-Maybe<int> GetNumberOption(Isolate* isolate, Handle<JSReceiver> options,
- Handle<String> property, int min, int max,
- int fallback) {
+Maybe<int> Intl::GetNumberOption(Isolate* isolate, Handle<JSReceiver> options,
+ Handle<String> property, int min, int max,
+ int fallback) {
// 1. Let value be ? Get(options, property).
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
@@ -1130,62 +1184,70 @@ Maybe<int> GetNumberOption(Isolate* isolate, Handle<JSReceiver> options,
return DefaultNumberOption(isolate, value, min, max, fallback, property);
}
-Maybe<int> GetNumberOption(Isolate* isolate, Handle<JSReceiver> options,
- const char* property, int min, int max,
- int fallback) {
- Handle<String> property_str =
- isolate->factory()->NewStringFromAsciiChecked(property);
- return GetNumberOption(isolate, options, property_str, min, max, fallback);
-}
-
-} // namespace
-
Maybe<Intl::NumberFormatDigitOptions> Intl::SetNumberFormatDigitOptions(
Isolate* isolate, Handle<JSReceiver> options, int mnfd_default,
- int mxfd_default) {
+ int mxfd_default, bool notation_is_compact) {
+ Factory* factory = isolate->factory();
Intl::NumberFormatDigitOptions digit_options;
// 5. Let mnid be ? GetNumberOption(options, "minimumIntegerDigits,", 1, 21,
// 1).
- int mnid;
- if (!GetNumberOption(isolate, options, "minimumIntegerDigits", 1, 21, 1)
+ int mnid = 1;
+ if (!Intl::GetNumberOption(isolate, options,
+ factory->minimumIntegerDigits_string(), 1, 21, 1)
.To(&mnid)) {
return Nothing<NumberFormatDigitOptions>();
}
- // 6. Let mnfd be ? GetNumberOption(options, "minimumFractionDigits", 0, 20,
- // mnfdDefault).
- int mnfd;
- if (!GetNumberOption(isolate, options, "minimumFractionDigits", 0, 20,
- mnfd_default)
- .To(&mnfd)) {
- return Nothing<NumberFormatDigitOptions>();
- }
+ int mnfd = 0;
+ int mxfd = 0;
+ Handle<Object> mnfd_obj;
+ Handle<Object> mxfd_obj;
+ if (FLAG_harmony_intl_numberformat_unified) {
+ // 6. Let mnfd be ? Get(options, "minimumFractionDigits").
+ Handle<String> mnfd_str = factory->minimumFractionDigits_string();
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, mnfd_obj, JSReceiver::GetProperty(isolate, options, mnfd_str),
+ Nothing<NumberFormatDigitOptions>());
+
+ // 8. Let mnfd be ? Get(options, "maximumFractionDigits").
+ Handle<String> mxfd_str = factory->maximumFractionDigits_string();
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, mxfd_obj, JSReceiver::GetProperty(isolate, options, mxfd_str),
+ Nothing<NumberFormatDigitOptions>());
+ } else {
+ // 6. Let mnfd be ? GetNumberOption(options, "minimumFractionDigits", 0, 20,
+ // mnfdDefault).
+ if (!Intl::GetNumberOption(isolate, options,
+ factory->minimumFractionDigits_string(), 0, 20,
+ mnfd_default)
+ .To(&mnfd)) {
+ return Nothing<NumberFormatDigitOptions>();
+ }
- // 7. Let mxfdActualDefault be max( mnfd, mxfdDefault ).
- int mxfd_actual_default = std::max(mnfd, mxfd_default);
+ // 7. Let mxfdActualDefault be max( mnfd, mxfdDefault ).
+ int mxfd_actual_default = std::max(mnfd, mxfd_default);
- // 8. Let mxfd be ? GetNumberOption(options,
- // "maximumFractionDigits", mnfd, 20, mxfdActualDefault).
- int mxfd;
- if (!GetNumberOption(isolate, options, "maximumFractionDigits", mnfd, 20,
- mxfd_actual_default)
- .To(&mxfd)) {
- return Nothing<NumberFormatDigitOptions>();
+ // 8. Let mxfd be ? GetNumberOption(options,
+ // "maximumFractionDigits", mnfd, 20, mxfdActualDefault).
+ if (!Intl::GetNumberOption(isolate, options,
+ factory->maximumFractionDigits_string(), mnfd,
+ 20, mxfd_actual_default)
+ .To(&mxfd)) {
+ return Nothing<NumberFormatDigitOptions>();
+ }
}
// 9. Let mnsd be ? Get(options, "minimumSignificantDigits").
Handle<Object> mnsd_obj;
- Handle<String> mnsd_str =
- isolate->factory()->minimumSignificantDigits_string();
+ Handle<String> mnsd_str = factory->minimumSignificantDigits_string();
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, mnsd_obj, JSReceiver::GetProperty(isolate, options, mnsd_str),
Nothing<NumberFormatDigitOptions>());
// 10. Let mxsd be ? Get(options, "maximumSignificantDigits").
Handle<Object> mxsd_obj;
- Handle<String> mxsd_str =
- isolate->factory()->maximumSignificantDigits_string();
+ Handle<String> mxsd_str = factory->maximumSignificantDigits_string();
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, mxsd_obj, JSReceiver::GetProperty(isolate, options, mxsd_str),
Nothing<NumberFormatDigitOptions>());
@@ -1222,8 +1284,50 @@ Maybe<Intl::NumberFormatDigitOptions> Intl::SetNumberFormatDigitOptions(
} else {
digit_options.minimum_significant_digits = 0;
digit_options.maximum_significant_digits = 0;
- }
+ if (FLAG_harmony_intl_numberformat_unified) {
+ // 15. Else If mnfd is not undefined or mxfd is not undefined, then
+ if (!mnfd_obj->IsUndefined(isolate) || !mxfd_obj->IsUndefined(isolate)) {
+ // 15. b. Let mnfd be ? DefaultNumberOption(mnfd, 0, 20, mnfdDefault).
+ Handle<String> mnfd_str = factory->minimumFractionDigits_string();
+ if (!DefaultNumberOption(isolate, mnfd_obj, 0, 20, mnfd_default,
+ mnfd_str)
+ .To(&mnfd)) {
+ return Nothing<NumberFormatDigitOptions>();
+ }
+
+ // 15. c. Let mxfdActualDefault be max( mnfd, mxfdDefault ).
+ int mxfd_actual_default = std::max(mnfd, mxfd_default);
+
+ // 15. d. Let mxfd be ? DefaultNumberOption(mxfd, mnfd, 20,
+ // mxfdActualDefault).
+ Handle<String> mxfd_str = factory->maximumFractionDigits_string();
+ if (!DefaultNumberOption(isolate, mxfd_obj, mnfd, 20,
+ mxfd_actual_default, mxfd_str)
+ .To(&mxfd)) {
+ return Nothing<NumberFormatDigitOptions>();
+ }
+ // 15. e. Set intlObj.[[MinimumFractionDigits]] to mnfd.
+ digit_options.minimum_fraction_digits = mnfd;
+
+ // 15. f. Set intlObj.[[MaximumFractionDigits]] to mxfd.
+ digit_options.maximum_fraction_digits = mxfd;
+ // Else If intlObj.[[Notation]] is "compact", then
+ } else if (notation_is_compact) {
+ // a. Set intlObj.[[RoundingType]] to "compact-rounding".
+ // Set minimum_significant_digits to -1 to represent roundingtype is
+ // "compact-rounding".
+ digit_options.minimum_significant_digits = -1;
+ // 17. Else,
+ } else {
+ // 17. b. Set intlObj.[[MinimumFractionDigits]] to mnfdDefault.
+ digit_options.minimum_fraction_digits = mnfd_default;
+
+ // 17. c. Set intlObj.[[MaximumFractionDigits]] to mxfdDefault.
+ digit_options.maximum_fraction_digits = mxfd_default;
+ }
+ }
+ }
return Just(digit_options);
}
@@ -1678,7 +1782,7 @@ Intl::ResolvedLocale Intl::ResolveLocale(
return Intl::ResolvedLocale{canonicalized_locale, icu_locale, extensions};
}
-Managed<icu::UnicodeString> Intl::SetTextToBreakIterator(
+Handle<Managed<icu::UnicodeString>> Intl::SetTextToBreakIterator(
Isolate* isolate, Handle<String> text, icu::BreakIterator* break_iterator) {
text = String::Flatten(isolate, text);
icu::UnicodeString* u_text =
@@ -1688,7 +1792,7 @@ Managed<icu::UnicodeString> Intl::SetTextToBreakIterator(
Managed<icu::UnicodeString>::FromRawPtr(isolate, 0, u_text);
break_iterator->setText(*u_text);
- return *new_u_text;
+ return new_u_text;
}
// ecma262 #sec-string.prototype.normalize
@@ -1927,8 +2031,18 @@ const std::set<std::string>& Intl::GetAvailableLocalesForLocale() {
return available_locales.Pointer()->Get();
}
+namespace {
+
+struct CheckCalendar {
+ static const char* key() { return "calendar"; }
+ static const char* path() { return nullptr; }
+};
+
+} // namespace
+
const std::set<std::string>& Intl::GetAvailableLocalesForDateFormat() {
- static base::LazyInstance<Intl::AvailableLocales<icu::DateFormat>>::type
+ static base::LazyInstance<
+ Intl::AvailableLocales<icu::DateFormat, CheckCalendar>>::type
available_locales = LAZY_INSTANCE_INITIALIZER;
return available_locales.Pointer()->Get();
}
@@ -1966,16 +2080,17 @@ Handle<String> Intl::NumberFieldToType(Isolate* isolate,
: isolate->factory()->plusSign_string();
} else {
double number = numeric_obj->Number();
- return number < 0 ? isolate->factory()->minusSign_string()
- : isolate->factory()->plusSign_string();
+ return std::signbit(number) ? isolate->factory()->minusSign_string()
+ : isolate->factory()->plusSign_string();
}
case UNUM_EXPONENT_SYMBOL_FIELD:
+ return isolate->factory()->exponentSeparator_string();
+
case UNUM_EXPONENT_SIGN_FIELD:
+ return isolate->factory()->exponentMinusSign_string();
+
case UNUM_EXPONENT_FIELD:
- // We should never get these because we're not using any scientific
- // formatter.
- UNREACHABLE();
- return Handle<String>();
+ return isolate->factory()->exponentInteger_string();
case UNUM_PERMILL_FIELD:
// We're not creating any permill formatter, and it's not even clear how
diff --git a/deps/v8/src/objects/intl-objects.h b/deps/v8/src/objects/intl-objects.h
index 1274fa0549..4d4d3245fd 100644
--- a/deps/v8/src/objects/intl-objects.h
+++ b/deps/v8/src/objects/intl-objects.h
@@ -49,7 +49,8 @@ class Intl {
// script; eg, pa_Guru_IN (language=Panjabi, script=Gurmukhi, country-India)
// would include pa_IN.
static std::set<std::string> BuildLocaleSet(
- const icu::Locale* icu_available_locales, int32_t count);
+ const icu::Locale* icu_available_locales, int32_t count, const char* path,
+ const char* validate_key);
static Maybe<std::string> ToLanguageTag(const icu::Locale& locale);
@@ -126,6 +127,10 @@ class Intl {
Isolate* isolate, Handle<JSReceiver> options, const char* property,
const char* service, bool* result);
+ V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<int> GetNumberOption(
+ Isolate* isolate, Handle<JSReceiver> options, Handle<String> property,
+ int min, int max, int fallback);
+
// Canonicalize the locale.
// https://tc39.github.io/ecma402/#sec-canonicalizelanguagetag,
// including type check and structural validity check.
@@ -180,7 +185,8 @@ class Intl {
};
V8_WARN_UNUSED_RESULT static Maybe<NumberFormatDigitOptions>
SetNumberFormatDigitOptions(Isolate* isolate, Handle<JSReceiver> options,
- int mnfd_default, int mxfd_default);
+ int mnfd_default, int mxfd_default,
+ bool notation_is_compact);
static icu::Locale CreateICULocale(const std::string& bcp47_locale);
@@ -277,20 +283,26 @@ class Intl {
// A helper template to implement the GetAvailableLocales
// Usage in src/objects/js-XXX.cc
- //
// const std::set<std::string>& JSXxx::GetAvailableLocales() {
// static base::LazyInstance<Intl::AvailableLocales<icu::YYY>>::type
// available_locales = LAZY_INSTANCE_INITIALIZER;
// return available_locales.Pointer()->Get();
// }
- template <typename T>
+
+ struct SkipResourceCheck {
+ static const char* key() { return nullptr; }
+ static const char* path() { return nullptr; }
+ };
+
+ template <typename T, typename C = SkipResourceCheck>
class AvailableLocales {
public:
AvailableLocales() {
int32_t num_locales = 0;
const icu::Locale* icu_available_locales =
T::getAvailableLocales(num_locales);
- set = Intl::BuildLocaleSet(icu_available_locales, num_locales);
+ set = Intl::BuildLocaleSet(icu_available_locales, num_locales, C::path(),
+ C::key());
}
virtual ~AvailableLocales() {}
const std::set<std::string>& Get() const { return set; }
@@ -300,7 +312,7 @@ class Intl {
};
// Utility function to set text to BreakIterator.
- static Managed<icu::UnicodeString> SetTextToBreakIterator(
+ static Handle<Managed<icu::UnicodeString>> SetTextToBreakIterator(
Isolate* isolate, Handle<String> text,
icu::BreakIterator* break_iterator);
@@ -313,6 +325,10 @@ class Intl {
static icu::UnicodeString ToICUUnicodeString(Isolate* isolate,
Handle<String> string);
+ // Convert a Handle<String> to icu::StringPiece
+ static icu::StringPiece ToICUStringPiece(Isolate* isolate,
+ Handle<String> string);
+
static const uint8_t* ToLatin1LowerTable();
static String ConvertOneByteToLower(String src, String dst);
diff --git a/deps/v8/src/objects/intl-objects.tq b/deps/v8/src/objects/intl-objects.tq
index 67d8537feb..d91df566c3 100644
--- a/deps/v8/src/objects/intl-objects.tq
+++ b/deps/v8/src/objects/intl-objects.tq
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include 'src/objects/js-break-iterator.h'
+#include 'src/objects/js-collator.h'
#include 'src/objects/js-number-format.h'
#include 'src/objects/js-objects.h'
#include 'src/objects/js-plural-rules.h'
@@ -37,8 +39,9 @@ extern class JSNumberFormat extends JSObject {
extern class JSPluralRules extends JSObject {
locale: String;
flags: Smi;
- icu_plural_rules: Foreign; // Managed<icu::PluralRules>
- icu_decimal_format: Foreign; // Managed<icu::DecimalFormat>
+ icu_plural_rules: Foreign; // Managed<icu::PluralRules>
+ icu_number_formatter:
+ Foreign; // Managed<icu::number::LocalizedNumberFormatter>
}
extern class JSRelativeTimeFormat extends JSObject {
@@ -62,3 +65,20 @@ extern class JSSegmentIterator extends JSObject {
unicode_string: Foreign; // Managed<icu::UnicodeString>
flags: Smi;
}
+
+extern class JSV8BreakIterator extends JSObject {
+ locale: String;
+ break_iterator: Foreign; // Managed<icu::BreakIterator>;
+ unicode_string: Foreign; // Managed<icu::UnicodeString>;
+ bound_adopt_text: Undefined | JSFunction;
+ bound_first: Undefined | JSFunction;
+ bound_next: Undefined | JSFunction;
+ bound_current: Undefined | JSFunction;
+ bound_break_type: Undefined | JSFunction;
+ break_iterator_type: Smi;
+}
+
+extern class JSCollator extends JSObject {
+ icu_collator: Foreign; // Managed<icu::Collator>
+ bound_compare: Undefined | JSFunction;
+}
diff --git a/deps/v8/src/objects/js-array-buffer-inl.h b/deps/v8/src/objects/js-array-buffer-inl.h
index 061fec10f7..9151be6da4 100644
--- a/deps/v8/src/objects/js-array-buffer-inl.h
+++ b/deps/v8/src/objects/js-array-buffer-inl.h
@@ -91,11 +91,11 @@ void JSArrayBuffer::clear_padding() {
}
void JSArrayBuffer::set_bit_field(uint32_t bits) {
- WriteField<uint32_t>(kBitFieldOffset, bits);
+ RELAXED_WRITE_UINT32_FIELD(*this, kBitFieldOffset, bits);
}
uint32_t JSArrayBuffer::bit_field() const {
- return ReadField<uint32_t>(kBitFieldOffset);
+ return RELAXED_READ_UINT32_FIELD(*this, kBitFieldOffset);
}
// |bit_field| fields.
diff --git a/deps/v8/src/objects/js-array-buffer.h b/deps/v8/src/objects/js-array-buffer.h
index b22001f04a..7bf2e1ae94 100644
--- a/deps/v8/src/objects/js-array-buffer.h
+++ b/deps/v8/src/objects/js-array-buffer.h
@@ -243,6 +243,12 @@ class JSTypedArray : public JSArrayBufferView {
class BodyDescriptor;
+#ifdef V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP
+ static constexpr size_t kMaxSizeInHeap = V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP;
+#else
+ static constexpr size_t kMaxSizeInHeap = 64;
+#endif
+
private:
static Handle<JSArrayBuffer> MaterializeArrayBuffer(
Handle<JSTypedArray> typed_array);
diff --git a/deps/v8/src/objects/js-array-inl.h b/deps/v8/src/objects/js-array-inl.h
index 335fabba86..1ff7dcb123 100644
--- a/deps/v8/src/objects/js-array-inl.h
+++ b/deps/v8/src/objects/js-array-inl.h
@@ -61,13 +61,14 @@ bool JSArray::HasArrayPrototype(Isolate* isolate) {
ACCESSORS(JSArrayIterator, iterated_object, Object, kIteratedObjectOffset)
ACCESSORS(JSArrayIterator, next_index, Object, kNextIndexOffset)
+SMI_ACCESSORS(JSArrayIterator, raw_kind, kKindOffset)
+
IterationKind JSArrayIterator::kind() const {
- return static_cast<IterationKind>(
- Smi::cast(READ_FIELD(*this, kKindOffset)).value());
+ return static_cast<IterationKind>(raw_kind());
}
void JSArrayIterator::set_kind(IterationKind kind) {
- WRITE_FIELD(*this, kKindOffset, Smi::FromInt(static_cast<int>(kind)));
+ set_raw_kind(static_cast<int>(kind));
}
} // namespace internal
diff --git a/deps/v8/src/objects/js-array.h b/deps/v8/src/objects/js-array.h
index 4bc296e31e..eb581c104e 100644
--- a/deps/v8/src/objects/js-array.h
+++ b/deps/v8/src/objects/js-array.h
@@ -132,7 +132,8 @@ class JSArray : public JSObject {
OBJECT_CONSTRUCTORS(JSArray, JSObject);
};
-Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
+Handle<Object> CacheInitialJSArrayMaps(Isolate* isolate,
+ Handle<Context> native_context,
Handle<Map> initial_map);
// The JSArrayIterator describes JavaScript Array Iterators Objects, as
@@ -179,6 +180,9 @@ class JSArrayIterator : public JSObject {
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
TORQUE_GENERATED_JSARRAY_ITERATOR_FIELDS)
+ private:
+ DECL_INT_ACCESSORS(raw_kind)
+
OBJECT_CONSTRUCTORS(JSArrayIterator, JSObject);
};
diff --git a/deps/v8/src/objects/js-break-iterator-inl.h b/deps/v8/src/objects/js-break-iterator-inl.h
index 177d9d352b..86e87ddb0d 100644
--- a/deps/v8/src/objects/js-break-iterator-inl.h
+++ b/deps/v8/src/objects/js-break-iterator-inl.h
@@ -20,14 +20,12 @@ namespace internal {
OBJECT_CONSTRUCTORS_IMPL(JSV8BreakIterator, JSObject)
-inline void JSV8BreakIterator::set_type(Type type) {
- DCHECK_GT(JSV8BreakIterator::Type::COUNT, type);
- WRITE_FIELD(*this, kTypeOffset, Smi::FromInt(static_cast<int>(type)));
+inline JSV8BreakIterator::Type JSV8BreakIterator::type() const {
+ return static_cast<JSV8BreakIterator::Type>(raw_type());
}
-inline JSV8BreakIterator::Type JSV8BreakIterator::type() const {
- Object value = READ_FIELD(*this, kTypeOffset);
- return static_cast<JSV8BreakIterator::Type>(Smi::ToInt(value));
+inline void JSV8BreakIterator::set_type(Type type) {
+ set_raw_type(static_cast<int>(type));
}
ACCESSORS(JSV8BreakIterator, locale, String, kLocaleOffset)
@@ -41,6 +39,8 @@ ACCESSORS(JSV8BreakIterator, bound_next, Object, kBoundNextOffset)
ACCESSORS(JSV8BreakIterator, bound_current, Object, kBoundCurrentOffset)
ACCESSORS(JSV8BreakIterator, bound_break_type, Object, kBoundBreakTypeOffset)
+SMI_ACCESSORS(JSV8BreakIterator, raw_type, kBreakIteratorTypeOffset)
+
CAST_ACCESSOR(JSV8BreakIterator)
} // namespace internal
diff --git a/deps/v8/src/objects/js-break-iterator.cc b/deps/v8/src/objects/js-break-iterator.cc
index 4879fb41a4..31ed3f8611 100644
--- a/deps/v8/src/objects/js-break-iterator.cc
+++ b/deps/v8/src/objects/js-break-iterator.cc
@@ -15,9 +15,9 @@
namespace v8 {
namespace internal {
-MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::Initialize(
- Isolate* isolate, Handle<JSV8BreakIterator> break_iterator_holder,
- Handle<Object> locales, Handle<Object> options_obj) {
+MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::New(
+ Isolate* isolate, Handle<Map> map, Handle<Object> locales,
+ Handle<Object> options_obj) {
Factory* factory = isolate->factory();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
@@ -96,8 +96,13 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::Initialize(
Handle<String> locale_str =
isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
- break_iterator_holder->set_locale(*locale_str);
+ // Now all properties are ready, so we can allocate the result object.
+ Handle<JSV8BreakIterator> break_iterator_holder =
+ Handle<JSV8BreakIterator>::cast(
+ isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
+ DisallowHeapAllocation no_gc;
+ break_iterator_holder->set_locale(*locale_str);
break_iterator_holder->set_type(type_enum);
break_iterator_holder->set_break_iterator(*managed_break_iterator);
break_iterator_holder->set_unicode_string(*managed_unicode_string);
@@ -126,9 +131,9 @@ void JSV8BreakIterator::AdoptText(
icu::BreakIterator* break_iterator =
break_iterator_holder->break_iterator().raw();
CHECK_NOT_NULL(break_iterator);
- Managed<icu::UnicodeString> unicode_string =
+ Handle<Managed<icu::UnicodeString>> unicode_string =
Intl::SetTextToBreakIterator(isolate, text, break_iterator);
- break_iterator_holder->set_unicode_string(unicode_string);
+ break_iterator_holder->set_unicode_string(*unicode_string);
}
Handle<String> JSV8BreakIterator::TypeAsString() const {
@@ -141,9 +146,8 @@ Handle<String> JSV8BreakIterator::TypeAsString() const {
return GetReadOnlyRoots().sentence_string_handle();
case Type::LINE:
return GetReadOnlyRoots().line_string_handle();
- case Type::COUNT:
- UNREACHABLE();
}
+ UNREACHABLE();
}
Handle<Object> JSV8BreakIterator::Current(
diff --git a/deps/v8/src/objects/js-break-iterator.h b/deps/v8/src/objects/js-break-iterator.h
index fe94c177c4..4b40192c81 100644
--- a/deps/v8/src/objects/js-break-iterator.h
+++ b/deps/v8/src/objects/js-break-iterator.h
@@ -15,6 +15,7 @@
#include "src/objects/intl-objects.h"
#include "src/objects/managed.h"
#include "src/objects/objects.h"
+#include "torque-generated/field-offsets-tq.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -28,9 +29,9 @@ namespace internal {
class JSV8BreakIterator : public JSObject {
public:
- V8_WARN_UNUSED_RESULT static MaybeHandle<JSV8BreakIterator> Initialize(
- Isolate* isolate, Handle<JSV8BreakIterator> break_iterator,
- Handle<Object> input_locales, Handle<Object> input_options);
+ V8_WARN_UNUSED_RESULT static MaybeHandle<JSV8BreakIterator> New(
+ Isolate* isolate, Handle<Map> map, Handle<Object> input_locales,
+ Handle<Object> input_options);
static Handle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSV8BreakIterator> break_iterator);
@@ -50,7 +51,7 @@ class JSV8BreakIterator : public JSObject {
static String BreakType(Isolate* isolate,
Handle<JSV8BreakIterator> break_iterator);
- enum class Type { CHARACTER, WORD, SENTENCE, LINE, COUNT };
+ enum class Type { CHARACTER, WORD, SENTENCE, LINE };
inline void set_type(Type type);
inline Type type() const;
@@ -69,23 +70,12 @@ class JSV8BreakIterator : public JSObject {
DECL_ACCESSORS(bound_current, Object)
DECL_ACCESSORS(bound_break_type, Object)
-// Layout description.
-#define BREAK_ITERATOR_FIELDS(V) \
- /* Pointer fields. */ \
- V(kLocaleOffset, kTaggedSize) \
- V(kTypeOffset, kTaggedSize) \
- V(kBreakIteratorOffset, kTaggedSize) \
- V(kUnicodeStringOffset, kTaggedSize) \
- V(kBoundAdoptTextOffset, kTaggedSize) \
- V(kBoundFirstOffset, kTaggedSize) \
- V(kBoundNextOffset, kTaggedSize) \
- V(kBoundCurrentOffset, kTaggedSize) \
- V(kBoundBreakTypeOffset, kTaggedSize) \
- /* Total Size */ \
- V(kSize, 0)
-
- DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, BREAK_ITERATOR_FIELDS)
-#undef BREAK_ITERATOR_FIELDS
+ // Layout description.
+ DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
+ TORQUE_GENERATED_JSV8BREAK_ITERATOR_FIELDS)
+
+ private:
+ DECL_INT_ACCESSORS(raw_type)
OBJECT_CONSTRUCTORS(JSV8BreakIterator, JSObject);
};
diff --git a/deps/v8/src/objects/js-collator-inl.h b/deps/v8/src/objects/js-collator-inl.h
index e82351993d..a8d3893316 100644
--- a/deps/v8/src/objects/js-collator-inl.h
+++ b/deps/v8/src/objects/js-collator-inl.h
@@ -20,7 +20,7 @@ namespace internal {
OBJECT_CONSTRUCTORS_IMPL(JSCollator, JSObject)
-ACCESSORS(JSCollator, icu_collator, Managed<icu::Collator>, kICUCollatorOffset)
+ACCESSORS(JSCollator, icu_collator, Managed<icu::Collator>, kIcuCollatorOffset)
ACCESSORS(JSCollator, bound_compare, Object, kBoundCompareOffset)
CAST_ACCESSOR(JSCollator)
diff --git a/deps/v8/src/objects/js-collator.cc b/deps/v8/src/objects/js-collator.cc
index 4a1e857403..0413e2acd1 100644
--- a/deps/v8/src/objects/js-collator.cc
+++ b/deps/v8/src/objects/js-collator.cc
@@ -15,7 +15,9 @@
#include "unicode/locid.h"
#include "unicode/strenum.h"
#include "unicode/ucol.h"
+#include "unicode/udata.h"
#include "unicode/uloc.h"
+#include "unicode/utypes.h"
namespace v8 {
namespace internal {
@@ -239,10 +241,9 @@ void SetCaseFirstOption(icu::Collator* icu_collator,
} // anonymous namespace
// static
-MaybeHandle<JSCollator> JSCollator::Initialize(Isolate* isolate,
- Handle<JSCollator> collator,
- Handle<Object> locales,
- Handle<Object> options_obj) {
+MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map,
+ Handle<Object> locales,
+ Handle<Object> options_obj) {
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> maybe_requested_locales =
Intl::CanonicalizeLocaleList(isolate, locales);
@@ -465,15 +466,31 @@ MaybeHandle<JSCollator> JSCollator::Initialize(Isolate* isolate,
Handle<Managed<icu::Collator>> managed_collator =
Managed<icu::Collator>::FromUniquePtr(isolate, 0,
std::move(icu_collator));
+
+ // Now all properties are ready, so we can allocate the result object.
+ Handle<JSCollator> collator = Handle<JSCollator>::cast(
+ isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
+ DisallowHeapAllocation no_gc;
collator->set_icu_collator(*managed_collator);
// 29. Return collator.
return collator;
}
+namespace {
+
+struct CheckColl {
+ static const char* key() { return nullptr; }
+#define U_ICUDATA_COLL U_ICUDATA_NAME U_TREE_SEPARATOR_STRING "coll"
+ static const char* path() { return U_ICUDATA_COLL; }
+#undef U_ICUDATA_COLL
+};
+
+} // namespace
+
const std::set<std::string>& JSCollator::GetAvailableLocales() {
- static base::LazyInstance<Intl::AvailableLocales<icu::Collator>>::type
- available_locales = LAZY_INSTANCE_INITIALIZER;
+ static base::LazyInstance<Intl::AvailableLocales<icu::Collator, CheckColl>>::
+ type available_locales = LAZY_INSTANCE_INITIALIZER;
return available_locales.Pointer()->Get();
}
diff --git a/deps/v8/src/objects/js-collator.h b/deps/v8/src/objects/js-collator.h
index 2bedbf811a..e9114afeb1 100644
--- a/deps/v8/src/objects/js-collator.h
+++ b/deps/v8/src/objects/js-collator.h
@@ -32,8 +32,8 @@ namespace internal {
class JSCollator : public JSObject {
public:
// ecma402/#sec-initializecollator
- V8_WARN_UNUSED_RESULT static MaybeHandle<JSCollator> Initialize(
- Isolate* isolate, Handle<JSCollator> collator, Handle<Object> locales,
+ V8_WARN_UNUSED_RESULT static MaybeHandle<JSCollator> New(
+ Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<Object> options);
// ecma402/#sec-intl.collator.prototype.resolvedoptions
@@ -47,14 +47,8 @@ class JSCollator : public JSObject {
DECL_VERIFIER(JSCollator)
// Layout description.
-#define JS_COLLATOR_FIELDS(V) \
- V(kICUCollatorOffset, kTaggedSize) \
- V(kBoundCompareOffset, kTaggedSize) \
- /* Total size. */ \
- V(kSize, 0)
-
- DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_COLLATOR_FIELDS)
-#undef JS_COLLATOR_FIELDS
+ DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
+ TORQUE_GENERATED_JSCOLLATOR_FIELDS)
DECL_ACCESSORS(icu_collator, Managed<icu::Collator>)
DECL_ACCESSORS(bound_compare, Object)
diff --git a/deps/v8/src/objects/js-collection-iterator.h b/deps/v8/src/objects/js-collection-iterator.h
index 4952f04a72..c002294b01 100644
--- a/deps/v8/src/objects/js-collection-iterator.h
+++ b/deps/v8/src/objects/js-collection-iterator.h
@@ -25,6 +25,7 @@ class JSCollectionIterator : public JSObject {
DECL_ACCESSORS(index, Object)
void JSCollectionIteratorPrint(std::ostream& os, const char* name);
+ DECL_VERIFIER(JSCollectionIterator)
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
TORQUE_GENERATED_JSCOLLECTION_ITERATOR_FIELDS)
diff --git a/deps/v8/src/objects/js-collection.h b/deps/v8/src/objects/js-collection.h
index 6dfde352ca..0a856ca062 100644
--- a/deps/v8/src/objects/js-collection.h
+++ b/deps/v8/src/objects/js-collection.h
@@ -30,6 +30,8 @@ class JSCollection : public JSObject {
static const int kAddFunctionDescriptorIndex = 3;
+ DECL_VERIFIER(JSCollection)
+
OBJECT_CONSTRUCTORS(JSCollection, JSObject);
};
@@ -114,6 +116,8 @@ class JSWeakCollection : public JSObject {
static Handle<JSArray> GetEntries(Handle<JSWeakCollection> holder,
int max_entries);
+ DECL_VERIFIER(JSWeakCollection)
+
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
TORQUE_GENERATED_JSWEAK_COLLECTION_FIELDS)
diff --git a/deps/v8/src/objects/js-date-time-format.cc b/deps/v8/src/objects/js-date-time-format.cc
index 8730e0a39b..db7ba27312 100644
--- a/deps/v8/src/objects/js-date-time-format.cc
+++ b/deps/v8/src/objects/js-date-time-format.cc
@@ -56,13 +56,13 @@ class PatternItem {
std::vector<const char*> allowed_values;
};
-static const std::vector<PatternItem> BuildPatternItems() {
+static std::vector<PatternItem> BuildPatternItems() {
const std::vector<const char*> kLongShort = {"long", "short"};
const std::vector<const char*> kNarrowLongShort = {"narrow", "long", "short"};
const std::vector<const char*> k2DigitNumeric = {"2-digit", "numeric"};
const std::vector<const char*> kNarrowLongShort2DigitNumeric = {
"narrow", "long", "short", "2-digit", "numeric"};
- const std::vector<PatternItem> kPatternItems = {
+ std::vector<PatternItem> items = {
PatternItem("weekday",
{{"EEEEE", "narrow"},
{"EEEE", "long"},
@@ -75,38 +75,59 @@ static const std::vector<PatternItem> BuildPatternItems() {
{{"GGGGG", "narrow"}, {"GGGG", "long"}, {"GGG", "short"}},
kNarrowLongShort),
PatternItem("year", {{"yy", "2-digit"}, {"y", "numeric"}},
- k2DigitNumeric),
- // Sometimes we get L instead of M for month - standalone name.
- PatternItem("month",
- {{"MMMMM", "narrow"},
- {"MMMM", "long"},
- {"MMM", "short"},
- {"MM", "2-digit"},
- {"M", "numeric"},
- {"LLLLL", "narrow"},
- {"LLLL", "long"},
- {"LLL", "short"},
- {"LL", "2-digit"},
- {"L", "numeric"}},
- kNarrowLongShort2DigitNumeric),
- PatternItem("day", {{"dd", "2-digit"}, {"d", "numeric"}}, k2DigitNumeric),
- PatternItem("hour",
- {{"HH", "2-digit"},
- {"H", "numeric"},
- {"hh", "2-digit"},
- {"h", "numeric"},
- {"kk", "2-digit"},
- {"k", "numeric"},
- {"KK", "2-digit"},
- {"K", "numeric"}},
- k2DigitNumeric),
- PatternItem("minute", {{"mm", "2-digit"}, {"m", "numeric"}},
- k2DigitNumeric),
- PatternItem("second", {{"ss", "2-digit"}, {"s", "numeric"}},
- k2DigitNumeric),
- PatternItem("timeZoneName", {{"zzzz", "long"}, {"z", "short"}},
- kLongShort)};
- return kPatternItems;
+ k2DigitNumeric)};
+ if (FLAG_harmony_intl_dateformat_quarter) {
+ items.push_back(PatternItem("quarter",
+ {{"QQQQQ", "narrow"},
+ {"QQQQ", "long"},
+ {"QQQ", "short"},
+ {"qqqqq", "narrow"},
+ {"qqqq", "long"},
+ {"qqq", "short"}},
+ kNarrowLongShort));
+ }
+ // Sometimes we get L instead of M for month - standalone name.
+ items.push_back(PatternItem("month",
+ {{"MMMMM", "narrow"},
+ {"MMMM", "long"},
+ {"MMM", "short"},
+ {"MM", "2-digit"},
+ {"M", "numeric"},
+ {"LLLLL", "narrow"},
+ {"LLLL", "long"},
+ {"LLL", "short"},
+ {"LL", "2-digit"},
+ {"L", "numeric"}},
+ kNarrowLongShort2DigitNumeric));
+ items.push_back(PatternItem("day", {{"dd", "2-digit"}, {"d", "numeric"}},
+ k2DigitNumeric));
+ if (FLAG_harmony_intl_dateformat_day_period) {
+ items.push_back(PatternItem("dayPeriod",
+ {{"BBBBB", "narrow"},
+ {"bbbbb", "narrow"},
+ {"BBBB", "long"},
+ {"bbbb", "long"},
+ {"B", "short"},
+ {"b", "short"}},
+ kNarrowLongShort));
+ }
+ items.push_back(PatternItem("hour",
+ {{"HH", "2-digit"},
+ {"H", "numeric"},
+ {"hh", "2-digit"},
+ {"h", "numeric"},
+ {"kk", "2-digit"},
+ {"k", "numeric"},
+ {"KK", "2-digit"},
+ {"K", "numeric"}},
+ k2DigitNumeric));
+ items.push_back(PatternItem("minute", {{"mm", "2-digit"}, {"m", "numeric"}},
+ k2DigitNumeric));
+ items.push_back(PatternItem("second", {{"ss", "2-digit"}, {"s", "numeric"}},
+ k2DigitNumeric));
+ items.push_back(PatternItem("timeZoneName",
+ {{"zzzz", "long"}, {"z", "short"}}, kLongShort));
+ return items;
}
class PatternItems {
@@ -348,6 +369,16 @@ Handle<String> DateTimeStyleAsString(Isolate* isolate,
}
}
+int FractionalSecondDigitsFromPattern(const std::string& pattern) {
+ int result = 0;
+ for (size_t i = 0; i < pattern.length() && result < 3; i++) {
+ if (pattern[i] == 'S') {
+ result++;
+ }
+ }
+ return result;
+}
+
} // namespace
// ecma402 #sec-intl.datetimeformat.prototype.resolvedoptions
@@ -532,6 +563,13 @@ MaybeHandle<JSObject> JSDateTimeFormat::ResolvedOptions(
Just(kDontThrow))
.FromJust());
}
+ if (FLAG_harmony_intl_dateformat_fractional_second_digits) {
+ int fsd = FractionalSecondDigitsFromPattern(pattern);
+ CHECK(JSReceiver::CreateDataProperty(
+ isolate, options, factory->fractionalSecondDigits_string(),
+ factory->NewNumberFromInt(fsd), Just(kDontThrow))
+ .FromJust());
+ }
return options;
}
@@ -643,17 +681,14 @@ MaybeHandle<String> JSDateTimeFormat::ToLocaleDateTime(
JSFunction::cast(
isolate->context().native_context().intl_date_time_format_function()),
isolate);
- Handle<JSObject> obj;
+ Handle<Map> map;
ASSIGN_RETURN_ON_EXCEPTION(
- isolate, obj,
- JSObject::New(constructor, constructor, Handle<AllocationSite>::null()),
- String);
+ isolate, map,
+ JSFunction::GetDerivedMap(isolate, constructor, constructor), String);
Handle<JSDateTimeFormat> date_time_format;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, date_time_format,
- JSDateTimeFormat::Initialize(isolate, Handle<JSDateTimeFormat>::cast(obj),
- locales, internal_options),
- String);
+ JSDateTimeFormat::New(isolate, map, locales, internal_options), String);
if (can_cache) {
isolate->set_icu_object_in_cache(
@@ -669,27 +704,23 @@ MaybeHandle<String> JSDateTimeFormat::ToLocaleDateTime(
namespace {
Maybe<bool> IsPropertyUndefined(Isolate* isolate, Handle<JSObject> options,
- const char* property) {
- Factory* factory = isolate->factory();
+ Handle<String> property) {
// i. Let prop be the property name.
// ii. Let value be ? Get(options, prop).
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
- isolate, value,
- Object::GetPropertyOrElement(
- isolate, options, factory->NewStringFromAsciiChecked(property)),
+ isolate, value, Object::GetPropertyOrElement(isolate, options, property),
Nothing<bool>());
return Just(value->IsUndefined(isolate));
}
Maybe<bool> NeedsDefault(Isolate* isolate, Handle<JSObject> options,
- const std::vector<std::string>& props) {
+ const std::vector<Handle<String>>& props) {
bool needs_default = true;
for (const auto& prop : props) {
// i. Let prop be the property name.
// ii. Let value be ? Get(options, prop)
- Maybe<bool> maybe_undefined =
- IsPropertyUndefined(isolate, options, prop.c_str());
+ Maybe<bool> maybe_undefined = IsPropertyUndefined(isolate, options, prop);
MAYBE_RETURN(maybe_undefined, Nothing<bool>());
// iii. If value is not undefined, let needDefaults be false.
if (!maybe_undefined.FromJust()) {
@@ -741,8 +772,15 @@ MaybeHandle<JSObject> JSDateTimeFormat::ToDateTimeOptions(
// 4. If required is "date" or "any", then
if (required == RequiredOption::kAny || required == RequiredOption::kDate) {
- // a. For each of the property names "weekday", "year", "month", "day", do
- const std::vector<std::string> list({"weekday", "year", "month", "day"});
+ // a. For each of the property names "weekday", "year", "quarter", "month",
+ // "day", do
+ std::vector<Handle<String>> list(
+ {factory->weekday_string(), factory->year_string()});
+ if (FLAG_harmony_intl_dateformat_quarter) {
+ list.push_back(factory->quarter_string());
+ }
+ list.push_back(factory->month_string());
+ list.push_back(factory->day_string());
Maybe<bool> maybe_needs_default = NeedsDefault(isolate, options, list);
MAYBE_RETURN(maybe_needs_default, Handle<JSObject>());
needs_default = maybe_needs_default.FromJust();
@@ -750,8 +788,18 @@ MaybeHandle<JSObject> JSDateTimeFormat::ToDateTimeOptions(
// 5. If required is "time" or "any", then
if (required == RequiredOption::kAny || required == RequiredOption::kTime) {
- // a. For each of the property names "hour", "minute", "second", do
- const std::vector<std::string> list({"hour", "minute", "second"});
+ // a. For each of the property names "dayPeriod", "hour", "minute",
+ // "second", "fractionalSecondDigits", do
+ std::vector<Handle<String>> list;
+ if (FLAG_harmony_intl_dateformat_day_period) {
+ list.push_back(factory->dayPeriod_string());
+ }
+ list.push_back(factory->hour_string());
+ list.push_back(factory->minute_string());
+ list.push_back(factory->second_string());
+ if (FLAG_harmony_intl_dateformat_fractional_second_digits) {
+ list.push_back(factory->fractionalSecondDigits_string());
+ }
Maybe<bool> maybe_needs_default = NeedsDefault(isolate, options, list);
MAYBE_RETURN(maybe_needs_default, Handle<JSObject>());
needs_default &= maybe_needs_default.FromJust();
@@ -890,7 +938,7 @@ icu::Calendar* CreateCalendar(Isolate* isolate, const icu::Locale& icu_locale,
std::unique_ptr<icu::SimpleDateFormat> CreateICUDateFormat(
const icu::Locale& icu_locale, const icu::UnicodeString& skeleton,
- icu::DateTimePatternGenerator& generator) {
+ icu::DateTimePatternGenerator& generator) { // NOLINT(runtime/references)
// See https://github.com/tc39/ecma402/issues/225 . The best pattern
// generation needs to be done in the base locale according to the
// current spec however odd it may be. See also crbug.com/826549 .
@@ -920,9 +968,9 @@ std::unique_ptr<icu::SimpleDateFormat> CreateICUDateFormat(
class DateFormatCache {
public:
- icu::SimpleDateFormat* Create(const icu::Locale& icu_locale,
- const icu::UnicodeString& skeleton,
- icu::DateTimePatternGenerator& generator) {
+ icu::SimpleDateFormat* Create(
+ const icu::Locale& icu_locale, const icu::UnicodeString& skeleton,
+ icu::DateTimePatternGenerator& generator) { // NOLINT(runtime/references)
std::string key;
skeleton.toUTF8String<std::string>(key);
key += ":";
@@ -951,7 +999,7 @@ class DateFormatCache {
std::unique_ptr<icu::SimpleDateFormat> CreateICUDateFormatFromCache(
const icu::Locale& icu_locale, const icu::UnicodeString& skeleton,
- icu::DateTimePatternGenerator& generator) {
+ icu::DateTimePatternGenerator& generator) { // NOLINT(runtime/references)
static base::LazyInstance<DateFormatCache>::type cache =
LAZY_INSTANCE_INITIALIZER;
return std::unique_ptr<icu::SimpleDateFormat>(
@@ -1087,7 +1135,8 @@ icu::UnicodeString ReplaceSkeleton(const icu::UnicodeString input,
std::unique_ptr<icu::SimpleDateFormat> DateTimeStylePattern(
JSDateTimeFormat::DateTimeStyle date_style,
JSDateTimeFormat::DateTimeStyle time_style, const icu::Locale& icu_locale,
- Intl::HourCycle hc, icu::DateTimePatternGenerator& generator) {
+ Intl::HourCycle hc,
+ icu::DateTimePatternGenerator& generator) { // NOLINT(runtime/references)
std::unique_ptr<icu::SimpleDateFormat> result;
if (date_style != JSDateTimeFormat::DateTimeStyle::kUndefined) {
if (time_style != JSDateTimeFormat::DateTimeStyle::kUndefined) {
@@ -1156,10 +1205,9 @@ class DateTimePatternGeneratorCache {
enum FormatMatcherOption { kBestFit, kBasic };
// ecma402/#sec-initializedatetimeformat
-MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
- Isolate* isolate, Handle<JSDateTimeFormat> date_time_format,
- Handle<Object> locales, Handle<Object> input_options) {
- date_time_format->set_flags(0);
+MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
+ Isolate* isolate, Handle<Map> map, Handle<Object> locales,
+ Handle<Object> input_options) {
Factory* factory = isolate->factory();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> maybe_requested_locales =
@@ -1347,7 +1395,6 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
}
}
}
- date_time_format->set_hour_cycle(hc);
DateTimeStyle date_style = DateTimeStyle::kUndefined;
DateTimeStyle time_style = DateTimeStyle::kUndefined;
@@ -1367,9 +1414,6 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
// 29. If dateStyle is not undefined, set dateTimeFormat.[[DateStyle]] to
// dateStyle.
date_style = maybe_date_style.FromJust();
- if (date_style != DateTimeStyle::kUndefined) {
- date_time_format->set_date_style(date_style);
- }
// 30. Let timeStyle be ? GetOption(options, "timeStyle", "string", «
// "full", "long", "medium", "short" »).
@@ -1385,9 +1429,6 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
// 31. If timeStyle is not undefined, set dateTimeFormat.[[TimeStyle]] to
// timeStyle.
time_style = maybe_time_style.FromJust();
- if (time_style != DateTimeStyle::kUndefined) {
- date_time_format->set_time_style(time_style);
- }
// 32. If dateStyle or timeStyle are not undefined, then
if (date_style != DateTimeStyle::kUndefined ||
@@ -1419,6 +1460,16 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
skeleton += item.map.find(input.get())->second;
}
}
+ if (FLAG_harmony_intl_dateformat_fractional_second_digits) {
+ Maybe<int> maybe_fsd = Intl::GetNumberOption(
+ isolate, options, factory->fractionalSecondDigits_string(), 0, 3, 0);
+ MAYBE_RETURN(maybe_fsd, MaybeHandle<JSDateTimeFormat>());
+ // Convert fractionalSecondDigits to skeleton.
+ int fsd = maybe_fsd.FromJust();
+ for (int i = 0; i < fsd; i++) {
+ skeleton += "S";
+ }
+ }
enum FormatMatcherOption { kBestFit, kBasic };
// We implement only best fit algorithm, but still need to check
@@ -1451,7 +1502,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
// g. If dateTimeFormat.[[Hour]] is not undefined, then
if (!has_hour_option) {
// h. Else, i. Set dateTimeFormat.[[HourCycle]] to undefined.
- date_time_format->set_hour_cycle(Intl::HourCycle::kUndefined);
+ hc = Intl::HourCycle::kUndefined;
}
}
@@ -1477,8 +1528,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
maybe_hour_cycle.FromJust() != Intl::HourCycle::kUndefined) {
auto hc_extension_it = r.extensions.find("hc");
if (hc_extension_it != r.extensions.end()) {
- if (date_time_format->hour_cycle() !=
- Intl::ToHourCycle(hc_extension_it->second.c_str())) {
+ if (hc != Intl::ToHourCycle(hc_extension_it->second.c_str())) {
// Remove -hc- if it does not agree with what we used.
UErrorCode status = U_ZERO_ERROR;
icu_locale.setUnicodeKeywordValue("hc", nullptr, status);
@@ -1490,16 +1540,28 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
Handle<Managed<icu::Locale>> managed_locale =
Managed<icu::Locale>::FromRawPtr(isolate, 0, icu_locale.clone());
- date_time_format->set_icu_locale(*managed_locale);
Handle<Managed<icu::SimpleDateFormat>> managed_format =
Managed<icu::SimpleDateFormat>::FromUniquePtr(isolate, 0,
std::move(icu_date_format));
- date_time_format->set_icu_simple_date_format(*managed_format);
Handle<Managed<icu::DateIntervalFormat>> managed_interval_format =
Managed<icu::DateIntervalFormat>::FromRawPtr(isolate, 0, nullptr);
- date_time_format->set_icu_date_interval_format(*managed_interval_format);
+ // Now all properties are ready, so we can allocate the result object.
+ Handle<JSDateTimeFormat> date_time_format = Handle<JSDateTimeFormat>::cast(
+ isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
+ DisallowHeapAllocation no_gc;
+ date_time_format->set_flags(0);
+ date_time_format->set_hour_cycle(hc);
+ if (date_style != DateTimeStyle::kUndefined) {
+ date_time_format->set_date_style(date_style);
+ }
+ if (time_style != DateTimeStyle::kUndefined) {
+ date_time_format->set_time_style(time_style);
+ }
+ date_time_format->set_icu_locale(*managed_locale);
+ date_time_format->set_icu_simple_date_format(*managed_format);
+ date_time_format->set_icu_date_interval_format(*managed_interval_format);
return date_time_format;
}
@@ -1516,6 +1578,9 @@ Handle<String> IcuDateFieldIdToDateType(int32_t field_id, Isolate* isolate) {
case UDAT_EXTENDED_YEAR_FIELD:
case UDAT_YEAR_NAME_FIELD:
return isolate->factory()->year_string();
+ case UDAT_QUARTER_FIELD:
+ case UDAT_STANDALONE_QUARTER_FIELD:
+ return isolate->factory()->quarter_string();
case UDAT_MONTH_FIELD:
case UDAT_STANDALONE_MONTH_FIELD:
return isolate->factory()->month_string();
@@ -1535,6 +1600,8 @@ Handle<String> IcuDateFieldIdToDateType(int32_t field_id, Isolate* isolate) {
case UDAT_STANDALONE_DAY_FIELD:
return isolate->factory()->weekday_string();
case UDAT_AM_PM_FIELD:
+ case UDAT_AM_PM_MIDNIGHT_NOON_FIELD:
+ case UDAT_FLEXIBLE_DAY_PERIOD_FIELD:
return isolate->factory()->dayPeriod_string();
case UDAT_TIMEZONE_FIELD:
case UDAT_TIMEZONE_RFC_FIELD:
@@ -1546,6 +1613,8 @@ Handle<String> IcuDateFieldIdToDateType(int32_t field_id, Isolate* isolate) {
return isolate->factory()->timeZoneName_string();
case UDAT_ERA_FIELD:
return isolate->factory()->era_string();
+ case UDAT_FRACTIONAL_SECOND_FIELD:
+ return isolate->factory()->fractionalSecond_string();
default:
// Other UDAT_*_FIELD's cannot show up because there is no way to specify
// them via options of Intl.DateTimeFormat.
diff --git a/deps/v8/src/objects/js-date-time-format.h b/deps/v8/src/objects/js-date-time-format.h
index 664ccdcdf7..f4a8ccc8f5 100644
--- a/deps/v8/src/objects/js-date-time-format.h
+++ b/deps/v8/src/objects/js-date-time-format.h
@@ -32,9 +32,9 @@ namespace internal {
class JSDateTimeFormat : public JSObject {
public:
- V8_WARN_UNUSED_RESULT static MaybeHandle<JSDateTimeFormat> Initialize(
- Isolate* isolate, Handle<JSDateTimeFormat> date_time_format,
- Handle<Object> locales, Handle<Object> options);
+ V8_WARN_UNUSED_RESULT static MaybeHandle<JSDateTimeFormat> New(
+ Isolate* isolate, Handle<Map> map, Handle<Object> locales,
+ Handle<Object> options);
V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSDateTimeFormat> date_time_format);
diff --git a/deps/v8/src/objects/js-list-format-inl.h b/deps/v8/src/objects/js-list-format-inl.h
index 96e61c2205..6a1529ad33 100644
--- a/deps/v8/src/objects/js-list-format-inl.h
+++ b/deps/v8/src/objects/js-list-format-inl.h
@@ -27,7 +27,7 @@ ACCESSORS(JSListFormat, icu_formatter, Managed<icu::ListFormatter>,
SMI_ACCESSORS(JSListFormat, flags, kFlagsOffset)
inline void JSListFormat::set_style(Style style) {
- DCHECK_GT(Style::COUNT, style);
+ DCHECK_GE(StyleBits::kMax, style);
int hints = flags();
hints = StyleBits::update(hints, style);
set_flags(hints);
@@ -38,7 +38,7 @@ inline JSListFormat::Style JSListFormat::style() const {
}
inline void JSListFormat::set_type(Type type) {
- DCHECK_GT(Type::COUNT, type);
+ DCHECK_GE(TypeBits::kMax, type);
int hints = flags();
hints = TypeBits::update(hints, type);
set_flags(hints);
diff --git a/deps/v8/src/objects/js-list-format.cc b/deps/v8/src/objects/js-list-format.cc
index 84691194ec..4f303b1874 100644
--- a/deps/v8/src/objects/js-list-format.cc
+++ b/deps/v8/src/objects/js-list-format.cc
@@ -50,8 +50,6 @@ const char* GetIcuStyleString(JSListFormat::Style style,
return kStandardShort;
case JSListFormat::Style::NARROW:
return kStandardNarrow;
- case JSListFormat::Style::COUNT:
- UNREACHABLE();
}
case JSListFormat::Type::DISJUNCTION:
switch (style) {
@@ -61,8 +59,6 @@ const char* GetIcuStyleString(JSListFormat::Style style,
return kOrShort;
case JSListFormat::Style::NARROW:
return kOrNarrow;
- case JSListFormat::Style::COUNT:
- UNREACHABLE();
}
case JSListFormat::Type::UNIT:
switch (style) {
@@ -72,12 +68,9 @@ const char* GetIcuStyleString(JSListFormat::Style style,
return kUnitShort;
case JSListFormat::Style::NARROW:
return kUnitNarrow;
- case JSListFormat::Style::COUNT:
- UNREACHABLE();
}
- case JSListFormat::Type::COUNT:
- UNREACHABLE();
}
+ UNREACHABLE();
}
} // namespace
@@ -114,11 +107,9 @@ JSListFormat::Type get_type(const char* str) {
UNREACHABLE();
}
-MaybeHandle<JSListFormat> JSListFormat::Initialize(
- Isolate* isolate, Handle<JSListFormat> list_format, Handle<Object> locales,
- Handle<Object> input_options) {
- list_format->set_flags(0);
-
+MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map,
+ Handle<Object> locales,
+ Handle<Object> input_options) {
Handle<JSReceiver> options;
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> maybe_requested_locales =
@@ -156,11 +147,8 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize(
Intl::ResolvedLocale r =
Intl::ResolveLocale(isolate, JSListFormat::GetAvailableLocales(),
requested_locales, matcher, {});
-
- // 11. Set listFormat.[[Locale]] to r.[[Locale]].
Handle<String> locale_str =
isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
- list_format->set_locale(*locale_str);
// 12. Let t be GetOption(options, "type", "string", «"conjunction",
// "disjunction", "unit"», "conjunction").
@@ -171,9 +159,6 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize(
MAYBE_RETURN(maybe_type, MaybeHandle<JSListFormat>());
Type type_enum = maybe_type.FromJust();
- // 13. Set listFormat.[[Type]] to t.
- list_format->set_type(type_enum);
-
// 14. Let s be ? GetOption(options, "style", "string",
// «"long", "short", "narrow"», "long").
Maybe<Style> maybe_style = Intl::GetStringOption<Style>(
@@ -182,9 +167,6 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize(
MAYBE_RETURN(maybe_style, MaybeHandle<JSListFormat>());
Style style_enum = maybe_style.FromJust();
- // 15. Set listFormat.[[Style]] to s.
- list_format->set_style(style_enum);
-
icu::Locale icu_locale = r.icu_locale;
UErrorCode status = U_ZERO_ERROR;
icu::ListFormatter* formatter = icu::ListFormatter::createInstance(
@@ -198,7 +180,22 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize(
Handle<Managed<icu::ListFormatter>> managed_formatter =
Managed<icu::ListFormatter>::FromRawPtr(isolate, 0, formatter);
+ // Now all properties are ready, so we can allocate the result object.
+ Handle<JSListFormat> list_format = Handle<JSListFormat>::cast(
+ isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
+ DisallowHeapAllocation no_gc;
+ list_format->set_flags(0);
list_format->set_icu_formatter(*managed_formatter);
+
+ // 11. Set listFormat.[[Locale]] to r.[[Locale]].
+ list_format->set_locale(*locale_str);
+
+ // 13. Set listFormat.[[Type]] to t.
+ list_format->set_type(type_enum);
+
+ // 15. Set listFormat.[[Style]] to s.
+ list_format->set_style(style_enum);
+
return list_format;
}
@@ -234,9 +231,8 @@ Handle<String> JSListFormat::StyleAsString() const {
return GetReadOnlyRoots().short_string_handle();
case Style::NARROW:
return GetReadOnlyRoots().narrow_string_handle();
- case Style::COUNT:
- UNREACHABLE();
}
+ UNREACHABLE();
}
Handle<String> JSListFormat::TypeAsString() const {
@@ -247,9 +243,8 @@ Handle<String> JSListFormat::TypeAsString() const {
return GetReadOnlyRoots().disjunction_string_handle();
case Type::UNIT:
return GetReadOnlyRoots().unit_string_handle();
- case Type::COUNT:
- UNREACHABLE();
}
+ UNREACHABLE();
}
namespace {
@@ -375,11 +370,20 @@ MaybeHandle<JSArray> JSListFormat::FormatListToParts(
FormattedListToJSArray);
}
+namespace {
+
+struct CheckListPattern {
+ static const char* key() { return "listPattern"; }
+ static const char* path() { return nullptr; }
+};
+
+} // namespace
+
const std::set<std::string>& JSListFormat::GetAvailableLocales() {
- // Since ListFormatter does not have a method to list all supported
- // locales, use the one in icu::Locale per comments in
- // ICU FR at https://unicode-org.atlassian.net/browse/ICU-20015
- return Intl::GetAvailableLocalesForLocale();
+ static base::LazyInstance<
+ Intl::AvailableLocales<icu::Locale, CheckListPattern>>::type
+ available_locales = LAZY_INSTANCE_INITIALIZER;
+ return available_locales.Pointer()->Get();
}
} // namespace internal
diff --git a/deps/v8/src/objects/js-list-format.h b/deps/v8/src/objects/js-list-format.h
index 0284d05d42..df937722e6 100644
--- a/deps/v8/src/objects/js-list-format.h
+++ b/deps/v8/src/objects/js-list-format.h
@@ -30,11 +30,11 @@ namespace internal {
class JSListFormat : public JSObject {
public:
- // Initializes relative time format object with properties derived from input
+ // Creates relative time format object with properties derived from input
// locales and options.
- static MaybeHandle<JSListFormat> Initialize(
- Isolate* isolate, Handle<JSListFormat> list_format_holder,
- Handle<Object> locales, Handle<Object> options);
+ static MaybeHandle<JSListFormat> New(Isolate* isolate, Handle<Map> map,
+ Handle<Object> locales,
+ Handle<Object> options);
static Handle<JSObject> ResolvedOptions(Isolate* isolate,
Handle<JSListFormat> format_holder);
@@ -64,10 +64,9 @@ class JSListFormat : public JSObject {
//
// ecma402/#sec-properties-of-intl-listformat-instances
enum class Style {
- LONG, // Everything spelled out.
- SHORT, // Abbreviations used when possible.
- NARROW, // Use the shortest possible form.
- COUNT
+ LONG, // Everything spelled out.
+ SHORT, // Abbreviations used when possible.
+ NARROW // Use the shortest possible form.
};
inline void set_style(Style style);
inline Style style() const;
@@ -78,8 +77,7 @@ class JSListFormat : public JSObject {
enum class Type {
CONJUNCTION, // for "and"-based lists (e.g., "A, B and C")
DISJUNCTION, // for "or"-based lists (e.g., "A, B or C"),
- UNIT, // for lists of values with units (e.g., "5 pounds, 12 ounces").
- COUNT
+ UNIT // for lists of values with units (e.g., "5 pounds, 12 ounces").
};
inline void set_type(Type type);
inline Type type() const;
diff --git a/deps/v8/src/objects/js-locale.cc b/deps/v8/src/objects/js-locale.cc
index 509f9a3069..4a66ea9eca 100644
--- a/deps/v8/src/objects/js-locale.cc
+++ b/deps/v8/src/objects/js-locale.cc
@@ -313,10 +313,9 @@ Maybe<bool> ApplyOptionsToTag(Isolate* isolate, Handle<String> tag,
} // namespace
-MaybeHandle<JSLocale> JSLocale::Initialize(Isolate* isolate,
- Handle<JSLocale> locale,
- Handle<String> locale_str,
- Handle<JSReceiver> options) {
+MaybeHandle<JSLocale> JSLocale::New(Isolate* isolate, Handle<Map> map,
+ Handle<String> locale_str,
+ Handle<JSReceiver> options) {
icu::LocaleBuilder builder;
Maybe<bool> maybe_apply =
ApplyOptionsToTag(isolate, locale_str, options, &builder);
@@ -341,8 +340,12 @@ MaybeHandle<JSLocale> JSLocale::Initialize(Isolate* isolate,
// 31. Set locale.[[Locale]] to r.[[locale]].
Handle<Managed<icu::Locale>> managed_locale =
Managed<icu::Locale>::FromRawPtr(isolate, 0, icu_locale.clone());
- locale->set_icu_locale(*managed_locale);
+ // Now all properties are ready, so we can allocate the result object.
+ Handle<JSLocale> locale = Handle<JSLocale>::cast(
+ isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
+ DisallowHeapAllocation no_gc;
+ locale->set_icu_locale(*managed_locale);
return locale;
}
diff --git a/deps/v8/src/objects/js-locale.h b/deps/v8/src/objects/js-locale.h
index 1a833e0e18..e1806e6b7f 100644
--- a/deps/v8/src/objects/js-locale.h
+++ b/deps/v8/src/objects/js-locale.h
@@ -27,12 +27,11 @@ namespace internal {
class JSLocale : public JSObject {
public:
- // Initializes locale object with properties derived from input locale string
+ // Creates locale object with properties derived from input locale string
// and options.
- static MaybeHandle<JSLocale> Initialize(Isolate* isolate,
- Handle<JSLocale> locale_holder,
- Handle<String> locale,
- Handle<JSReceiver> options);
+ static MaybeHandle<JSLocale> New(Isolate* isolate, Handle<Map> map,
+ Handle<String> locale,
+ Handle<JSReceiver> options);
static Handle<String> Maximize(Isolate* isolate, String locale);
static Handle<String> Minimize(Isolate* isolate, String locale);
diff --git a/deps/v8/src/objects/js-number-format-inl.h b/deps/v8/src/objects/js-number-format-inl.h
index bd76dfe556..afdfef89f2 100644
--- a/deps/v8/src/objects/js-number-format-inl.h
+++ b/deps/v8/src/objects/js-number-format-inl.h
@@ -66,6 +66,17 @@ inline void JSNumberFormat::set_maximum_fraction_digits(int digits) {
set_flags(hints);
}
+inline void JSNumberFormat::set_style(Style style) {
+ DCHECK_GE(StyleBits::kMax, style);
+ int hints = flags();
+ hints = StyleBits::update(hints, style);
+ set_flags(hints);
+}
+
+inline JSNumberFormat::Style JSNumberFormat::style() const {
+ return StyleBits::decode(flags());
+}
+
CAST_ACCESSOR(JSNumberFormat)
} // namespace internal
diff --git a/deps/v8/src/objects/js-number-format.cc b/deps/v8/src/objects/js-number-format.cc
index 67d545e0be..d1e3ef4d0c 100644
--- a/deps/v8/src/objects/js-number-format.cc
+++ b/deps/v8/src/objects/js-number-format.cc
@@ -31,19 +31,9 @@ namespace internal {
namespace {
-// [[Style]] is one of the values "decimal", "percent", "currency",
-// or "unit" identifying the style of the number format.
-// Note: "unit" is added in proposal-unified-intl-numberformat
-enum class Style {
- DECIMAL,
- PERCENT,
- CURRENCY,
- UNIT,
-};
-
// [[CurrencyDisplay]] is one of the values "code", "symbol", "name",
-// or "narrow-symbol" identifying the display of the currency number format.
-// Note: "narrow-symbol" is added in proposal-unified-intl-numberformat
+// or "narrowSymbol" identifying the display of the currency number format.
+// Note: "narrowSymbol" is added in proposal-unified-intl-numberformat
enum class CurrencyDisplay {
CODE,
SYMBOL,
@@ -62,8 +52,8 @@ enum class CurrencySign {
// [[UnitDisplay]] is one of the String values "short", "narrow", or "long",
// specifying whether to display the unit as a symbol, narrow symbol, or
-// localized long name if formatting with the "unit" or "percent" style. It is
-// only used when [[Style]] has the value "unit" or "percent".
+// localized long name if formatting with the "unit" style. It is
+// only used when [[Style]] has the value "unit".
enum class UnitDisplay {
SHORT,
NARROW,
@@ -95,7 +85,7 @@ enum class CompactDisplay {
};
// [[SignDisplay]] is one of the String values "auto", "always", "never", or
-// "except-zero", specifying whether to show the sign on negative numbers
+// "exceptZero", specifying whether to show the sign on negative numbers
// only, positive and negative numbers including zero, neither positive nor
// negative numbers, or positive and negative numbers but not zero.
enum class SignDisplay {
@@ -164,7 +154,9 @@ icu::number::Notation ToICUNotation(Notation notation,
return icu::number::Notation::scientific();
case Notation::ENGINEERING:
return icu::number::Notation::engineering();
+ // 29. If notation is "compact", then
case Notation::COMPACT:
+ // 29. a. Set numberFormat.[[CompactDisplay]] to compactDisplay.
if (compact_display == CompactDisplay::SHORT) {
return icu::number::Notation::compactShort();
}
@@ -195,7 +187,9 @@ std::map<const std::string, icu::MeasureUnit> CreateUnitMap() {
CHECK(U_SUCCESS(status));
std::map<const std::string, icu::MeasureUnit> map;
for (auto it = units.begin(); it != units.end(); ++it) {
- if (sanctioned.count(it->getSubtype()) > 0) {
+ // Need to skip none/percent
+ if (sanctioned.count(it->getSubtype()) > 0 &&
+ strcmp("none", it->getType()) != 0) {
map[it->getSubtype()] = *it;
}
}
@@ -304,38 +298,16 @@ bool IsWellFormedCurrencyCode(const std::string& currency) {
return (IsAToZ(currency[0]) && IsAToZ(currency[1]) && IsAToZ(currency[2]));
}
-// Parse the 'style' from the skeleton.
-Style StyleFromSkeleton(const icu::UnicodeString& skeleton) {
- // Ex: skeleton as
- // "percent precision-integer rounding-mode-half-up scale/100"
- if (skeleton.indexOf("percent") >= 0 && skeleton.indexOf("scale/100") >= 0) {
- return Style::PERCENT;
- }
- // Ex: skeleton as "currency/TWD .00 rounding-mode-half-up"
- if (skeleton.indexOf("currency") >= 0) {
- return Style::CURRENCY;
- }
- // Ex: skeleton as
- // "measure-unit/length-meter .### rounding-mode-half-up unit-width-narrow"
- // or special case for "percent .### rounding-mode-half-up"
- if (skeleton.indexOf("measure-unit") >= 0 ||
- skeleton.indexOf("percent") >= 0) {
- return Style::UNIT;
- }
- // Ex: skeleton as ".### rounding-mode-half-up"
- return Style::DECIMAL;
-}
-
// Return the style as a String.
-Handle<String> StyleAsString(Isolate* isolate, Style style) {
+Handle<String> StyleAsString(Isolate* isolate, JSNumberFormat::Style style) {
switch (style) {
- case Style::PERCENT:
+ case JSNumberFormat::Style::PERCENT:
return ReadOnlyRoots(isolate).percent_string_handle();
- case Style::CURRENCY:
+ case JSNumberFormat::Style::CURRENCY:
return ReadOnlyRoots(isolate).currency_string_handle();
- case Style::UNIT:
+ case JSNumberFormat::Style::UNIT:
return ReadOnlyRoots(isolate).unit_string_handle();
- case Style::DECIMAL:
+ case JSNumberFormat::Style::DECIMAL:
return ReadOnlyRoots(isolate).decimal_string_handle();
}
UNREACHABLE();
@@ -357,7 +329,7 @@ Handle<String> CurrencyDisplayString(Isolate* isolate,
// Ex: skeleton as
// "currency/TWD .00 rounding-mode-half-up unit-width-narrow;
if (skeleton.indexOf("unit-width-narrow") >= 0) {
- return ReadOnlyRoots(isolate).narrow_symbol_string_handle();
+ return ReadOnlyRoots(isolate).narrowSymbol_string_handle();
}
// Ex: skeleton as "currency/TWD .00 rounding-mode-half-up"
return ReadOnlyRoots(isolate).symbol_string_handle();
@@ -480,11 +452,13 @@ Handle<String> SignDisplayString(Isolate* isolate,
// "currency/TWD .00 rounding-mode-half-up sign-except-zero"
if (skeleton.indexOf("sign-accounting-except-zero") >= 0 ||
skeleton.indexOf("sign-except-zero") >= 0) {
- return ReadOnlyRoots(isolate).except_zero_string_handle();
+ return ReadOnlyRoots(isolate).exceptZero_string_handle();
}
return ReadOnlyRoots(isolate).auto_string_handle();
}
+} // anonymous namespace
+
// Return the minimum integer digits by counting the number of '0' after
// "integer-width/+" in the skeleton.
// Ex: Return 15 for skeleton as
@@ -492,7 +466,8 @@ Handle<String> SignDisplayString(Isolate* isolate,
// 1
// 123456789012345
// Return default value as 1 if there are no "integer-width/+".
-int32_t MinimumIntegerDigitsFromSkeleton(const icu::UnicodeString& skeleton) {
+int32_t JSNumberFormat::MinimumIntegerDigitsFromSkeleton(
+ const icu::UnicodeString& skeleton) {
// count the number of 0 after "integer-width/+"
icu::UnicodeString search("integer-width/+");
int32_t index = skeleton.indexOf(search);
@@ -515,8 +490,8 @@ int32_t MinimumIntegerDigitsFromSkeleton(const icu::UnicodeString& skeleton) {
// 123
// 4567
// Set The minimum as 3 and maximum as 7.
-bool FractionDigitsFromSkeleton(const icu::UnicodeString& skeleton,
- int32_t* minimum, int32_t* maximum) {
+bool JSNumberFormat::FractionDigitsFromSkeleton(
+ const icu::UnicodeString& skeleton, int32_t* minimum, int32_t* maximum) {
icu::UnicodeString search(".");
int32_t index = skeleton.indexOf(search);
if (index < 0) return false;
@@ -542,8 +517,8 @@ bool FractionDigitsFromSkeleton(const icu::UnicodeString& skeleton,
// 12345
// 6789012
// Set The minimum as 5 and maximum as 12.
-bool SignificantDigitsFromSkeleton(const icu::UnicodeString& skeleton,
- int32_t* minimum, int32_t* maximum) {
+bool JSNumberFormat::SignificantDigitsFromSkeleton(
+ const icu::UnicodeString& skeleton, int32_t* minimum, int32_t* maximum) {
icu::UnicodeString search("@");
int32_t index = skeleton.indexOf(search);
if (index < 0) return false;
@@ -561,6 +536,8 @@ bool SignificantDigitsFromSkeleton(const icu::UnicodeString& skeleton,
return true;
}
+namespace {
+
// Ex: percent .### rounding-mode-half-up
// Special case for "percent"
// Ex: "measure-unit/length-kilometer per-measure-unit/duration-hour .###
@@ -630,6 +607,34 @@ std::string UnitFromSkeleton(const icu::UnicodeString& skeleton) {
} // anonymous namespace
+icu::number::LocalizedNumberFormatter
+JSNumberFormat::SetDigitOptionsToFormatter(
+ const icu::number::LocalizedNumberFormatter& icu_number_formatter,
+ const Intl::NumberFormatDigitOptions& digit_options) {
+ icu::number::LocalizedNumberFormatter result = icu_number_formatter;
+ if (digit_options.minimum_integer_digits > 1) {
+ result = result.integerWidth(icu::number::IntegerWidth::zeroFillTo(
+ digit_options.minimum_integer_digits));
+ }
+ if (FLAG_harmony_intl_numberformat_unified) {
+ // Value -1 of minimum_significant_digits represent the roundingtype is
+ // "compact-rounding".
+ if (digit_options.minimum_significant_digits < 0) {
+ return result;
+ }
+ }
+ icu::number::Precision precision =
+ (digit_options.minimum_significant_digits > 0)
+ ? icu::number::Precision::minMaxSignificantDigits(
+ digit_options.minimum_significant_digits,
+ digit_options.maximum_significant_digits)
+ : icu::number::Precision::minMaxFraction(
+ digit_options.minimum_fraction_digits,
+ digit_options.maximum_fraction_digits);
+
+ return result.precision(precision);
+}
+
// static
// ecma402 #sec-intl.numberformat.prototype.resolvedoptions
Handle<JSObject> JSNumberFormat::ResolvedOptions(
@@ -642,9 +647,6 @@ Handle<JSObject> JSNumberFormat::ResolvedOptions(
icu::UnicodeString skeleton = icu_number_formatter->toSkeleton(status);
CHECK(U_SUCCESS(status));
- std::string s_str;
- s_str = skeleton.toUTF8String<std::string>(s_str);
-
// 4. Let options be ! ObjectCreate(%ObjectPrototype%).
Handle<JSObject> options = factory->NewJSObject(isolate->object_function());
@@ -680,7 +682,7 @@ Handle<JSObject> JSNumberFormat::ResolvedOptions(
Just(kDontThrow))
.FromJust());
}
- Style style = StyleFromSkeleton(skeleton);
+ JSNumberFormat::Style style = number_format->style();
CHECK(JSReceiver::CreateDataProperty(
isolate, options, factory->style_string(),
StyleAsString(isolate, style), Just(kDontThrow))
@@ -706,15 +708,15 @@ Handle<JSObject> JSNumberFormat::ResolvedOptions(
}
if (FLAG_harmony_intl_numberformat_unified) {
- std::string unit = UnitFromSkeleton(skeleton);
- if (!unit.empty()) {
- CHECK(JSReceiver::CreateDataProperty(
- isolate, options, factory->unit_string(),
- isolate->factory()->NewStringFromAsciiChecked(unit.c_str()),
- Just(kDontThrow))
- .FromJust());
- }
- if (style == Style::UNIT || style == Style::PERCENT) {
+ if (style == JSNumberFormat::Style::UNIT) {
+ std::string unit = UnitFromSkeleton(skeleton);
+ if (!unit.empty()) {
+ CHECK(JSReceiver::CreateDataProperty(
+ isolate, options, factory->unit_string(),
+ isolate->factory()->NewStringFromAsciiChecked(unit.c_str()),
+ Just(kDontThrow))
+ .FromJust());
+ }
CHECK(JSReceiver::CreateDataProperty(
isolate, options, factory->unitDisplay_string(),
UnitDisplayString(isolate, skeleton), Just(kDontThrow))
@@ -827,10 +829,10 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::UnwrapNumberFormat(
}
// static
-MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
- Isolate* isolate, Handle<JSNumberFormat> number_format,
- Handle<Object> locales, Handle<Object> options_obj) {
- number_format->set_flags(0);
+MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
+ Handle<Map> map,
+ Handle<Object> locales,
+ Handle<Object> options_obj) {
Factory* factory = isolate->factory();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
@@ -898,7 +900,6 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
// 9. Set numberFormat.[[Locale]] to r.[[locale]].
Handle<String> locale_str =
isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
- number_format->set_locale(*locale_str);
// 11. Let dataLocale be r.[[dataLocale]].
@@ -911,17 +912,19 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
const char* service = "Intl.NumberFormat";
std::vector<const char*> style_str_values({"decimal", "percent", "currency"});
- std::vector<Style> style_enum_values(
- {Style::DECIMAL, Style::PERCENT, Style::CURRENCY});
+ std::vector<JSNumberFormat::Style> style_enum_values(
+ {JSNumberFormat::Style::DECIMAL, JSNumberFormat::Style::PERCENT,
+ JSNumberFormat::Style::CURRENCY});
if (FLAG_harmony_intl_numberformat_unified) {
style_str_values.push_back("unit");
- style_enum_values.push_back(Style::UNIT);
+ style_enum_values.push_back(JSNumberFormat::Style::UNIT);
}
- Maybe<Style> maybe_style = Intl::GetStringOption<Style>(
- isolate, options, "style", service, style_str_values, style_enum_values,
- Style::DECIMAL);
+ Maybe<JSNumberFormat::Style> maybe_style =
+ Intl::GetStringOption<JSNumberFormat::Style>(
+ isolate, options, "style", service, style_str_values,
+ style_enum_values, JSNumberFormat::Style::DECIMAL);
MAYBE_RETURN(maybe_style, MaybeHandle<JSNumberFormat>());
- Style style = maybe_style.FromJust();
+ JSNumberFormat::Style style = maybe_style.FromJust();
// 13. Set numberFormat.[[Style]] to style.
@@ -952,14 +955,14 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
// 16. If style is "currency" and currency is undefined, throw a TypeError
// exception.
- if (style == Style::CURRENCY && !found_currency.FromJust()) {
+ if (style == JSNumberFormat::Style::CURRENCY && !found_currency.FromJust()) {
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kCurrencyCode),
JSNumberFormat);
}
// 17. If style is "currency", then
int c_digits = 0;
icu::UnicodeString currency_ustr;
- if (style == Style::CURRENCY) {
+ if (style == JSNumberFormat::Style::CURRENCY) {
// a. Let currency be the result of converting currency to upper case as
// specified in 6.1
std::transform(currency.begin(), currency.end(), currency.begin(), toupper);
@@ -975,7 +978,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
std::vector<CurrencyDisplay> currency_display_enum_values(
{CurrencyDisplay::CODE, CurrencyDisplay::SYMBOL, CurrencyDisplay::NAME});
if (FLAG_harmony_intl_numberformat_unified) {
- currency_display_str_values.push_back("narrow-symbol");
+ currency_display_str_values.push_back("narrowSymbol");
currency_display_enum_values.push_back(CurrencyDisplay::NARROW_SYMBOL);
}
Maybe<CurrencyDisplay> maybe_currency_display =
@@ -1020,13 +1023,8 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
MAYBE_RETURN(maybe_unit_display, MaybeHandle<JSNumberFormat>());
UnitDisplay unit_display = maybe_unit_display.FromJust();
- // If style is "percent", then
- if (style == Style::PERCENT) {
- // Let unit be "concentr-percent".
- unit = "percent";
- }
- // If style is "unit" or "percent", then
- if (style == Style::PERCENT || style == Style::UNIT) {
+ // If style is "unit", then
+ if (style == JSNumberFormat::Style::UNIT) {
// If unit is undefined, throw a TypeError exception.
if (unit == "") {
THROW_NEW_ERROR(
@@ -1070,12 +1068,12 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
}
}
- if (style == Style::PERCENT) {
+ if (style == JSNumberFormat::Style::PERCENT) {
icu_number_formatter = icu_number_formatter.unit(icu::NoUnit::percent())
.scale(icu::number::Scale::powerOfTen(2));
}
- if (style == Style::CURRENCY) {
+ if (style == JSNumberFormat::Style::CURRENCY) {
// 19. If style is "currency", set numberFormat.[[CurrencyDisplay]] to
// currencyDisplay.
@@ -1099,19 +1097,19 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
}
}
- // 20. If style is "currency", then
+ // 23. If style is "currency", then
int mnfd_default, mxfd_default;
- if (style == Style::CURRENCY) {
+ if (style == JSNumberFormat::Style::CURRENCY) {
// a. Let mnfdDefault be cDigits.
// b. Let mxfdDefault be cDigits.
mnfd_default = c_digits;
mxfd_default = c_digits;
+ // 24. Else,
} else {
- // 21. Else,
// a. Let mnfdDefault be 0.
mnfd_default = 0;
// b. If style is "percent", then
- if (style == Style::PERCENT) {
+ if (style == JSNumberFormat::Style::PERCENT) {
// i. Let mxfdDefault be 0.
mxfd_default = 0;
} else {
@@ -1120,51 +1118,11 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
mxfd_default = 3;
}
}
- // 22. Perform ? SetNumberFormatDigitOptions(numberFormat, options,
- // mnfdDefault, mxfdDefault).
- Maybe<Intl::NumberFormatDigitOptions> maybe_digit_options =
- Intl::SetNumberFormatDigitOptions(isolate, options, mnfd_default,
- mxfd_default);
- MAYBE_RETURN(maybe_digit_options, Handle<JSNumberFormat>());
- Intl::NumberFormatDigitOptions digit_options = maybe_digit_options.FromJust();
-
- icu::number::Precision precision =
- (digit_options.minimum_significant_digits > 0)
- ? icu::number::Precision::minMaxSignificantDigits(
- digit_options.minimum_significant_digits,
- digit_options.maximum_significant_digits)
- : icu::number::Precision::minMaxFraction(
- digit_options.minimum_fraction_digits,
- digit_options.maximum_fraction_digits);
-
- if (digit_options.minimum_significant_digits > 0) {
- // Currenct ECMA 402 spec mandate to record (Min|Max)imumFractionDigits
- // uncondictionally while the unified number proposal eventually will only
- // record either (Min|Max)imumFractionDigits or
- // (Min|Max)imumSignaficantDigits Since LocalizedNumberFormatter can only
- // remember one set, and during 2019-1-17 ECMA402 meeting that the committee
- // decide not to take a PR to address that prior to the unified number
- // proposal, we have to add these two 5 bits int into flags to remember the
- // (Min|Max)imumFractionDigits while (Min|Max)imumSignaficantDigits is
- // present.
- // TODO(ftang) remove the following two lines once we ship
- // int-number-format-unified
- number_format->set_minimum_fraction_digits(
- digit_options.minimum_fraction_digits);
- number_format->set_maximum_fraction_digits(
- digit_options.maximum_fraction_digits);
- }
-
- icu_number_formatter = icu_number_formatter.precision(precision);
- if (digit_options.minimum_integer_digits > 1) {
- icu_number_formatter =
- icu_number_formatter.integerWidth(icu::number::IntegerWidth::zeroFillTo(
- digit_options.minimum_integer_digits));
- }
+ Notation notation = Notation::STANDARD;
if (FLAG_harmony_intl_numberformat_unified) {
- // Let notation be ? GetOption(options, "notation", "string", « "standard",
- // "scientific", "engineering", "compact" », "standard").
+ // 25. Let notation be ? GetOption(options, "notation", "string", «
+ // "standard", "scientific", "engineering", "compact" », "standard").
Maybe<Notation> maybe_notation = Intl::GetStringOption<Notation>(
isolate, options, "notation", service,
{"standard", "scientific", "engineering", "compact"},
@@ -1172,10 +1130,23 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
Notation::COMPACT},
Notation::STANDARD);
MAYBE_RETURN(maybe_notation, MaybeHandle<JSNumberFormat>());
- Notation notation = maybe_notation.FromJust();
+ notation = maybe_notation.FromJust();
+ }
+
+ // 27. Perform ? SetNumberFormatDigitOptions(numberFormat, options,
+ // mnfdDefault, mxfdDefault).
+ Maybe<Intl::NumberFormatDigitOptions> maybe_digit_options =
+ Intl::SetNumberFormatDigitOptions(isolate, options, mnfd_default,
+ mxfd_default,
+ notation == Notation::COMPACT);
+ MAYBE_RETURN(maybe_digit_options, Handle<JSNumberFormat>());
+ Intl::NumberFormatDigitOptions digit_options = maybe_digit_options.FromJust();
+ icu_number_formatter = JSNumberFormat::SetDigitOptionsToFormatter(
+ icu_number_formatter, digit_options);
- // Let compactDisplay be ? GetOption(options, "compactDisplay", "string", «
- // "short", "long" », "short").
+ if (FLAG_harmony_intl_numberformat_unified) {
+ // 28. Let compactDisplay be ? GetOption(options, "compactDisplay",
+ // "string", « "short", "long" », "short").
Maybe<CompactDisplay> maybe_compact_display =
Intl::GetStringOption<CompactDisplay>(
isolate, options, "compactDisplay", service, {"short", "long"},
@@ -1184,6 +1155,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
MAYBE_RETURN(maybe_compact_display, MaybeHandle<JSNumberFormat>());
CompactDisplay compact_display = maybe_compact_display.FromJust();
+ // 26. Set numberFormat.[[Notation]] to notation.
// The default notation in ICU is Simple, which mapped from STANDARD
// so we can skip setting it.
if (notation != Notation::STANDARD) {
@@ -1191,30 +1163,31 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
ToICUNotation(notation, compact_display));
}
}
- // 23. Let useGrouping be ? GetOption(options, "useGrouping", "boolean",
+ // 30. Let useGrouping be ? GetOption(options, "useGrouping", "boolean",
// undefined, true).
bool use_grouping = true;
Maybe<bool> found_use_grouping = Intl::GetBoolOption(
isolate, options, "useGrouping", service, &use_grouping);
MAYBE_RETURN(found_use_grouping, MaybeHandle<JSNumberFormat>());
- // 24. Set numberFormat.[[UseGrouping]] to useGrouping.
+ // 31. Set numberFormat.[[UseGrouping]] to useGrouping.
if (!use_grouping) {
icu_number_formatter = icu_number_formatter.grouping(
UNumberGroupingStrategy::UNUM_GROUPING_OFF);
}
if (FLAG_harmony_intl_numberformat_unified) {
- // Let signDisplay be ? GetOption(options, "signDisplay", "string", «
- // "auto", "never", "always", "except-zero" », "auto").
+ // 32. Let signDisplay be ? GetOption(options, "signDisplay", "string", «
+ // "auto", "never", "always", "exceptZero" », "auto").
Maybe<SignDisplay> maybe_sign_display = Intl::GetStringOption<SignDisplay>(
isolate, options, "signDisplay", service,
- {"auto", "never", "always", "except-zero"},
+ {"auto", "never", "always", "exceptZero"},
{SignDisplay::AUTO, SignDisplay::NEVER, SignDisplay::ALWAYS,
SignDisplay::EXCEPT_ZERO},
SignDisplay::AUTO);
MAYBE_RETURN(maybe_sign_display, MaybeHandle<JSNumberFormat>());
SignDisplay sign_display = maybe_sign_display.FromJust();
+ // 33. Set numberFormat.[[SignDisplay]] to signDisplay.
// The default sign in ICU is UNUM_SIGN_AUTO which is mapped from
// SignDisplay::AUTO and CurrencySign::STANDARD so we can skip setting
// under that values for optimization.
@@ -1244,6 +1217,33 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
Managed<icu::number::LocalizedNumberFormatter>::FromRawPtr(
isolate, 0,
new icu::number::LocalizedNumberFormatter(icu_number_formatter));
+
+ // Now all properties are ready, so we can allocate the result object.
+ Handle<JSNumberFormat> number_format = Handle<JSNumberFormat>::cast(
+ isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
+ DisallowHeapAllocation no_gc;
+ number_format->set_flags(0);
+ number_format->set_style(style);
+ number_format->set_locale(*locale_str);
+
+ if (digit_options.minimum_significant_digits > 0) {
+ // The current ECMA 402 spec mandates recording (Min|Max)imumFractionDigits
+ // unconditionally, while the unified number proposal eventually will only
+ // record either (Min|Max)imumFractionDigits or
+ // (Min|Max)imumSignificantDigits. Since LocalizedNumberFormatter can only
+ // remember one set, and during 2019-1-17 ECMA402 meeting the committee
+ // decided not to take a PR to address that prior to the unified number
+ // proposal, we have to add these two 5-bit ints into flags to remember the
+ // (Min|Max)imumFractionDigits while (Min|Max)imumSignificantDigits is
+ // present.
+ // TODO(ftang) remove the following two lines once we ship
+ // int-number-format-unified
+ number_format->set_minimum_fraction_digits(
+ digit_options.minimum_fraction_digits);
+ number_format->set_maximum_fraction_digits(
+ digit_options.maximum_fraction_digits);
+ }
+
number_format->set_icu_number_formatter(*managed_number_formatter);
number_format->set_bound_format(*factory->undefined_value());
@@ -1417,7 +1417,7 @@ namespace {
Maybe<int> ConstructParts(Isolate* isolate, const icu::UnicodeString& formatted,
icu::FieldPositionIterator* fp_iter,
Handle<JSArray> result, int start_index,
- Handle<Object> numeric_obj, Handle<String> unit) {
+ Handle<Object> numeric_obj, bool style_is_unit) {
DCHECK(numeric_obj->IsNumeric());
int32_t length = formatted.length();
int index = start_index;
@@ -1442,21 +1442,23 @@ Maybe<int> ConstructParts(Isolate* isolate, const icu::UnicodeString& formatted,
for (auto it = parts.begin(); it < parts.end(); it++) {
NumberFormatSpan part = *it;
- Handle<String> field_type_string =
- part.field_id == -1
- ? isolate->factory()->literal_string()
- : Intl::NumberFieldToType(isolate, numeric_obj, part.field_id);
+ Handle<String> field_type_string = isolate->factory()->literal_string();
+ if (part.field_id != -1) {
+ if (style_is_unit && static_cast<UNumberFormatFields>(part.field_id) ==
+ UNUM_PERCENT_FIELD) {
+ // Special case when style is unit.
+ field_type_string = isolate->factory()->unit_string();
+ } else {
+ field_type_string =
+ Intl::NumberFieldToType(isolate, numeric_obj, part.field_id);
+ }
+ }
Handle<String> substring;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, substring,
Intl::ToString(isolate, formatted, part.begin_pos, part.end_pos),
Nothing<int>());
- if (unit.is_null()) {
- Intl::AddElement(isolate, result, index, field_type_string, substring);
- } else {
- Intl::AddElement(isolate, result, index, field_type_string, substring,
- isolate->factory()->unit_string(), unit);
- }
+ Intl::AddElement(isolate, result, index, field_type_string, substring);
++index;
}
JSObject::ValidateElements(*result);
@@ -1480,16 +1482,26 @@ MaybeHandle<JSArray> JSNumberFormat::FormatToParts(
MAYBE_RETURN(maybe_format, Handle<JSArray>());
Handle<JSArray> result = factory->NewJSArray(0);
- Maybe<int> maybe_format_to_parts =
- ConstructParts(isolate, maybe_format.FromJust(), &fp_iter, result, 0,
- numeric_obj, Handle<String>());
+ Maybe<int> maybe_format_to_parts = ConstructParts(
+ isolate, maybe_format.FromJust(), &fp_iter, result, 0, numeric_obj,
+ number_format->style() == JSNumberFormat::Style::UNIT);
MAYBE_RETURN(maybe_format_to_parts, Handle<JSArray>());
return result;
}
+namespace {
+
+struct CheckNumberElements {
+ static const char* key() { return "NumberElements"; }
+ static const char* path() { return nullptr; }
+};
+
+} // namespace
+
const std::set<std::string>& JSNumberFormat::GetAvailableLocales() {
- static base::LazyInstance<Intl::AvailableLocales<icu::NumberFormat>>::type
+ static base::LazyInstance<
+ Intl::AvailableLocales<icu::NumberFormat, CheckNumberElements>>::type
available_locales = LAZY_INSTANCE_INITIALIZER;
return available_locales.Pointer()->Get();
}
diff --git a/deps/v8/src/objects/js-number-format.h b/deps/v8/src/objects/js-number-format.h
index 6c59e76f7a..2979ab10f4 100644
--- a/deps/v8/src/objects/js-number-format.h
+++ b/deps/v8/src/objects/js-number-format.h
@@ -17,14 +17,15 @@
#include "src/objects/intl-objects.h"
#include "src/objects/managed.h"
#include "src/objects/objects.h"
-#include "unicode/numberformatter.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace U_ICU_NAMESPACE {
-class NumberFormat;
class UnicodeString;
+namespace number {
+class LocalizedNumberFormatter;
+} // namespace number
} // namespace U_ICU_NAMESPACE
namespace v8 {
@@ -33,9 +34,9 @@ namespace internal {
class JSNumberFormat : public JSObject {
public:
// ecma402/#sec-initializenumberformat
- V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> Initialize(
- Isolate* isolate, Handle<JSNumberFormat> number_format,
- Handle<Object> locales, Handle<Object> options);
+ V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> New(
+ Isolate* isolate, Handle<Map> map, Handle<Object> locales,
+ Handle<Object> options);
// ecma402/#sec-unwrapnumberformat
V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> UnwrapNumberFormat(
@@ -56,6 +57,17 @@ class JSNumberFormat : public JSObject {
V8_EXPORT_PRIVATE static const std::set<std::string>& GetAvailableLocales();
+ // Helper functions shared with JSPluralRules.
+ static int32_t MinimumIntegerDigitsFromSkeleton(
+ const icu::UnicodeString& skeleton);
+ static bool FractionDigitsFromSkeleton(const icu::UnicodeString& skeleton,
+ int32_t* minimum, int32_t* maximum);
+ static bool SignificantDigitsFromSkeleton(const icu::UnicodeString& skeleton,
+ int32_t* minimum, int32_t* maximum);
+ static icu::number::LocalizedNumberFormatter SetDigitOptionsToFormatter(
+ const icu::number::LocalizedNumberFormatter& icu_number_formatter,
+ const Intl::NumberFormatDigitOptions& digit_options);
+
DECL_CAST(JSNumberFormat)
DECL_PRINTER(JSNumberFormat)
DECL_VERIFIER(JSNumberFormat)
@@ -80,6 +92,14 @@ class JSNumberFormat : public JSObject {
inline int maximum_fraction_digits() const;
inline void set_maximum_fraction_digits(int digits);
+ // [[Style]] is one of the values "decimal", "percent", "currency",
+ // or "unit" identifying the style of the number format.
+ // Note: "unit" is added in proposal-unified-intl-numberformat
+ enum class Style { DECIMAL, PERCENT, CURRENCY, UNIT };
+
+ inline void set_style(Style style);
+ inline Style style() const;
+
// Layout description.
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
TORQUE_GENERATED_JSNUMBER_FORMAT_FIELDS)
@@ -87,13 +107,18 @@ class JSNumberFormat : public JSObject {
// Bit positions in |flags|.
#define FLAGS_BIT_FIELDS(V, _) \
V(MinimumFractionDigitsBits, int, 5, _) \
- V(MaximumFractionDigitsBits, int, 5, _)
+ V(MaximumFractionDigitsBits, int, 5, _) \
+ V(StyleBits, Style, 2, _)
DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
#undef FLAGS_BIT_FIELDS
STATIC_ASSERT(20 <= MinimumFractionDigitsBits::kMax);
STATIC_ASSERT(20 <= MaximumFractionDigitsBits::kMax);
+ STATIC_ASSERT(Style::DECIMAL <= StyleBits::kMax);
+ STATIC_ASSERT(Style::PERCENT <= StyleBits::kMax);
+ STATIC_ASSERT(Style::CURRENCY <= StyleBits::kMax);
+ STATIC_ASSERT(Style::UNIT <= StyleBits::kMax);
DECL_ACCESSORS(locale, String)
DECL_ACCESSORS(icu_number_formatter,
diff --git a/deps/v8/src/objects/js-objects-inl.h b/deps/v8/src/objects/js-objects-inl.h
index 6b7a7d72f0..10672d4443 100644
--- a/deps/v8/src/objects/js-objects-inl.h
+++ b/deps/v8/src/objects/js-objects-inl.h
@@ -8,6 +8,7 @@
#include "src/objects/js-objects.h"
#include "src/heap/heap-write-barrier.h"
+#include "src/objects/elements.h"
#include "src/objects/embedder-data-slot-inl.h"
#include "src/objects/feedback-cell-inl.h"
#include "src/objects/feedback-vector.h"
@@ -29,17 +30,17 @@ namespace v8 {
namespace internal {
OBJECT_CONSTRUCTORS_IMPL(JSReceiver, HeapObject)
-OBJECT_CONSTRUCTORS_IMPL(JSObject, JSReceiver)
+TQ_OBJECT_CONSTRUCTORS_IMPL(JSObject)
OBJECT_CONSTRUCTORS_IMPL(JSAsyncFromSyncIterator, JSObject)
OBJECT_CONSTRUCTORS_IMPL(JSBoundFunction, JSObject)
OBJECT_CONSTRUCTORS_IMPL(JSDate, JSObject)
OBJECT_CONSTRUCTORS_IMPL(JSFunction, JSObject)
OBJECT_CONSTRUCTORS_IMPL(JSGlobalObject, JSObject)
-OBJECT_CONSTRUCTORS_IMPL(JSGlobalProxy, JSObject)
+TQ_OBJECT_CONSTRUCTORS_IMPL(JSGlobalProxy)
JSIteratorResult::JSIteratorResult(Address ptr) : JSObject(ptr) {}
OBJECT_CONSTRUCTORS_IMPL(JSMessageObject, JSObject)
+TQ_OBJECT_CONSTRUCTORS_IMPL(JSPrimitiveWrapper)
OBJECT_CONSTRUCTORS_IMPL(JSStringIterator, JSObject)
-OBJECT_CONSTRUCTORS_IMPL(JSValue, JSObject)
NEVER_READ_ONLY_SPACE_IMPL(JSReceiver)
@@ -48,13 +49,10 @@ CAST_ACCESSOR(JSBoundFunction)
CAST_ACCESSOR(JSDate)
CAST_ACCESSOR(JSFunction)
CAST_ACCESSOR(JSGlobalObject)
-CAST_ACCESSOR(JSGlobalProxy)
CAST_ACCESSOR(JSIteratorResult)
CAST_ACCESSOR(JSMessageObject)
-CAST_ACCESSOR(JSObject)
CAST_ACCESSOR(JSReceiver)
CAST_ACCESSOR(JSStringIterator)
-CAST_ACCESSOR(JSValue)
MaybeHandle<Object> JSReceiver::GetProperty(Isolate* isolate,
Handle<JSReceiver> receiver,
@@ -130,11 +128,6 @@ bool JSObject::PrototypeHasNoElements(Isolate* isolate, JSObject object) {
ACCESSORS(JSReceiver, raw_properties_or_hash, Object, kPropertiesOrHashOffset)
-FixedArrayBase JSObject::elements() const {
- Object array = READ_FIELD(*this, kElementsOffset);
- return FixedArrayBase::cast(array);
-}
-
void JSObject::EnsureCanContainHeapObjectElements(Handle<JSObject> object) {
JSObject::ValidateElements(*object);
ElementsKind elements_kind = object->map().elements_kind();
@@ -225,39 +218,34 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object,
void JSObject::SetMapAndElements(Handle<JSObject> object, Handle<Map> new_map,
Handle<FixedArrayBase> value) {
- JSObject::MigrateToMap(object, new_map);
+ Isolate* isolate = object->GetIsolate();
+ JSObject::MigrateToMap(isolate, object, new_map);
DCHECK((object->map().has_fast_smi_or_object_elements() ||
- (*value == object->GetReadOnlyRoots().empty_fixed_array()) ||
+ (*value == ReadOnlyRoots(isolate).empty_fixed_array()) ||
object->map().has_fast_string_wrapper_elements()) ==
- (value->map() == object->GetReadOnlyRoots().fixed_array_map() ||
- value->map() == object->GetReadOnlyRoots().fixed_cow_array_map()));
- DCHECK((*value == object->GetReadOnlyRoots().empty_fixed_array()) ||
+ (value->map() == ReadOnlyRoots(isolate).fixed_array_map() ||
+ value->map() == ReadOnlyRoots(isolate).fixed_cow_array_map()));
+ DCHECK((*value == ReadOnlyRoots(isolate).empty_fixed_array()) ||
(object->map().has_fast_double_elements() ==
value->IsFixedDoubleArray()));
object->set_elements(*value);
}
-void JSObject::set_elements(FixedArrayBase value, WriteBarrierMode mode) {
- WRITE_FIELD(*this, kElementsOffset, value);
- CONDITIONAL_WRITE_BARRIER(*this, kElementsOffset, value, mode);
-}
-
void JSObject::initialize_elements() {
FixedArrayBase elements = map().GetInitialElements();
- WRITE_FIELD(*this, kElementsOffset, elements);
+ set_elements(elements, SKIP_WRITE_BARRIER);
}
-InterceptorInfo JSObject::GetIndexedInterceptor() {
- return map().GetIndexedInterceptor();
+DEF_GETTER(JSObject, GetIndexedInterceptor, InterceptorInfo) {
+ return map(isolate).GetIndexedInterceptor(isolate);
}
-InterceptorInfo JSObject::GetNamedInterceptor() {
- return map().GetNamedInterceptor();
+DEF_GETTER(JSObject, GetNamedInterceptor, InterceptorInfo) {
+ return map(isolate).GetNamedInterceptor(isolate);
}
-int JSObject::GetHeaderSize() const { return GetHeaderSize(map()); }
-
-int JSObject::GetHeaderSize(const Map map) {
+// static
+int JSObject::GetHeaderSize(Map map) {
// Check for the most common kind of JavaScript object before
// falling into the generic switch. This speeds up the internal
// field operations considerably on average.
@@ -268,7 +256,7 @@ int JSObject::GetHeaderSize(const Map map) {
}
// static
-int JSObject::GetEmbedderFieldsStartOffset(const Map map) {
+int JSObject::GetEmbedderFieldsStartOffset(Map map) {
// Embedder fields are located after the object header.
return GetHeaderSize(map);
}
@@ -278,7 +266,7 @@ int JSObject::GetEmbedderFieldsStartOffset() {
}
// static
-int JSObject::GetEmbedderFieldCount(const Map map) {
+int JSObject::GetEmbedderFieldCount(Map map) {
int instance_size = map.instance_size();
if (instance_size == kVariableSizeSentinel) return 0;
// Embedder fields are located after the object header, whereas in-object
@@ -314,29 +302,39 @@ void JSObject::SetEmbedderField(int index, Smi value) {
EmbedderDataSlot(*this, index).store_smi(value);
}
-bool JSObject::IsUnboxedDoubleField(FieldIndex index) {
+bool JSObject::IsUnboxedDoubleField(FieldIndex index) const {
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return IsUnboxedDoubleField(isolate, index);
+}
+
+bool JSObject::IsUnboxedDoubleField(Isolate* isolate, FieldIndex index) const {
if (!FLAG_unbox_double_fields) return false;
- return map().IsUnboxedDoubleField(index);
+ return map(isolate).IsUnboxedDoubleField(isolate, index);
}
// Access fast-case object properties at index. The use of these routines
// is needed to correctly distinguish between properties stored in-object and
// properties stored in the properties array.
-Object JSObject::RawFastPropertyAt(FieldIndex index) {
- DCHECK(!IsUnboxedDoubleField(index));
+Object JSObject::RawFastPropertyAt(FieldIndex index) const {
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return RawFastPropertyAt(isolate, index);
+}
+
+Object JSObject::RawFastPropertyAt(Isolate* isolate, FieldIndex index) const {
+ DCHECK(!IsUnboxedDoubleField(isolate, index));
if (index.is_inobject()) {
- return READ_FIELD(*this, index.offset());
+ return TaggedField<Object>::load(isolate, *this, index.offset());
} else {
- return property_array().get(index.outobject_array_index());
+ return property_array(isolate).get(isolate, index.outobject_array_index());
}
}
-double JSObject::RawFastDoublePropertyAt(FieldIndex index) {
+double JSObject::RawFastDoublePropertyAt(FieldIndex index) const {
DCHECK(IsUnboxedDoubleField(index));
return ReadField<double>(index.offset());
}
-uint64_t JSObject::RawFastDoublePropertyAsBitsAt(FieldIndex index) {
+uint64_t JSObject::RawFastDoublePropertyAsBitsAt(FieldIndex index) const {
DCHECK(IsUnboxedDoubleField(index));
return ReadField<uint64_t>(index.offset());
}
@@ -417,7 +415,7 @@ int JSObject::GetInObjectPropertyOffset(int index) {
Object JSObject::InObjectPropertyAt(int index) {
int offset = GetInObjectPropertyOffset(index);
- return READ_FIELD(*this, offset);
+ return TaggedField<Object>::load(*this, offset);
}
Object JSObject::InObjectPropertyAtPut(int index, Object value,
@@ -452,10 +450,6 @@ void JSObject::InitializeBody(Map map, int start_offset,
}
}
-Object JSBoundFunction::raw_bound_target_function() const {
- return READ_FIELD(*this, kBoundTargetFunctionOffset);
-}
-
ACCESSORS(JSBoundFunction, bound_target_function, JSReceiver,
kBoundTargetFunctionOffset)
ACCESSORS(JSBoundFunction, bound_this, Object, kBoundThisOffset)
@@ -466,8 +460,6 @@ ACCESSORS(JSFunction, raw_feedback_cell, FeedbackCell, kFeedbackCellOffset)
ACCESSORS(JSGlobalObject, native_context, NativeContext, kNativeContextOffset)
ACCESSORS(JSGlobalObject, global_proxy, JSGlobalProxy, kGlobalProxyOffset)
-ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
-
FeedbackVector JSFunction::feedback_vector() const {
DCHECK(has_feedback_vector());
return FeedbackVector::cast(raw_feedback_cell().value());
@@ -564,7 +556,8 @@ void JSFunction::set_code_no_write_barrier(Code value) {
RELAXED_WRITE_FIELD(*this, kCodeOffset, value);
}
-SharedFunctionInfo JSFunction::shared() const {
+// TODO(ishell): Why relaxed read but release store?
+DEF_GETTER(JSFunction, shared, SharedFunctionInfo) {
return SharedFunctionInfo::cast(
RELAXED_READ_FIELD(*this, kSharedFunctionInfoOffset));
}
@@ -606,11 +599,11 @@ bool JSFunction::has_closure_feedback_cell_array() const {
}
Context JSFunction::context() {
- return Context::cast(READ_FIELD(*this, kContextOffset));
+ return TaggedField<Context, kContextOffset>::load(*this);
}
bool JSFunction::has_context() const {
- return READ_FIELD(*this, kContextOffset).IsContext();
+ return TaggedField<HeapObject, kContextOffset>::load(*this).IsContext();
}
JSGlobalProxy JSFunction::global_proxy() { return context().global_proxy(); }
@@ -619,65 +612,73 @@ NativeContext JSFunction::native_context() {
return context().native_context();
}
-void JSFunction::set_context(Object value) {
+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, Object,
+ACCESSORS_CHECKED(JSFunction, prototype_or_initial_map, HeapObject,
kPrototypeOrInitialMapOffset, map().has_prototype_slot())
-bool JSFunction::has_prototype_slot() const {
- return map().has_prototype_slot();
+DEF_GETTER(JSFunction, has_prototype_slot, bool) {
+ return map(isolate).has_prototype_slot();
}
-Map JSFunction::initial_map() { return Map::cast(prototype_or_initial_map()); }
+DEF_GETTER(JSFunction, initial_map, Map) {
+ return Map::cast(prototype_or_initial_map(isolate));
+}
-bool JSFunction::has_initial_map() {
- DCHECK(has_prototype_slot());
- return prototype_or_initial_map().IsMap();
+DEF_GETTER(JSFunction, has_initial_map, bool) {
+ DCHECK(has_prototype_slot(isolate));
+ return prototype_or_initial_map(isolate).IsMap(isolate);
}
-bool JSFunction::has_instance_prototype() {
- DCHECK(has_prototype_slot());
- return has_initial_map() || !prototype_or_initial_map().IsTheHole();
+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));
}
-bool JSFunction::has_prototype() {
- DCHECK(has_prototype_slot());
- return map().has_non_instance_prototype() || has_instance_prototype();
+DEF_GETTER(JSFunction, has_prototype, bool) {
+ DCHECK(has_prototype_slot(isolate));
+ return map(isolate).has_non_instance_prototype() ||
+ has_instance_prototype(isolate);
}
-bool JSFunction::has_prototype_property() {
- return (has_prototype_slot() && IsConstructor()) ||
- IsGeneratorFunction(shared().kind());
+DEF_GETTER(JSFunction, has_prototype_property, bool) {
+ return (has_prototype_slot(isolate) && IsConstructor(isolate)) ||
+ IsGeneratorFunction(shared(isolate).kind());
}
-bool JSFunction::PrototypeRequiresRuntimeLookup() {
- return !has_prototype_property() || map().has_non_instance_prototype();
+DEF_GETTER(JSFunction, PrototypeRequiresRuntimeLookup, bool) {
+ return !has_prototype_property(isolate) ||
+ map(isolate).has_non_instance_prototype();
}
-HeapObject JSFunction::instance_prototype() {
- DCHECK(has_instance_prototype());
- if (has_initial_map()) return initial_map().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());
+ return HeapObject::cast(prototype_or_initial_map(isolate));
}
-Object JSFunction::prototype() {
- DCHECK(has_prototype());
+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().has_non_instance_prototype()) {
- Object prototype = map().GetConstructor();
+ 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());
- DCHECK(!prototype.IsFunctionTemplateInfo());
+ DCHECK(!prototype.IsMap(isolate));
+ DCHECK(!prototype.IsFunctionTemplateInfo(isolate));
return prototype;
}
- return instance_prototype();
+ return instance_prototype(isolate);
}
bool JSFunction::is_compiled() const {
@@ -711,8 +712,6 @@ void JSFunction::ResetIfBytecodeFlushed() {
}
}
-ACCESSORS(JSValue, value, Object, kValueOffset)
-
ACCESSORS(JSDate, value, Object, kValueOffset)
ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
ACCESSORS(JSDate, year, Object, kYearOffset)
@@ -738,12 +737,11 @@ int JSMessageObject::GetEndPosition() const {
}
MessageTemplate JSMessageObject::type() const {
- Object value = READ_FIELD(*this, kMessageTypeOffset);
- return MessageTemplateFromInt(Smi::ToInt(value));
+ return MessageTemplateFromInt(raw_type());
}
void JSMessageObject::set_type(MessageTemplate value) {
- WRITE_FIELD(*this, kMessageTypeOffset, Smi::FromInt(static_cast<int>(value)));
+ set_raw_type(static_cast<int>(value));
}
ACCESSORS(JSMessageObject, argument, Object, kArgumentsOffset)
@@ -754,143 +752,154 @@ ACCESSORS(JSMessageObject, bytecode_offset, Smi, kBytecodeOffsetOffset)
SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
SMI_ACCESSORS(JSMessageObject, error_level, kErrorLevelOffset)
+SMI_ACCESSORS(JSMessageObject, raw_type, kMessageTypeOffset)
-ElementsKind JSObject::GetElementsKind() const {
- ElementsKind kind = map().elements_kind();
+DEF_GETTER(JSObject, GetElementsKind, ElementsKind) {
+ ElementsKind kind = map(isolate).elements_kind();
#if VERIFY_HEAP && DEBUG
- FixedArrayBase fixed_array =
- FixedArrayBase::unchecked_cast(READ_FIELD(*this, kElementsOffset));
+ FixedArrayBase fixed_array = FixedArrayBase::unchecked_cast(
+ TaggedField<HeapObject, kElementsOffset>::load(isolate, *this));
// If a GC was caused while constructing this object, the elements
// pointer may point to a one pointer filler map.
- if (ElementsAreSafeToExamine()) {
- Map map = fixed_array.map();
+ if (ElementsAreSafeToExamine(isolate)) {
+ Map map = fixed_array.map(isolate);
if (IsSmiOrObjectElementsKind(kind)) {
- DCHECK(map == GetReadOnlyRoots().fixed_array_map() ||
- map == GetReadOnlyRoots().fixed_cow_array_map());
+ DCHECK(map == GetReadOnlyRoots(isolate).fixed_array_map() ||
+ map == GetReadOnlyRoots(isolate).fixed_cow_array_map());
} else if (IsDoubleElementsKind(kind)) {
- DCHECK(fixed_array.IsFixedDoubleArray() ||
- fixed_array == GetReadOnlyRoots().empty_fixed_array());
+ DCHECK(fixed_array.IsFixedDoubleArray(isolate) ||
+ fixed_array == GetReadOnlyRoots(isolate).empty_fixed_array());
} else if (kind == DICTIONARY_ELEMENTS) {
- DCHECK(fixed_array.IsFixedArray());
- DCHECK(fixed_array.IsNumberDictionary());
+ DCHECK(fixed_array.IsFixedArray(isolate));
+ DCHECK(fixed_array.IsNumberDictionary(isolate));
} else {
DCHECK(kind > DICTIONARY_ELEMENTS || IsFrozenOrSealedElementsKind(kind));
}
- DCHECK(!IsSloppyArgumentsElementsKind(kind) ||
- (elements().IsFixedArray() && elements().length() >= 2));
+ DCHECK(
+ !IsSloppyArgumentsElementsKind(kind) ||
+ (elements(isolate).IsFixedArray() && elements(isolate).length() >= 2));
}
#endif
return kind;
}
-bool JSObject::HasObjectElements() {
- return IsObjectElementsKind(GetElementsKind());
+DEF_GETTER(JSObject, GetElementsAccessor, ElementsAccessor*) {
+ return ElementsAccessor::ForKind(GetElementsKind(isolate));
+}
+
+DEF_GETTER(JSObject, HasObjectElements, bool) {
+ return IsObjectElementsKind(GetElementsKind(isolate));
}
-bool JSObject::HasSmiElements() { return IsSmiElementsKind(GetElementsKind()); }
+DEF_GETTER(JSObject, HasSmiElements, bool) {
+ return IsSmiElementsKind(GetElementsKind(isolate));
+}
-bool JSObject::HasSmiOrObjectElements() {
- return IsSmiOrObjectElementsKind(GetElementsKind());
+DEF_GETTER(JSObject, HasSmiOrObjectElements, bool) {
+ return IsSmiOrObjectElementsKind(GetElementsKind(isolate));
}
-bool JSObject::HasDoubleElements() {
- return IsDoubleElementsKind(GetElementsKind());
+DEF_GETTER(JSObject, HasDoubleElements, bool) {
+ return IsDoubleElementsKind(GetElementsKind(isolate));
}
-bool JSObject::HasHoleyElements() {
- return IsHoleyElementsKind(GetElementsKind());
+DEF_GETTER(JSObject, HasHoleyElements, bool) {
+ return IsHoleyElementsKind(GetElementsKind(isolate));
}
-bool JSObject::HasFastElements() {
- return IsFastElementsKind(GetElementsKind());
+DEF_GETTER(JSObject, HasFastElements, bool) {
+ return IsFastElementsKind(GetElementsKind(isolate));
}
-bool JSObject::HasFastPackedElements() {
- return IsFastPackedElementsKind(GetElementsKind());
+DEF_GETTER(JSObject, HasFastPackedElements, bool) {
+ return IsFastPackedElementsKind(GetElementsKind(isolate));
}
-bool JSObject::HasDictionaryElements() {
- return GetElementsKind() == DICTIONARY_ELEMENTS;
+DEF_GETTER(JSObject, HasDictionaryElements, bool) {
+ return GetElementsKind(isolate) == DICTIONARY_ELEMENTS;
}
-bool JSObject::HasPackedElements() {
- return GetElementsKind() == PACKED_ELEMENTS;
+DEF_GETTER(JSObject, HasPackedElements, bool) {
+ return GetElementsKind(isolate) == PACKED_ELEMENTS;
}
-bool JSObject::HasFrozenOrSealedElements() {
- return IsFrozenOrSealedElementsKind(GetElementsKind());
+DEF_GETTER(JSObject, HasFrozenOrSealedElements, bool) {
+ return IsFrozenOrSealedElementsKind(GetElementsKind(isolate));
}
-bool JSObject::HasSealedElements() {
- return IsSealedElementsKind(GetElementsKind());
+DEF_GETTER(JSObject, HasSealedElements, bool) {
+ return IsSealedElementsKind(GetElementsKind(isolate));
}
-bool JSObject::HasFastArgumentsElements() {
- return GetElementsKind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS;
+DEF_GETTER(JSObject, HasFastArgumentsElements, bool) {
+ return GetElementsKind(isolate) == FAST_SLOPPY_ARGUMENTS_ELEMENTS;
}
-bool JSObject::HasSlowArgumentsElements() {
- return GetElementsKind() == SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
+DEF_GETTER(JSObject, HasSlowArgumentsElements, bool) {
+ return GetElementsKind(isolate) == SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
}
-bool JSObject::HasSloppyArgumentsElements() {
- return IsSloppyArgumentsElementsKind(GetElementsKind());
+DEF_GETTER(JSObject, HasSloppyArgumentsElements, bool) {
+ return IsSloppyArgumentsElementsKind(GetElementsKind(isolate));
}
-bool JSObject::HasStringWrapperElements() {
- return IsStringWrapperElementsKind(GetElementsKind());
+DEF_GETTER(JSObject, HasStringWrapperElements, bool) {
+ return IsStringWrapperElementsKind(GetElementsKind(isolate));
}
-bool JSObject::HasFastStringWrapperElements() {
- return GetElementsKind() == FAST_STRING_WRAPPER_ELEMENTS;
+DEF_GETTER(JSObject, HasFastStringWrapperElements, bool) {
+ return GetElementsKind(isolate) == FAST_STRING_WRAPPER_ELEMENTS;
}
-bool JSObject::HasSlowStringWrapperElements() {
- return GetElementsKind() == SLOW_STRING_WRAPPER_ELEMENTS;
+DEF_GETTER(JSObject, HasSlowStringWrapperElements, bool) {
+ return GetElementsKind(isolate) == SLOW_STRING_WRAPPER_ELEMENTS;
}
-bool JSObject::HasTypedArrayElements() {
- DCHECK(!elements().is_null());
- return map().has_typed_array_elements();
+DEF_GETTER(JSObject, HasTypedArrayElements, bool) {
+ DCHECK(!elements(isolate).is_null());
+ return map(isolate).has_typed_array_elements();
}
#define FIXED_TYPED_ELEMENTS_CHECK(Type, type, TYPE, ctype) \
- bool JSObject::HasFixed##Type##Elements() { \
- return map().elements_kind() == TYPE##_ELEMENTS; \
+ DEF_GETTER(JSObject, HasFixed##Type##Elements, bool) { \
+ return map(isolate).elements_kind() == TYPE##_ELEMENTS; \
}
TYPED_ARRAYS(FIXED_TYPED_ELEMENTS_CHECK)
#undef FIXED_TYPED_ELEMENTS_CHECK
-bool JSObject::HasNamedInterceptor() { return map().has_named_interceptor(); }
+DEF_GETTER(JSObject, HasNamedInterceptor, bool) {
+ return map(isolate).has_named_interceptor();
+}
-bool JSObject::HasIndexedInterceptor() {
- return map().has_indexed_interceptor();
+DEF_GETTER(JSObject, HasIndexedInterceptor, bool) {
+ return map(isolate).has_indexed_interceptor();
}
-void JSGlobalObject::set_global_dictionary(GlobalDictionary dictionary) {
- DCHECK(IsJSGlobalObject());
- set_raw_properties_or_hash(dictionary);
+DEF_GETTER(JSGlobalObject, global_dictionary, GlobalDictionary) {
+ DCHECK(!HasFastProperties(isolate));
+ DCHECK(IsJSGlobalObject(isolate));
+ return GlobalDictionary::cast(raw_properties_or_hash(isolate));
}
-GlobalDictionary JSGlobalObject::global_dictionary() {
- DCHECK(!HasFastProperties());
+void JSGlobalObject::set_global_dictionary(GlobalDictionary dictionary) {
DCHECK(IsJSGlobalObject());
- return GlobalDictionary::cast(raw_properties_or_hash());
+ set_raw_properties_or_hash(dictionary);
}
-NumberDictionary JSObject::element_dictionary() {
- DCHECK(HasDictionaryElements() || HasSlowStringWrapperElements());
- return NumberDictionary::cast(elements());
+DEF_GETTER(JSObject, element_dictionary, NumberDictionary) {
+ DCHECK(HasDictionaryElements(isolate) ||
+ HasSlowStringWrapperElements(isolate));
+ return NumberDictionary::cast(elements(isolate));
}
-void JSReceiver::initialize_properties() {
- ReadOnlyRoots roots = GetReadOnlyRoots();
+void JSReceiver::initialize_properties(Isolate* isolate) {
+ ReadOnlyRoots roots(isolate);
DCHECK(!ObjectInYoungGeneration(roots.empty_fixed_array()));
DCHECK(!ObjectInYoungGeneration(roots.empty_property_dictionary()));
- if (map().is_dictionary_map()) {
+ if (map(isolate).is_dictionary_map()) {
WRITE_FIELD(*this, kPropertiesOrHashOffset,
roots.empty_property_dictionary());
} else {
@@ -898,36 +907,36 @@ void JSReceiver::initialize_properties() {
}
}
-bool JSReceiver::HasFastProperties() const {
- DCHECK(raw_properties_or_hash().IsSmi() ||
- ((raw_properties_or_hash().IsGlobalDictionary() ||
- raw_properties_or_hash().IsNameDictionary()) ==
- map().is_dictionary_map()));
- return !map().is_dictionary_map();
+DEF_GETTER(JSReceiver, HasFastProperties, bool) {
+ DCHECK(raw_properties_or_hash(isolate).IsSmi() ||
+ ((raw_properties_or_hash(isolate).IsGlobalDictionary(isolate) ||
+ raw_properties_or_hash(isolate).IsNameDictionary(isolate)) ==
+ map(isolate).is_dictionary_map()));
+ return !map(isolate).is_dictionary_map();
}
-NameDictionary JSReceiver::property_dictionary() const {
- DCHECK(!IsJSGlobalObject());
- DCHECK(!HasFastProperties());
-
- Object prop = raw_properties_or_hash();
+DEF_GETTER(JSReceiver, property_dictionary, NameDictionary) {
+ DCHECK(!IsJSGlobalObject(isolate));
+ DCHECK(!HasFastProperties(isolate));
+ // Can't use ReadOnlyRoots(isolate) as this isolate could be produced by
+ // i::GetIsolateForPtrCompr(HeapObject).
+ Object prop = raw_properties_or_hash(isolate);
if (prop.IsSmi()) {
- return GetReadOnlyRoots().empty_property_dictionary();
+ return GetReadOnlyRoots(isolate).empty_property_dictionary();
}
-
return NameDictionary::cast(prop);
}
// TODO(gsathya): Pass isolate directly to this function and access
// the heap from this.
-PropertyArray JSReceiver::property_array() const {
- DCHECK(HasFastProperties());
-
- Object prop = raw_properties_or_hash();
- if (prop.IsSmi() || prop == GetReadOnlyRoots().empty_fixed_array()) {
- return GetReadOnlyRoots().empty_property_array();
+DEF_GETTER(JSReceiver, property_array, PropertyArray) {
+ DCHECK(HasFastProperties(isolate));
+ // Can't use ReadOnlyRoots(isolate) as this isolate could be produced by
+ // i::GetIsolateForPtrCompr(HeapObject).
+ Object prop = raw_properties_or_hash(isolate);
+ if (prop.IsSmi() || prop == GetReadOnlyRoots(isolate).empty_fixed_array()) {
+ return GetReadOnlyRoots(isolate).empty_property_array();
}
-
return PropertyArray::cast(prop);
}
diff --git a/deps/v8/src/objects/js-objects.cc b/deps/v8/src/objects/js-objects.cc
index 317837a99f..5c4db16206 100644
--- a/deps/v8/src/objects/js-objects.cc
+++ b/deps/v8/src/objects/js-objects.cc
@@ -8,6 +8,7 @@
#include "src/codegen/compiler.h"
#include "src/date/date.h"
#include "src/execution/arguments.h"
+#include "src/execution/frames.h"
#include "src/execution/isolate.h"
#include "src/handles/handles-inl.h"
#include "src/handles/maybe-handles.h"
@@ -194,15 +195,16 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastAssign(
return Just(!source->IsString() || String::cast(*source).length() == 0);
}
+ Isolate* isolate = target->GetIsolate();
+
// If the target is deprecated, the object will be updated on first store. If
// the source for that store equals the target, this will invalidate the
// cached representation of the source. Preventively upgrade the target.
// Do this on each iteration since any property load could cause deprecation.
if (target->map().is_deprecated()) {
- JSObject::MigrateInstance(Handle<JSObject>::cast(target));
+ JSObject::MigrateInstance(isolate, Handle<JSObject>::cast(target));
}
- Isolate* isolate = target->GetIsolate();
Handle<Map> map(JSReceiver::cast(*source).map(), isolate);
if (!map->IsJSObjectMap()) return Just(false);
@@ -374,8 +376,8 @@ String JSReceiver::class_name() {
TYPED_ARRAYS(SWITCH_KIND)
#undef SWITCH_KIND
}
- if (IsJSValue()) {
- Object value = JSValue::cast(*this).value();
+ if (IsJSPrimitiveWrapper()) {
+ Object value = JSPrimitiveWrapper::cast(*this).value();
if (value.IsBoolean()) return roots.Boolean_string();
if (value.IsString()) return roots.String_string();
if (value.IsNumber()) return roots.Number_string();
@@ -1092,7 +1094,8 @@ Maybe<bool> SetPropertyWithInterceptorInternal(
Maybe<bool> DefinePropertyWithInterceptorInternal(
LookupIterator* it, Handle<InterceptorInfo> interceptor,
- Maybe<ShouldThrow> should_throw, PropertyDescriptor& desc) {
+ Maybe<ShouldThrow> should_throw,
+ PropertyDescriptor& desc) { // NOLINT(runtime/references)
Isolate* isolate = it->isolate();
// Make sure that the top context does not change when doing callbacks or
// interceptor calls.
@@ -1827,6 +1830,13 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastGetOwnValuesOrEntries(
int number_of_own_descriptors = map->NumberOfOwnDescriptors();
int number_of_own_elements =
object->GetElementsAccessor()->GetCapacity(*object, object->elements());
+
+ if (number_of_own_elements >
+ FixedArray::kMaxLength - number_of_own_descriptors) {
+ isolate->Throw(*isolate->factory()->NewRangeError(
+ MessageTemplate::kInvalidArrayLength));
+ return Nothing<bool>();
+ }
Handle<FixedArray> values_or_entries = isolate->factory()->NewFixedArray(
number_of_own_descriptors + number_of_own_elements);
int count = 0;
@@ -1918,7 +1928,8 @@ MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate,
int length = 0;
for (int i = 0; i < keys->length(); ++i) {
- Handle<Name> key = Handle<Name>::cast(handle(keys->get(i), isolate));
+ Handle<Name> key =
+ Handle<Name>::cast(handle(keys->get(isolate, i), isolate));
if (filter & ONLY_ENUMERABLE) {
PropertyDescriptor descriptor;
@@ -2002,13 +2013,9 @@ MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor,
ASSIGN_RETURN_ON_EXCEPTION(
isolate, initial_map,
JSFunction::GetDerivedMap(isolate, constructor, new_target), JSObject);
- Handle<JSObject> result = isolate->factory()->NewJSObjectFromMap(
- initial_map, AllocationType::kYoung, site);
- if (initial_map->is_dictionary_map()) {
- Handle<NameDictionary> dictionary =
- NameDictionary::New(isolate, NameDictionary::kInitialCapacity);
- result->SetProperties(*dictionary);
- }
+ Handle<JSObject> result = isolate->factory()->NewFastOrSlowJSObjectFromMap(
+ initial_map, NameDictionary::kInitialCapacity, AllocationType::kYoung,
+ site);
isolate->counters()->constructed_objects()->Increment();
isolate->counters()->constructed_objects_runtime()->Increment();
return result;
@@ -2026,13 +2033,7 @@ MaybeHandle<JSObject> JSObject::ObjectCreate(Isolate* isolate,
Map::GetObjectCreateMap(isolate, Handle<HeapObject>::cast(prototype));
// Actually allocate the object.
- Handle<JSObject> object;
- if (map->is_dictionary_map()) {
- object = isolate->factory()->NewSlowJSObjectFromMap(map);
- } else {
- object = isolate->factory()->NewJSObjectFromMap(map);
- }
- return object;
+ return isolate->factory()->NewFastOrSlowJSObjectFromMap(map);
}
void JSObject::EnsureWritableFastElements(Handle<JSObject> object) {
@@ -2072,8 +2073,8 @@ int JSObject::GetHeaderSize(InstanceType type,
return JSBoundFunction::kSize;
case JS_FUNCTION_TYPE:
return JSFunction::GetHeaderSize(function_has_prototype_slot);
- case JS_VALUE_TYPE:
- return JSValue::kSize;
+ case JS_PRIMITIVE_WRAPPER_TYPE:
+ return JSPrimitiveWrapper::kSize;
case JS_DATE_TYPE:
return JSDate::kSize;
case JS_ARRAY_TYPE:
@@ -2423,7 +2424,7 @@ void JSObject::JSObjectShortPrint(StringStream* accumulator) {
}
// All other JSObjects are rather similar to each other (JSObject,
- // JSGlobalProxy, JSGlobalObject, JSUndetectable, JSValue).
+ // JSGlobalProxy, JSGlobalObject, JSUndetectable, JSPrimitiveWrapper).
default: {
Map map_of_this = map();
Heap* heap = GetHeap();
@@ -2457,9 +2458,9 @@ void JSObject::JSObjectShortPrint(StringStream* accumulator) {
accumulator->Add("<JS%sObject", global_object ? "Global " : "");
}
}
- if (IsJSValue()) {
+ if (IsJSPrimitiveWrapper()) {
accumulator->Add(" value = ");
- JSValue::cast(*this).value().ShortPrint(accumulator);
+ JSPrimitiveWrapper::cast(*this).value().ShortPrint(accumulator);
}
accumulator->Put('>');
break;
@@ -2595,11 +2596,11 @@ namespace {
// to temporarily store the inobject properties.
// * If there are properties left in the backing store, install the backing
// store.
-void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
- Isolate* isolate = object->GetIsolate();
+void MigrateFastToFast(Isolate* isolate, Handle<JSObject> object,
+ Handle<Map> new_map) {
Handle<Map> old_map(object->map(), isolate);
// In case of a regular transition.
- if (new_map->GetBackPointer() == *old_map) {
+ if (new_map->GetBackPointer(isolate) == *old_map) {
// If the map does not add named properties, simply set the map.
if (old_map->NumberOfOwnDescriptors() ==
new_map->NumberOfOwnDescriptors()) {
@@ -2608,7 +2609,7 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
}
// If the map adds a new kDescriptor property, simply set the map.
- PropertyDetails details = new_map->GetLastDescriptorDetails();
+ PropertyDetails details = new_map->GetLastDescriptorDetails(isolate);
if (details.location() == kDescriptor) {
object->synchronized_set_map(*new_map);
return;
@@ -2618,14 +2619,14 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
// can also simply set the map (modulo a special case for mutable
// double boxes).
FieldIndex index =
- FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
- if (index.is_inobject() ||
- index.outobject_array_index() < object->property_array().length()) {
+ FieldIndex::ForDescriptor(isolate, *new_map, new_map->LastAdded());
+ if (index.is_inobject() || index.outobject_array_index() <
+ object->property_array(isolate).length()) {
// We still need to allocate MutableHeapNumbers for double fields
// if either double field unboxing is disabled or the double field
// is in the PropertyArray backing store (where we don't support
// double field unboxing).
- if (index.is_double() && !new_map->IsUnboxedDoubleField(index)) {
+ if (index.is_double() && !new_map->IsUnboxedDoubleField(isolate, index)) {
auto value = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
object->RawFastPropertyAtPut(index, *value);
}
@@ -2636,7 +2637,7 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
// This migration is a transition from a map that has run out of property
// space. Extend the backing store.
int grow_by = new_map->UnusedPropertyFields() + 1;
- Handle<PropertyArray> old_storage(object->property_array(), isolate);
+ Handle<PropertyArray> old_storage(object->property_array(isolate), isolate);
Handle<PropertyArray> new_storage =
isolate->factory()->CopyPropertyArrayAndGrow(old_storage, grow_by);
@@ -2682,10 +2683,10 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
Handle<FixedArray> inobject_props =
isolate->factory()->NewFixedArray(inobject);
- Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors(),
- isolate);
- Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors(),
- isolate);
+ Handle<DescriptorArray> old_descriptors(
+ old_map->instance_descriptors(isolate), isolate);
+ Handle<DescriptorArray> new_descriptors(
+ new_map->instance_descriptors(isolate), isolate);
int old_nof = old_map->NumberOfOwnDescriptors();
int new_nof = new_map->NumberOfOwnDescriptors();
@@ -2713,13 +2714,13 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
}
} else {
DCHECK_EQ(kData, old_details.kind());
- value = handle(old_descriptors->GetStrongValue(i), isolate);
+ value = handle(old_descriptors->GetStrongValue(isolate, i), isolate);
DCHECK(!old_representation.IsDouble() && !representation.IsDouble());
}
} else {
DCHECK_EQ(kField, old_details.location());
- FieldIndex index = FieldIndex::ForDescriptor(*old_map, i);
- if (object->IsUnboxedDoubleField(index)) {
+ FieldIndex index = FieldIndex::ForDescriptor(isolate, *old_map, i);
+ if (object->IsUnboxedDoubleField(isolate, index)) {
uint64_t old_bits = object->RawFastDoublePropertyAsBitsAt(index);
if (representation.IsDouble()) {
value = isolate->factory()->NewMutableHeapNumberFromBits(old_bits);
@@ -2727,7 +2728,7 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
value = isolate->factory()->NewHeapNumberFromBits(old_bits);
}
} else {
- value = handle(object->RawFastPropertyAt(index), isolate);
+ value = handle(object->RawFastPropertyAt(isolate, index), isolate);
if (!old_representation.IsDouble() && representation.IsDouble()) {
DCHECK_IMPLIES(old_representation.IsNone(),
value->IsUninitialized(isolate));
@@ -2779,11 +2780,11 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
int limit = Min(inobject, number_of_fields);
for (int i = 0; i < limit; i++) {
FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
- Object value = inobject_props->get(i);
+ Object value = inobject_props->get(isolate, i);
// Can't use JSObject::FastPropertyAtPut() because proper map was not set
// yet.
- if (new_map->IsUnboxedDoubleField(index)) {
- DCHECK(value.IsMutableHeapNumber());
+ if (new_map->IsUnboxedDoubleField(isolate, index)) {
+ DCHECK(value.IsMutableHeapNumber(isolate));
// Ensure that all bits of the double value are preserved.
object->RawFastDoublePropertyAsBitsAtPut(
index, MutableHeapNumber::cast(value).value_as_bits());
@@ -2818,19 +2819,19 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
object->synchronized_set_map(*new_map);
}
-void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
+void MigrateFastToSlow(Isolate* isolate, Handle<JSObject> object,
+ Handle<Map> new_map,
int expected_additional_properties) {
// The global object is always normalized.
- DCHECK(!object->IsJSGlobalObject());
+ DCHECK(!object->IsJSGlobalObject(isolate));
// JSGlobalProxy must never be normalized
- DCHECK(!object->IsJSGlobalProxy());
+ DCHECK(!object->IsJSGlobalProxy(isolate));
DCHECK_IMPLIES(new_map->is_prototype_map(),
Map::IsPrototypeChainInvalidated(*new_map));
- Isolate* isolate = object->GetIsolate();
HandleScope scope(isolate);
- Handle<Map> map(object->map(), isolate);
+ Handle<Map> map(object->map(isolate), isolate);
// Allocate new content.
int real_size = map->NumberOfOwnDescriptors();
@@ -2844,33 +2845,33 @@ void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
Handle<NameDictionary> dictionary =
NameDictionary::New(isolate, property_count);
- Handle<DescriptorArray> descs(map->instance_descriptors(), isolate);
+ Handle<DescriptorArray> descs(map->instance_descriptors(isolate), isolate);
for (int i = 0; i < real_size; i++) {
PropertyDetails details = descs->GetDetails(i);
- Handle<Name> key(descs->GetKey(i), isolate);
+ Handle<Name> key(descs->GetKey(isolate, i), isolate);
Handle<Object> value;
if (details.location() == kField) {
- FieldIndex index = FieldIndex::ForDescriptor(*map, i);
+ FieldIndex index = FieldIndex::ForDescriptor(isolate, *map, i);
if (details.kind() == kData) {
- if (object->IsUnboxedDoubleField(index)) {
+ if (object->IsUnboxedDoubleField(isolate, index)) {
double old_value = object->RawFastDoublePropertyAt(index);
value = isolate->factory()->NewHeapNumber(old_value);
} else {
- value = handle(object->RawFastPropertyAt(index), isolate);
+ value = handle(object->RawFastPropertyAt(isolate, index), isolate);
if (details.representation().IsDouble()) {
- DCHECK(value->IsMutableHeapNumber());
+ DCHECK(value->IsMutableHeapNumber(isolate));
double old_value = Handle<MutableHeapNumber>::cast(value)->value();
value = isolate->factory()->NewHeapNumber(old_value);
}
}
} else {
DCHECK_EQ(kAccessor, details.kind());
- value = handle(object->RawFastPropertyAt(index), isolate);
+ value = handle(object->RawFastPropertyAt(isolate, index), isolate);
}
} else {
DCHECK_EQ(kDescriptor, details.location());
- value = handle(descs->GetStrongValue(i), isolate);
+ value = handle(descs->GetStrongValue(isolate, i), isolate);
}
DCHECK(!value.is_null());
PropertyDetails d(details.kind(), details.attributes(),
@@ -2932,11 +2933,12 @@ void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
} // namespace
-void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
+void JSObject::MigrateToMap(Isolate* isolate, Handle<JSObject> object,
+ Handle<Map> new_map,
int expected_additional_properties) {
- if (object->map() == *new_map) return;
- Handle<Map> old_map(object->map(), object->GetIsolate());
- NotifyMapChange(old_map, new_map, object->GetIsolate());
+ if (object->map(isolate) == *new_map) return;
+ Handle<Map> old_map(object->map(isolate), isolate);
+ NotifyMapChange(old_map, new_map, isolate);
if (old_map->is_dictionary_map()) {
// For slow-to-fast migrations JSObject::MigrateSlowToFast()
@@ -2946,7 +2948,7 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
// Slow-to-slow migration is trivial.
object->synchronized_set_map(*new_map);
} else if (!new_map->is_dictionary_map()) {
- MigrateFastToFast(object, new_map);
+ MigrateFastToFast(isolate, object, new_map);
if (old_map->is_prototype_map()) {
DCHECK(!old_map->is_stable());
DCHECK(new_map->is_stable());
@@ -2958,13 +2960,12 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
old_map->set_owns_descriptors(false);
DCHECK(old_map->is_abandoned_prototype_map());
// Ensure that no transition was inserted for prototype migrations.
- DCHECK_EQ(0, TransitionsAccessor(object->GetIsolate(), old_map)
- .NumberOfTransitions());
- DCHECK(new_map->GetBackPointer().IsUndefined());
- DCHECK(object->map() != *old_map);
+ DCHECK_EQ(0, TransitionsAccessor(isolate, old_map).NumberOfTransitions());
+ DCHECK(new_map->GetBackPointer(isolate).IsUndefined(isolate));
+ DCHECK(object->map(isolate) != *old_map);
}
} else {
- MigrateFastToSlow(object, new_map, expected_additional_properties);
+ MigrateFastToSlow(isolate, object, new_map, expected_additional_properties);
}
// Careful: Don't allocate here!
@@ -2978,11 +2979,11 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
void JSObject::ForceSetPrototype(Handle<JSObject> object,
Handle<HeapObject> proto) {
// object.__proto__ = proto;
- Handle<Map> old_map = Handle<Map>(object->map(), object->GetIsolate());
- Handle<Map> new_map =
- Map::Copy(object->GetIsolate(), old_map, "ForceSetPrototype");
- Map::SetPrototype(object->GetIsolate(), new_map, proto);
- JSObject::MigrateToMap(object, new_map);
+ Isolate* isolate = object->GetIsolate();
+ Handle<Map> old_map = Handle<Map>(object->map(), isolate);
+ Handle<Map> new_map = Map::Copy(isolate, old_map, "ForceSetPrototype");
+ Map::SetPrototype(isolate, new_map, proto);
+ JSObject::MigrateToMap(isolate, object, new_map);
}
Maybe<bool> JSObject::SetPropertyWithInterceptor(
@@ -3068,31 +3069,30 @@ void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
object->synchronized_set_map(*map);
}
-void JSObject::MigrateInstance(Handle<JSObject> object) {
- Handle<Map> original_map(object->map(), object->GetIsolate());
- Handle<Map> map = Map::Update(object->GetIsolate(), original_map);
+void JSObject::MigrateInstance(Isolate* isolate, Handle<JSObject> object) {
+ Handle<Map> original_map(object->map(), isolate);
+ Handle<Map> map = Map::Update(isolate, original_map);
map->set_is_migration_target(true);
- MigrateToMap(object, map);
+ JSObject::MigrateToMap(isolate, object, map);
if (FLAG_trace_migration) {
object->PrintInstanceMigration(stdout, *original_map, *map);
}
#if VERIFY_HEAP
if (FLAG_verify_heap) {
- object->JSObjectVerify(object->GetIsolate());
+ object->JSObjectVerify(isolate);
}
#endif
}
// static
-bool JSObject::TryMigrateInstance(Handle<JSObject> object) {
- Isolate* isolate = object->GetIsolate();
+bool JSObject::TryMigrateInstance(Isolate* isolate, Handle<JSObject> object) {
DisallowDeoptimization no_deoptimization(isolate);
Handle<Map> original_map(object->map(), isolate);
Handle<Map> new_map;
if (!Map::TryUpdate(isolate, original_map).ToHandle(&new_map)) {
return false;
}
- JSObject::MigrateToMap(object, new_map);
+ JSObject::MigrateToMap(isolate, object, new_map);
if (FLAG_trace_migration && *original_map != object->map()) {
object->PrintInstanceMigration(stdout, *original_map, object->map());
}
@@ -3263,16 +3263,18 @@ Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
return GetPropertyAttributesWithInterceptorInternal(it, it->GetInterceptor());
}
-void JSObject::NormalizeProperties(Handle<JSObject> object,
+void JSObject::NormalizeProperties(Isolate* isolate, Handle<JSObject> object,
PropertyNormalizationMode mode,
int expected_additional_properties,
const char* reason) {
if (!object->HasFastProperties()) return;
- Handle<Map> map(object->map(), object->GetIsolate());
- Handle<Map> new_map = Map::Normalize(object->GetIsolate(), map, mode, reason);
+ Handle<Map> map(object->map(), isolate);
+ Handle<Map> new_map =
+ Map::Normalize(isolate, map, map->elements_kind(), mode, reason);
- MigrateToMap(object, new_map, expected_additional_properties);
+ JSObject::MigrateToMap(isolate, object, new_map,
+ expected_additional_properties);
}
void JSObject::MigrateSlowToFast(Handle<JSObject> object,
@@ -3475,7 +3477,7 @@ Handle<NumberDictionary> JSObject::NormalizeElements(Handle<JSObject> object) {
: DICTIONARY_ELEMENTS;
Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind);
// Set the new map first to satify the elements type assert in set_elements().
- JSObject::MigrateToMap(object, new_map);
+ JSObject::MigrateToMap(isolate, object, new_map);
if (is_sloppy_arguments) {
SloppyArgumentsElements::cast(object->elements())
@@ -3710,7 +3712,7 @@ Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object,
Map::Copy(isolate, handle(object->map(), isolate), "PreventExtensions");
new_map->set_is_extensible(false);
- JSObject::MigrateToMap(object, new_map);
+ JSObject::MigrateToMap(isolate, object, new_map);
DCHECK(!object->map().is_extensible());
return Just(true);
@@ -3756,6 +3758,21 @@ template void JSObject::ApplyAttributesToDictionary(
Isolate* isolate, ReadOnlyRoots roots, Handle<NumberDictionary> dictionary,
const PropertyAttributes attributes);
+Handle<NumberDictionary> CreateElementDictionary(Isolate* isolate,
+ Handle<JSObject> object) {
+ Handle<NumberDictionary> new_element_dictionary;
+ if (!object->HasTypedArrayElements() && !object->HasDictionaryElements() &&
+ !object->HasSlowStringWrapperElements()) {
+ int length = object->IsJSArray()
+ ? Smi::ToInt(Handle<JSArray>::cast(object)->length())
+ : object->elements().length();
+ new_element_dictionary =
+ length == 0 ? isolate->factory()->empty_slow_element_dictionary()
+ : object->GetElementsAccessor()->Normalize(object);
+ }
+ return new_element_dictionary;
+}
+
template <PropertyAttributes attrs>
Maybe<bool> JSObject::PreventExtensionsWithTransition(
Handle<JSObject> object, ShouldThrow should_throw) {
@@ -3776,10 +3793,12 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
}
if (attrs == NONE && !object->map().is_extensible()) return Just(true);
- ElementsKind old_elements_kind = object->map().elements_kind();
- if (attrs != FROZEN && IsSealedElementsKind(old_elements_kind))
- return Just(true);
- if (old_elements_kind == PACKED_FROZEN_ELEMENTS) return Just(true);
+ {
+ ElementsKind old_elements_kind = object->map().elements_kind();
+ if (attrs != FROZEN && IsSealedElementsKind(old_elements_kind))
+ return Just(true);
+ if (old_elements_kind == PACKED_FROZEN_ELEMENTS) return Just(true);
+ }
if (object->IsJSGlobalProxy()) {
PrototypeIterator iter(isolate, object);
@@ -3808,17 +3827,6 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
RETURN_FAILURE(isolate, should_throw, NewTypeError(message));
}
- Handle<NumberDictionary> new_element_dictionary;
- if (!object->HasTypedArrayElements() && !object->HasDictionaryElements() &&
- !object->HasSlowStringWrapperElements()) {
- int length = object->IsJSArray()
- ? Smi::ToInt(Handle<JSArray>::cast(object)->length())
- : object->elements().length();
- new_element_dictionary =
- length == 0 ? isolate->factory()->empty_slow_element_dictionary()
- : object->GetElementsAccessor()->Normalize(object);
- }
-
Handle<Symbol> transition_marker;
if (attrs == NONE) {
transition_marker = isolate->factory()->nonextensible_symbol();
@@ -3829,6 +3837,31 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
transition_marker = isolate->factory()->frozen_symbol();
}
+ // Currently, there are only have sealed/frozen Object element kinds and
+ // Map::MigrateToMap doesn't handle properties' attributes reconfiguring and
+ // elements kind change in one go. If seal or freeze with Smi or Double
+ // elements kind, we will transition to Object elements kind first to make
+ // sure of valid element access.
+ if (FLAG_enable_sealed_frozen_elements_kind &&
+ (attrs == SEALED || attrs == FROZEN)) {
+ switch (object->map().elements_kind()) {
+ case PACKED_SMI_ELEMENTS:
+ case PACKED_DOUBLE_ELEMENTS:
+ JSObject::TransitionElementsKind(object, PACKED_ELEMENTS);
+ break;
+ case HOLEY_SMI_ELEMENTS:
+ case HOLEY_DOUBLE_ELEMENTS:
+ JSObject::TransitionElementsKind(object, HOLEY_ELEMENTS);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Make sure we only use this element dictionary in case we can't transition
+ // to sealed, frozen elements kind.
+ Handle<NumberDictionary> new_element_dictionary;
+
Handle<Map> old_map(object->map(), isolate);
old_map = Map::Update(isolate, old_map);
TransitionsAccessor transitions(isolate, old_map);
@@ -3840,16 +3873,22 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
transition_map->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS ||
transition_map->has_frozen_or_sealed_elements());
DCHECK(!transition_map->is_extensible());
- JSObject::MigrateToMap(object, transition_map);
+ if (!transition_map->has_frozen_or_sealed_elements()) {
+ new_element_dictionary = CreateElementDictionary(isolate, object);
+ }
+ JSObject::MigrateToMap(isolate, object, transition_map);
} else if (transitions.CanHaveMoreTransitions()) {
// Create a new descriptor array with the appropriate property attributes
Handle<Map> new_map = Map::CopyForPreventExtensions(
isolate, old_map, attrs, transition_marker, "CopyForPreventExtensions");
- JSObject::MigrateToMap(object, new_map);
+ if (!new_map->has_frozen_or_sealed_elements()) {
+ new_element_dictionary = CreateElementDictionary(isolate, object);
+ }
+ JSObject::MigrateToMap(isolate, object, new_map);
} else {
DCHECK(old_map->is_dictionary_map() || !old_map->is_prototype_map());
// Slow path: need to normalize properties for safety
- NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0,
+ NormalizeProperties(isolate, object, CLEAR_INOBJECT_PROPERTIES, 0,
"SlowPreventExtensions");
// Create a new map, since other objects with this map may be extensible.
@@ -3857,6 +3896,7 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
Handle<Map> new_map = Map::Copy(isolate, handle(object->map(), isolate),
"SlowCopyForPreventExtensions");
new_map->set_is_extensible(false);
+ new_element_dictionary = CreateElementDictionary(isolate, object);
if (!new_element_dictionary.is_null()) {
ElementsKind new_kind =
IsStringWrapperElementsKind(old_map->elements_kind())
@@ -3864,7 +3904,7 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
: DICTIONARY_ELEMENTS;
new_map->set_elements_kind(new_kind);
}
- JSObject::MigrateToMap(object, new_map);
+ JSObject::MigrateToMap(isolate, object, new_map);
if (attrs != NONE) {
ReadOnlyRoots roots(isolate);
@@ -3883,6 +3923,7 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
}
if (object->map().has_frozen_or_sealed_elements()) {
+ DCHECK(new_element_dictionary.is_null());
return Just(true);
}
@@ -3990,7 +4031,7 @@ bool JSObject::HasEnumerableElements() {
return true;
case FAST_STRING_WRAPPER_ELEMENTS:
case SLOW_STRING_WRAPPER_ELEMENTS:
- if (String::cast(JSValue::cast(object).value()).length() > 0) {
+ if (String::cast(JSPrimitiveWrapper::cast(object).value()).length() > 0) {
return true;
}
return object.elements().length() > 0;
@@ -4177,10 +4218,11 @@ static bool PrototypeBenefitsFromNormalization(Handle<JSObject> object) {
// static
void JSObject::OptimizeAsPrototype(Handle<JSObject> object,
bool enable_setup_mode) {
+ Isolate* isolate = object->GetIsolate();
if (object->IsJSGlobalObject()) return;
if (enable_setup_mode && PrototypeBenefitsFromNormalization(object)) {
// First normalize to ensure all JSFunctions are DATA_CONSTANT.
- JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0,
+ JSObject::NormalizeProperties(isolate, object, KEEP_INOBJECT_PROPERTIES, 0,
"NormalizeAsPrototype");
}
if (object->map().is_prototype_map()) {
@@ -4189,10 +4231,9 @@ void JSObject::OptimizeAsPrototype(Handle<JSObject> object,
JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype");
}
} else {
- Handle<Map> new_map = Map::Copy(object->GetIsolate(),
- handle(object->map(), object->GetIsolate()),
- "CopyAsPrototype");
- JSObject::MigrateToMap(object, new_map);
+ Handle<Map> new_map =
+ Map::Copy(isolate, handle(object->map(), isolate), "CopyAsPrototype");
+ JSObject::MigrateToMap(isolate, object, new_map);
object->map().set_is_prototype_map(true);
// Replace the pointer to the exact constructor with the Object function
@@ -4451,7 +4492,7 @@ Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
Handle<Map> new_map =
Map::TransitionToPrototype(isolate, map, Handle<HeapObject>::cast(value));
DCHECK(new_map->prototype() == *value);
- JSObject::MigrateToMap(real_receiver, new_map);
+ JSObject::MigrateToMap(isolate, real_receiver, new_map);
DCHECK(size == object->Size());
return Just(true);
@@ -4481,10 +4522,6 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object,
object, args->slot_at(first_arg + arg_count - 1), arg_count, mode);
}
-ElementsAccessor* JSObject::GetElementsAccessor() {
- return ElementsAccessor::ForKind(GetElementsKind());
-}
-
void JSObject::ValidateElements(JSObject object) {
#ifdef ENABLE_SLOW_DCHECKS
if (FLAG_enable_slow_asserts) {
@@ -4560,22 +4597,22 @@ static ElementsKind BestFittingFastElementsKind(JSObject object) {
void JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
Handle<Object> value,
PropertyAttributes attributes) {
- DCHECK(object->map().is_extensible());
-
Isolate* isolate = object->GetIsolate();
+ DCHECK(object->map(isolate).is_extensible());
+
uint32_t old_length = 0;
uint32_t new_capacity = 0;
- if (object->IsJSArray()) {
+ if (object->IsJSArray(isolate)) {
CHECK(JSArray::cast(*object).length().ToArrayLength(&old_length));
}
- ElementsKind kind = object->GetElementsKind();
- FixedArrayBase elements = object->elements();
+ ElementsKind kind = object->GetElementsKind(isolate);
+ FixedArrayBase elements = object->elements(isolate);
ElementsKind dictionary_kind = DICTIONARY_ELEMENTS;
if (IsSloppyArgumentsElementsKind(kind)) {
- elements = SloppyArgumentsElements::cast(elements).arguments();
+ elements = SloppyArgumentsElements::cast(elements).arguments(isolate);
dictionary_kind = SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
} else if (IsStringWrapperElementsKind(kind)) {
dictionary_kind = SLOW_STRING_WRAPPER_ELEMENTS;
@@ -4583,7 +4620,7 @@ void JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
if (attributes != NONE) {
kind = dictionary_kind;
- } else if (elements.IsNumberDictionary()) {
+ } else if (elements.IsNumberDictionary(isolate)) {
kind = ShouldConvertToFastElements(
*object, NumberDictionary::cast(elements), index, &new_capacity)
? BestFittingFastElementsKind(*object)
@@ -4594,8 +4631,9 @@ void JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
kind = dictionary_kind;
}
- ElementsKind to = value->OptimalElementsKind();
- if (IsHoleyElementsKind(kind) || !object->IsJSArray() || index > old_length) {
+ ElementsKind to = value->OptimalElementsKind(isolate);
+ if (IsHoleyElementsKind(kind) || !object->IsJSArray(isolate) ||
+ index > old_length) {
to = GetHoleyElementsKind(to);
kind = GetHoleyElementsKind(kind);
}
@@ -4603,7 +4641,7 @@ void JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
ElementsAccessor* accessor = ElementsAccessor::ForKind(to);
accessor->Add(object, index, value, attributes, new_capacity);
- if (object->IsJSArray() && index >= old_length) {
+ if (object->IsJSArray(isolate) && index >= old_length) {
Handle<Object> new_length =
isolate->factory()->NewNumberFromUint(index + 1);
JSArray::cast(*object).set_length(*new_length);
@@ -4658,14 +4696,15 @@ void JSObject::TransitionElementsKind(Handle<JSObject> object,
DCHECK_NE(TERMINAL_FAST_ELEMENTS_KIND, from_kind);
UpdateAllocationSite(object, to_kind);
- if (object->elements() == object->GetReadOnlyRoots().empty_fixed_array() ||
+ Isolate* isolate = object->GetIsolate();
+ if (object->elements() == ReadOnlyRoots(isolate).empty_fixed_array() ||
IsDoubleElementsKind(from_kind) == IsDoubleElementsKind(to_kind)) {
// No change is needed to the elements() buffer, the transition
// only requires a map change.
Handle<Map> new_map = GetElementsTransitionMap(object, to_kind);
- MigrateToMap(object, new_map);
+ JSObject::MigrateToMap(isolate, object, new_map);
if (FLAG_trace_elements_transitions) {
- Handle<FixedArrayBase> elms(object->elements(), object->GetIsolate());
+ Handle<FixedArrayBase> elms(object->elements(), isolate);
PrintElementsTransition(stdout, object, from_kind, elms, to_kind, elms);
}
} else {
@@ -4946,6 +4985,17 @@ void JSFunction::EnsureFeedbackVector(Handle<JSFunction> function) {
// static
void JSFunction::InitializeFeedbackCell(Handle<JSFunction> function) {
Isolate* const isolate = function->GetIsolate();
+
+ if (function->has_feedback_vector()) {
+ // TODO(984344): Make this a CHECK that feedback vectors are identical to
+ // what we expect once we have removed all bytecode generation differences
+ // between eager and lazy compilation. For now just reset if they aren't
+ // identical
+ FeedbackVector vector = function->feedback_vector();
+ if (vector.length() == vector.metadata().slot_count()) return;
+ function->raw_feedback_cell().reset();
+ }
+
bool needs_feedback_vector = !FLAG_lazy_feedback_allocation;
// We need feedback vector for certain log events, collecting type profile
// and more precise code coverage.
@@ -4995,7 +5045,7 @@ void SetInstancePrototype(Isolate* isolate, Handle<JSFunction> function,
native_context->get(Context::ARRAY_FUNCTION_INDEX), isolate);
if (array_function->IsJSFunction() &&
*function == JSFunction::cast(*array_function)) {
- CacheInitialJSArrayMaps(native_context, new_map);
+ CacheInitialJSArrayMaps(isolate, native_context, new_map);
}
}
@@ -5034,7 +5084,7 @@ void JSFunction::SetPrototype(Handle<JSFunction> function,
Handle<Map> new_map =
Map::Copy(isolate, handle(function->map(), isolate), "SetPrototype");
- JSObject::MigrateToMap(function, new_map);
+ JSObject::MigrateToMap(isolate, function, new_map);
new_map->SetConstructor(*value);
new_map->set_has_non_instance_prototype(true);
@@ -5145,14 +5195,16 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
case JS_MESSAGE_OBJECT_TYPE:
case JS_OBJECT_TYPE:
case JS_ERROR_TYPE:
+ case JS_FINALIZATION_GROUP_TYPE:
case JS_ARGUMENTS_TYPE:
case JS_PROMISE_TYPE:
case JS_REGEXP_TYPE:
case JS_SET_TYPE:
case JS_SPECIAL_API_OBJECT_TYPE:
case JS_TYPED_ARRAY_TYPE:
- case JS_VALUE_TYPE:
+ case JS_PRIMITIVE_WRAPPER_TYPE:
case JS_WEAK_MAP_TYPE:
+ case JS_WEAK_REF_TYPE:
case JS_WEAK_SET_TYPE:
case WASM_GLOBAL_TYPE:
case WASM_INSTANCE_TYPE:
@@ -5530,7 +5582,7 @@ void JSFunction::ClearTypeFeedbackInfo() {
FeedbackVector vector = feedback_vector();
Isolate* isolate = GetIsolate();
if (vector.ClearSlots(isolate)) {
- IC::OnFeedbackChanged(isolate, vector, FeedbackSlot::Invalid(), *this,
+ IC::OnFeedbackChanged(isolate, vector, FeedbackSlot::Invalid(),
"ClearTypeFeedbackInfo");
}
}
diff --git a/deps/v8/src/objects/js-objects.h b/deps/v8/src/objects/js-objects.h
index 5ac1751c48..bcea3a28df 100644
--- a/deps/v8/src/objects/js-objects.h
+++ b/deps/v8/src/objects/js-objects.h
@@ -8,6 +8,7 @@
#include "src/objects/embedder-data-slot.h"
#include "src/objects/objects.h"
#include "src/objects/property-array.h"
+#include "torque-generated/class-definitions-tq.h"
#include "torque-generated/field-offsets-tq.h"
// Has to be the last include (doesn't have include guards):
@@ -27,16 +28,16 @@ class JSReceiver : public HeapObject {
public:
NEVER_READ_ONLY_SPACE
// Returns true if there is no slow (ie, dictionary) backing store.
- inline bool HasFastProperties() const;
+ DECL_GETTER(HasFastProperties, bool)
// Returns the properties array backing store if it
// exists. Otherwise, returns an empty_property_array when there's a
// Smi (hash code) or an empty_fixed_array for a fast properties
// map.
- inline PropertyArray property_array() const;
+ DECL_GETTER(property_array, PropertyArray)
// Gets slow properties for non-global objects.
- inline NameDictionary property_dictionary() const;
+ DECL_GETTER(property_dictionary, NameDictionary)
// Sets the properties backing store and makes sure any existing hash is moved
// to the new properties store. To clear out the properties store, pass in the
@@ -62,12 +63,13 @@ class JSReceiver : public HeapObject {
// above typed getters and setters to access the properties.
DECL_ACCESSORS(raw_properties_or_hash, Object)
- inline void initialize_properties();
+ inline void initialize_properties(Isolate* isolate);
// Deletes an existing named property in a normalized object.
static void DeleteNormalizedProperty(Handle<JSReceiver> object, int entry);
DECL_CAST(JSReceiver)
+ DECL_VERIFIER(JSReceiver)
// ES6 section 7.1.1 ToPrimitive
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ToPrimitive(
@@ -275,7 +277,7 @@ class JSReceiver : public HeapObject {
// properties.
// Note that the map of JSObject changes during execution to enable inline
// caching.
-class JSObject : public JSReceiver {
+class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
public:
static bool IsUnmodifiedApiObject(FullObjectSlot o);
@@ -290,78 +292,63 @@ class JSObject : public JSReceiver {
static V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> ObjectCreate(
Isolate* isolate, Handle<Object> prototype);
- // [elements]: The elements (properties with names that are integers).
- //
- // Elements can be in two general modes: fast and slow. Each mode
- // corresponds to a set of object representations of elements that
- // have something in common.
- //
- // In the fast mode elements is a FixedArray and so each element can be
- // quickly accessed. The elements array can have one of several maps in this
- // mode: fixed_array_map, fixed_double_array_map,
- // sloppy_arguments_elements_map or fixed_cow_array_map (for copy-on-write
- // arrays). In the latter case the elements array may be shared by a few
- // objects and so before writing to any element the array must be copied. Use
- // EnsureWritableFastElements in this case.
- //
- // In the slow mode the elements is either a NumberDictionary or a
- // FixedArray parameter map for a (sloppy) arguments object.
- DECL_ACCESSORS(elements, FixedArrayBase)
inline void initialize_elements();
static inline void SetMapAndElements(Handle<JSObject> object, Handle<Map> map,
Handle<FixedArrayBase> elements);
- inline ElementsKind GetElementsKind() const;
- V8_EXPORT_PRIVATE ElementsAccessor* GetElementsAccessor();
+ DECL_GETTER(GetElementsKind, ElementsKind)
+ DECL_GETTER(GetElementsAccessor, ElementsAccessor*)
+
// Returns true if an object has elements of PACKED_SMI_ELEMENTS or
// HOLEY_SMI_ELEMENTS ElementsKind.
- inline bool HasSmiElements();
+ DECL_GETTER(HasSmiElements, bool)
// Returns true if an object has elements of PACKED_ELEMENTS or
// HOLEY_ELEMENTS ElementsKind.
- inline bool HasObjectElements();
+ DECL_GETTER(HasObjectElements, bool)
// Returns true if an object has elements of PACKED_SMI_ELEMENTS,
// HOLEY_SMI_ELEMENTS, PACKED_ELEMENTS, or HOLEY_ELEMENTS.
- inline bool HasSmiOrObjectElements();
+ DECL_GETTER(HasSmiOrObjectElements, bool)
// Returns true if an object has any of the "fast" elements kinds.
- inline bool HasFastElements();
+ DECL_GETTER(HasFastElements, bool)
// Returns true if an object has any of the PACKED elements kinds.
- inline bool HasFastPackedElements();
+ DECL_GETTER(HasFastPackedElements, bool)
// Returns true if an object has elements of PACKED_DOUBLE_ELEMENTS or
// HOLEY_DOUBLE_ELEMENTS ElementsKind.
- inline bool HasDoubleElements();
+ DECL_GETTER(HasDoubleElements, bool)
// Returns true if an object has elements of HOLEY_SMI_ELEMENTS,
// HOLEY_DOUBLE_ELEMENTS, or HOLEY_ELEMENTS ElementsKind.
- inline bool HasHoleyElements();
- inline bool HasSloppyArgumentsElements();
- inline bool HasStringWrapperElements();
- inline bool HasDictionaryElements();
+ DECL_GETTER(HasHoleyElements, bool)
+ DECL_GETTER(HasSloppyArgumentsElements, bool)
+ DECL_GETTER(HasStringWrapperElements, bool)
+ DECL_GETTER(HasDictionaryElements, bool)
// Returns true if an object has elements of PACKED_ELEMENTS
- inline bool HasPackedElements();
- inline bool HasFrozenOrSealedElements();
- inline bool HasSealedElements();
-
- inline bool HasTypedArrayElements();
-
- inline bool HasFixedUint8ClampedElements();
- inline bool HasFixedArrayElements();
- inline bool HasFixedInt8Elements();
- inline bool HasFixedUint8Elements();
- inline bool HasFixedInt16Elements();
- inline bool HasFixedUint16Elements();
- inline bool HasFixedInt32Elements();
- inline bool HasFixedUint32Elements();
- inline bool HasFixedFloat32Elements();
- inline bool HasFixedFloat64Elements();
- inline bool HasFixedBigInt64Elements();
- inline bool HasFixedBigUint64Elements();
-
- inline bool HasFastArgumentsElements();
- inline bool HasSlowArgumentsElements();
- inline bool HasFastStringWrapperElements();
- inline bool HasSlowStringWrapperElements();
+ DECL_GETTER(HasPackedElements, bool)
+ DECL_GETTER(HasFrozenOrSealedElements, bool)
+ DECL_GETTER(HasSealedElements, bool)
+
+ DECL_GETTER(HasTypedArrayElements, bool)
+
+ DECL_GETTER(HasFixedUint8ClampedElements, bool)
+ DECL_GETTER(HasFixedArrayElements, bool)
+ DECL_GETTER(HasFixedInt8Elements, bool)
+ DECL_GETTER(HasFixedUint8Elements, bool)
+ DECL_GETTER(HasFixedInt16Elements, bool)
+ DECL_GETTER(HasFixedUint16Elements, bool)
+ DECL_GETTER(HasFixedInt32Elements, bool)
+ DECL_GETTER(HasFixedUint32Elements, bool)
+ DECL_GETTER(HasFixedFloat32Elements, bool)
+ DECL_GETTER(HasFixedFloat64Elements, bool)
+ DECL_GETTER(HasFixedBigInt64Elements, bool)
+ DECL_GETTER(HasFixedBigUint64Elements, bool)
+
+ DECL_GETTER(HasFastArgumentsElements, bool)
+ DECL_GETTER(HasSlowArgumentsElements, bool)
+ DECL_GETTER(HasFastStringWrapperElements, bool)
+ DECL_GETTER(HasSlowStringWrapperElements, bool)
bool HasEnumerableElements();
- inline NumberDictionary element_dictionary(); // Gets slow elements.
+ // Gets slow elements.
+ DECL_GETTER(element_dictionary, NumberDictionary)
// Requires: HasFastElements().
static void EnsureWritableFastElements(Handle<JSObject> object);
@@ -431,11 +418,11 @@ class JSObject : public JSReceiver {
// Migrates the given object to a map whose field representations are the
// lowest upper bound of all known representations for that field.
- static void MigrateInstance(Handle<JSObject> instance);
+ static void MigrateInstance(Isolate* isolate, Handle<JSObject> instance);
// Migrates the given object only if the target map is already available,
// or returns false if such a map is not yet available.
- static bool TryMigrateInstance(Handle<JSObject> instance);
+ static bool TryMigrateInstance(Isolate* isolate, Handle<JSObject> instance);
// Sets the property value in a normalized object given (key, value, details).
// Handles the special representation of JS global objects.
@@ -476,8 +463,8 @@ class JSObject : public JSReceiver {
int old_index, int new_index);
// Retrieve interceptors.
- inline InterceptorInfo GetNamedInterceptor();
- inline InterceptorInfo GetIndexedInterceptor();
+ DECL_GETTER(GetNamedInterceptor, InterceptorInfo)
+ DECL_GETTER(GetIndexedInterceptor, InterceptorInfo)
// Used from JSReceiver.
V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes>
@@ -546,8 +533,8 @@ class JSObject : public JSReceiver {
// Lookup interceptors are used for handling properties controlled by host
// objects.
- inline bool HasNamedInterceptor();
- inline bool HasIndexedInterceptor();
+ DECL_GETTER(HasNamedInterceptor, bool)
+ DECL_GETTER(HasIndexedInterceptor, bool)
// Support functions for v8 api (needed for correct interceptor behavior).
V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealNamedProperty(
@@ -563,13 +550,12 @@ class JSObject : public JSReceiver {
// JSFunction objects.
static int GetHeaderSize(InstanceType instance_type,
bool function_has_prototype_slot = false);
- static inline int GetHeaderSize(const Map map);
- inline int GetHeaderSize() const;
+ static inline int GetHeaderSize(Map map);
- static inline int GetEmbedderFieldsStartOffset(const Map map);
+ static inline int GetEmbedderFieldsStartOffset(Map map);
inline int GetEmbedderFieldsStartOffset();
- static inline int GetEmbedderFieldCount(const Map map);
+ static inline int GetEmbedderFieldCount(Map map);
inline int GetEmbedderFieldCount() const;
inline int GetEmbedderFieldOffset(int index);
inline Object GetEmbedderField(int index);
@@ -596,7 +582,7 @@ class JSObject : public JSReceiver {
// |expected_additional_properties| is only used for fast-to-slow transitions
// and ignored otherwise.
V8_EXPORT_PRIVATE static void MigrateToMap(
- Handle<JSObject> object, Handle<Map> new_map,
+ Isolate* isolate, Handle<JSObject> object, Handle<Map> new_map,
int expected_additional_properties = 0);
// Forces a prototype without any of the checks that the regular SetPrototype
@@ -609,7 +595,7 @@ class JSObject : public JSReceiver {
// added this number can be indicated to have the backing store allocated to
// an initial capacity for holding these properties.
V8_EXPORT_PRIVATE static void NormalizeProperties(
- Handle<JSObject> object, PropertyNormalizationMode mode,
+ Isolate* isolate, Handle<JSObject> object, PropertyNormalizationMode mode,
int expected_additional_properties, const char* reason);
// Convert and update the elements backing store to be a
@@ -624,15 +610,17 @@ class JSObject : public JSReceiver {
int unused_property_fields,
const char* reason);
- inline bool IsUnboxedDoubleField(FieldIndex index);
+ inline bool IsUnboxedDoubleField(FieldIndex index) const;
+ inline bool IsUnboxedDoubleField(Isolate* isolate, FieldIndex index) const;
// Access fast-case object properties at index.
static Handle<Object> FastPropertyAt(Handle<JSObject> object,
Representation representation,
FieldIndex index);
- inline Object RawFastPropertyAt(FieldIndex index);
- inline double RawFastDoublePropertyAt(FieldIndex index);
- inline uint64_t RawFastDoublePropertyAsBitsAt(FieldIndex index);
+ inline Object RawFastPropertyAt(FieldIndex index) const;
+ inline Object RawFastPropertyAt(Isolate* isolate, FieldIndex index) const;
+ inline double RawFastDoublePropertyAt(FieldIndex index) const;
+ inline uint64_t RawFastDoublePropertyAsBitsAt(FieldIndex index) const;
inline void FastPropertyAtPut(FieldIndex index, Object value);
inline void RawFastPropertyAtPut(
@@ -679,8 +667,6 @@ class JSObject : public JSReceiver {
static bool IsExtensible(Handle<JSObject> object);
- DECL_CAST(JSObject)
-
// Dispatched behavior.
void JSObjectShortPrint(StringStream* accumulator);
DECL_PRINTER(JSObject)
@@ -727,7 +713,7 @@ class JSObject : public JSReceiver {
// If a GC was caused while constructing this object, the elements pointer
// may point to a one pointer filler map. The object won't be rooted, but
// our heap verification code could stumble across it.
- V8_EXPORT_PRIVATE bool ElementsAreSafeToExamine() const;
+ V8_EXPORT_PRIVATE bool ElementsAreSafeToExamine(Isolate* isolate) const;
#endif
Object SlowReverseLookup(Object value);
@@ -764,15 +750,6 @@ class JSObject : public JSReceiver {
STATIC_ASSERT(kMaxNumberOfDescriptors + kFieldsAdded <=
PropertyArray::kMaxLength);
-// Layout description.
-#define JS_OBJECT_FIELDS(V) \
- V(kElementsOffset, kTaggedSize) \
- /* Header size. */ \
- V(kHeaderSize, 0)
-
- DEFINE_FIELD_OFFSET_CONSTANTS(JSReceiver::kHeaderSize, JS_OBJECT_FIELDS)
-#undef JS_OBJECT_FIELDS
-
STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
static const int kMaxInObjectProperties =
(kMaxInstanceSize - kHeaderSize) >> kTaggedSizeLog2;
@@ -825,7 +802,7 @@ class JSObject : public JSReceiver {
V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensionsWithTransition(
Handle<JSObject> object, ShouldThrow should_throw);
- OBJECT_CONSTRUCTORS(JSObject, JSReceiver);
+ TQ_OBJECT_CONSTRUCTORS(JSObject)
};
// JSAccessorPropertyDescriptor is just a JSObject with a specific initial
@@ -835,9 +812,17 @@ class JSObject : public JSReceiver {
class JSAccessorPropertyDescriptor : public JSObject {
public:
// Layout description.
- DEFINE_FIELD_OFFSET_CONSTANTS(
- JSObject::kHeaderSize,
- TORQUE_GENERATED_JSACCESSOR_PROPERTY_DESCRIPTOR_FIELDS)
+#define JS_ACCESSOR_PROPERTY_DESCRIPTOR_FIELDS(V) \
+ V(kGetOffset, kTaggedSize) \
+ V(kSetOffset, kTaggedSize) \
+ V(kEnumerableOffset, kTaggedSize) \
+ V(kConfigurableOffset, kTaggedSize) \
+ /* Total size. */ \
+ V(kSize, 0)
+
+ DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
+ JS_ACCESSOR_PROPERTY_DESCRIPTOR_FIELDS)
+#undef JS_ACCESSOR_PROPERTY_DESCRIPTOR_FIELDS
// Indices of in-object properties.
static const int kGetIndex = 0;
@@ -855,8 +840,18 @@ class JSAccessorPropertyDescriptor : public JSObject {
// FromPropertyDescriptor function for regular data properties.
class JSDataPropertyDescriptor : public JSObject {
public:
- DEFINE_FIELD_OFFSET_CONSTANTS(
- JSObject::kHeaderSize, TORQUE_GENERATED_JSDATA_PROPERTY_DESCRIPTOR_FIELDS)
+ // Layout description.
+#define JS_DATA_PROPERTY_DESCRIPTOR_FIELDS(V) \
+ V(kValueOffset, kTaggedSize) \
+ V(kWritableOffset, kTaggedSize) \
+ V(kEnumerableOffset, kTaggedSize) \
+ V(kConfigurableOffset, kTaggedSize) \
+ /* Total size. */ \
+ V(kSize, 0)
+
+ DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
+ JS_DATA_PROPERTY_DESCRIPTOR_FIELDS)
+#undef JS_DATA_PROPERTY_DESCRIPTOR_FIELDS
// Indices of in-object properties.
static const int kValueIndex = 0;
@@ -870,7 +865,7 @@ class JSDataPropertyDescriptor : public JSObject {
// JSIteratorResult is just a JSObject with a specific initial map.
// This initial map adds in-object properties for "done" and "value",
-// as specified by ES6 section 25.1.1.3 The IteratorResult Interface
+// as specified by ES6 section 25.1.1.3 The IteratorResult Interface.
class JSIteratorResult : public JSObject {
public:
DECL_ACCESSORS(value, Object)
@@ -878,8 +873,15 @@ class JSIteratorResult : public JSObject {
DECL_ACCESSORS(done, Object)
// Layout description.
+#define JS_ITERATOR_RESULT_FIELDS(V) \
+ V(kValueOffset, kTaggedSize) \
+ V(kDoneOffset, kTaggedSize) \
+ /* Total size. */ \
+ V(kSize, 0)
+
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
- TORQUE_GENERATED_JSITERATOR_RESULT_FIELDS)
+ JS_ITERATOR_RESULT_FIELDS)
+#undef JS_ITERATOR_RESULT_FIELDS
// Indices of in-object properties.
static const int kValueIndex = 0;
@@ -894,7 +896,6 @@ class JSIteratorResult : public JSObject {
class JSBoundFunction : public JSObject {
public:
// [bound_target_function]: The wrapped function object.
- inline Object raw_bound_target_function() const;
DECL_ACCESSORS(bound_target_function, JSReceiver)
// [bound_this]: The value that is always passed as the this value when
@@ -933,7 +934,7 @@ class JSBoundFunction : public JSObject {
class JSFunction : public JSObject {
public:
// [prototype_or_initial_map]:
- DECL_ACCESSORS(prototype_or_initial_map, Object)
+ DECL_ACCESSORS(prototype_or_initial_map, HeapObject)
// [shared]: The information about the function that
// can be shared by instances.
@@ -947,7 +948,7 @@ class JSFunction : public JSObject {
// [context]: The context for this function.
inline Context context();
inline bool has_context() const;
- inline void set_context(Object context);
+ inline void set_context(HeapObject context);
inline JSGlobalProxy global_proxy();
inline NativeContext native_context();
inline int length();
@@ -1055,13 +1056,14 @@ class JSFunction : public JSObject {
inline bool NeedsResetDueToFlushedBytecode();
inline void ResetIfBytecodeFlushed();
- inline bool has_prototype_slot() const;
+ DECL_GETTER(has_prototype_slot, bool)
// The initial map for an object created by this constructor.
- inline Map initial_map();
+ DECL_GETTER(initial_map, Map)
+
static void SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
Handle<HeapObject> prototype);
- inline bool has_initial_map();
+ DECL_GETTER(has_initial_map, bool)
V8_EXPORT_PRIVATE static void EnsureHasInitialMap(
Handle<JSFunction> function);
@@ -1076,12 +1078,12 @@ class JSFunction : public JSObject {
// 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.
- inline bool has_prototype();
- inline bool has_instance_prototype();
- inline Object prototype();
- inline HeapObject instance_prototype();
- inline bool has_prototype_property();
- inline bool PrototypeRequiresRuntimeLookup();
+ 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.
@@ -1149,14 +1151,9 @@ class JSFunction : public JSObject {
//
// Accessing a JSGlobalProxy requires security check.
-class JSGlobalProxy : public JSObject {
+class JSGlobalProxy
+ : public TorqueGeneratedJSGlobalProxy<JSGlobalProxy, JSObject> {
public:
- // [native_context]: the owner native context of this global proxy object.
- // It is null value if this object is not used by any context.
- DECL_ACCESSORS(native_context, Object)
-
- DECL_CAST(JSGlobalProxy)
-
inline bool IsDetachedFrom(JSGlobalObject global) const;
static int SizeWithEmbedderFields(int embedder_field_count);
@@ -1165,11 +1162,7 @@ class JSGlobalProxy : public JSObject {
DECL_PRINTER(JSGlobalProxy)
DECL_VERIFIER(JSGlobalProxy)
- // Layout description.
- DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
- TORQUE_GENERATED_JSGLOBAL_PROXY_FIELDS)
-
- OBJECT_CONSTRUCTORS(JSGlobalProxy, JSObject);
+ TQ_OBJECT_CONSTRUCTORS(JSGlobalProxy)
};
// JavaScript global object.
@@ -1182,7 +1175,7 @@ class JSGlobalObject : public JSObject {
DECL_ACCESSORS(global_proxy, JSGlobalProxy)
// Gets global object properties.
- inline GlobalDictionary global_dictionary();
+ DECL_GETTER(global_dictionary, GlobalDictionary)
inline void set_global_dictionary(GlobalDictionary dictionary);
static void InvalidatePropertyCell(Handle<JSGlobalObject> object,
@@ -1208,22 +1201,13 @@ class JSGlobalObject : public JSObject {
};
// Representation for JS Wrapper objects, String, Number, Boolean, etc.
-class JSValue : public JSObject {
+class JSPrimitiveWrapper
+ : public TorqueGeneratedJSPrimitiveWrapper<JSPrimitiveWrapper, JSObject> {
public:
- // [value]: the object being wrapped.
- DECL_ACCESSORS(value, Object)
-
- DECL_CAST(JSValue)
-
// Dispatched behavior.
- DECL_PRINTER(JSValue)
- DECL_VERIFIER(JSValue)
+ DECL_PRINTER(JSPrimitiveWrapper)
- // Layout description.
- DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
- TORQUE_GENERATED_JSVALUE_FIELDS)
-
- OBJECT_CONSTRUCTORS(JSValue, JSObject);
+ TQ_OBJECT_CONSTRUCTORS(JSPrimitiveWrapper)
};
class DateCache;
@@ -1367,8 +1351,7 @@ class JSMessageObject : public JSObject {
// EnsureSourcePositionsAvailable must have been called before calling this.
Handle<String> GetSourceLine() const;
- inline int error_level() const;
- inline void set_error_level(int level);
+ DECL_INT_ACCESSORS(error_level)
DECL_CAST(JSMessageObject)
@@ -1384,8 +1367,6 @@ class JSMessageObject : public JSObject {
using BodyDescriptor = FixedBodyDescriptor<HeapObject::kMapOffset,
kPointerFieldsEndOffset, kSize>;
- OBJECT_CONSTRUCTORS(JSMessageObject, JSObject);
-
private:
friend class Factory;
@@ -1400,12 +1381,14 @@ class JSMessageObject : public JSObject {
DECL_ACCESSORS(bytecode_offset, Smi)
// [start_position]: the start position in the script for the error message.
- inline int start_position() const;
- inline void set_start_position(int value);
+ DECL_INT_ACCESSORS(start_position)
// [end_position]: the end position in the script for the error message.
- inline int end_position() const;
- inline void set_end_position(int value);
+ DECL_INT_ACCESSORS(end_position)
+
+ DECL_INT_ACCESSORS(raw_type)
+
+ OBJECT_CONSTRUCTORS(JSMessageObject, JSObject);
};
// The [Async-from-Sync Iterator] object
diff --git a/deps/v8/src/objects/js-plural-rules-inl.h b/deps/v8/src/objects/js-plural-rules-inl.h
index 1924bdc4ff..b8fe7f50f0 100644
--- a/deps/v8/src/objects/js-plural-rules-inl.h
+++ b/deps/v8/src/objects/js-plural-rules-inl.h
@@ -25,11 +25,12 @@ ACCESSORS(JSPluralRules, locale, String, kLocaleOffset)
SMI_ACCESSORS(JSPluralRules, flags, kFlagsOffset)
ACCESSORS(JSPluralRules, icu_plural_rules, Managed<icu::PluralRules>,
kIcuPluralRulesOffset)
-ACCESSORS(JSPluralRules, icu_decimal_format, Managed<icu::DecimalFormat>,
- kIcuDecimalFormatOffset)
+ACCESSORS(JSPluralRules, icu_number_formatter,
+ Managed<icu::number::LocalizedNumberFormatter>,
+ kIcuNumberFormatterOffset)
inline void JSPluralRules::set_type(Type type) {
- DCHECK_LT(type, Type::COUNT);
+ DCHECK_LE(type, TypeBits::kMax);
int hints = flags();
hints = TypeBits::update(hints, type);
set_flags(hints);
diff --git a/deps/v8/src/objects/js-plural-rules.cc b/deps/v8/src/objects/js-plural-rules.cc
index 8daf5db64a..84fe9b6d52 100644
--- a/deps/v8/src/objects/js-plural-rules.cc
+++ b/deps/v8/src/objects/js-plural-rules.cc
@@ -10,11 +10,12 @@
#include "src/execution/isolate-inl.h"
#include "src/objects/intl-objects.h"
+#include "src/objects/js-number-format.h"
#include "src/objects/js-plural-rules-inl.h"
-#include "unicode/decimfmt.h"
#include "unicode/locid.h"
-#include "unicode/numfmt.h"
+#include "unicode/numberformatter.h"
#include "unicode/plurrule.h"
+#include "unicode/unumberformatter.h"
namespace v8 {
namespace internal {
@@ -23,8 +24,7 @@ namespace {
bool CreateICUPluralRules(Isolate* isolate, const icu::Locale& icu_locale,
JSPluralRules::Type type,
- std::unique_ptr<icu::PluralRules>* pl,
- std::unique_ptr<icu::DecimalFormat>* nf) {
+ std::unique_ptr<icu::PluralRules>* pl) {
// Make formatter from options. Numbering system is added
// to the locale as Unicode extension (if it was specified at all).
UErrorCode status = U_ZERO_ERROR;
@@ -43,41 +43,10 @@ bool CreateICUPluralRules(Isolate* isolate, const icu::Locale& icu_locale,
}
CHECK_NOT_NULL(plural_rules.get());
- std::unique_ptr<icu::DecimalFormat> number_format(
- static_cast<icu::DecimalFormat*>(
- icu::NumberFormat::createInstance(icu_locale, UNUM_DECIMAL, status)));
- if (U_FAILURE(status)) {
- return false;
- }
- CHECK_NOT_NULL(number_format.get());
-
*pl = std::move(plural_rules);
- *nf = std::move(number_format);
-
return true;
}
-void InitializeICUPluralRules(
- Isolate* isolate, const icu::Locale& icu_locale, JSPluralRules::Type type,
- std::unique_ptr<icu::PluralRules>* plural_rules,
- std::unique_ptr<icu::DecimalFormat>* number_format) {
- bool success = CreateICUPluralRules(isolate, icu_locale, type, plural_rules,
- number_format);
- if (!success) {
- // Remove extensions and try again.
- icu::Locale no_extension_locale(icu_locale.getBaseName());
- success = CreateICUPluralRules(isolate, no_extension_locale, type,
- plural_rules, number_format);
-
- if (!success) {
- FATAL("Failed to create ICU PluralRules, are ICU data files missing?");
- }
- }
-
- CHECK_NOT_NULL((*plural_rules).get());
- CHECK_NOT_NULL((*number_format).get());
-}
-
} // namespace
Handle<String> JSPluralRules::TypeAsString() const {
@@ -86,16 +55,14 @@ Handle<String> JSPluralRules::TypeAsString() const {
return GetReadOnlyRoots().cardinal_string_handle();
case Type::ORDINAL:
return GetReadOnlyRoots().ordinal_string_handle();
- case Type::COUNT:
- UNREACHABLE();
}
+ UNREACHABLE();
}
// static
-MaybeHandle<JSPluralRules> JSPluralRules::Initialize(
- Isolate* isolate, Handle<JSPluralRules> plural_rules,
- Handle<Object> locales, Handle<Object> options_obj) {
- plural_rules->set_flags(0);
+MaybeHandle<JSPluralRules> JSPluralRules::New(Isolate* isolate, Handle<Map> map,
+ Handle<Object> locales,
+ Handle<Object> options_obj) {
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> maybe_requested_locales =
Intl::CanonicalizeLocaleList(isolate, locales);
@@ -135,9 +102,6 @@ MaybeHandle<JSPluralRules> JSPluralRules::Initialize(
MAYBE_RETURN(maybe_type, MaybeHandle<JSPluralRules>());
Type type = maybe_type.FromJust();
- // 8. Set pluralRules.[[Type]] to t.
- plural_rules->set_type(type);
-
// Note: The spec says we should do ResolveLocale after performing
// SetNumberFormatDigitOptions but we need the locale to create all
// the ICU data structures.
@@ -150,48 +114,64 @@ MaybeHandle<JSPluralRules> JSPluralRules::Initialize(
Intl::ResolvedLocale r =
Intl::ResolveLocale(isolate, JSPluralRules::GetAvailableLocales(),
requested_locales, matcher, {});
-
- // 12. Set pluralRules.[[Locale]] to the value of r.[[locale]].
Handle<String> locale_str =
isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
- plural_rules->set_locale(*locale_str);
+
+ icu::number::LocalizedNumberFormatter icu_number_formatter =
+ icu::number::NumberFormatter::withLocale(r.icu_locale)
+ .roundingMode(UNUM_ROUND_HALFUP);
std::unique_ptr<icu::PluralRules> icu_plural_rules;
- std::unique_ptr<icu::DecimalFormat> icu_decimal_format;
- InitializeICUPluralRules(isolate, r.icu_locale, type, &icu_plural_rules,
- &icu_decimal_format);
+ bool success =
+ CreateICUPluralRules(isolate, r.icu_locale, type, &icu_plural_rules);
+ if (!success) {
+ // Remove extensions and try again.
+ icu::Locale no_extension_locale(r.icu_locale.getBaseName());
+ success = CreateICUPluralRules(isolate, no_extension_locale, type,
+ &icu_plural_rules);
+ icu_number_formatter =
+ icu::number::NumberFormatter::withLocale(no_extension_locale)
+ .roundingMode(UNUM_ROUND_HALFUP);
+
+ if (!success) {
+ FATAL("Failed to create ICU PluralRules, are ICU data files missing?");
+ }
+ }
+
CHECK_NOT_NULL(icu_plural_rules.get());
- CHECK_NOT_NULL(icu_decimal_format.get());
// 9. Perform ? SetNumberFormatDigitOptions(pluralRules, options, 0, 3).
Maybe<Intl::NumberFormatDigitOptions> maybe_digit_options =
- Intl::SetNumberFormatDigitOptions(isolate, options, 0, 3);
+ Intl::SetNumberFormatDigitOptions(isolate, options, 0, 3, false);
MAYBE_RETURN(maybe_digit_options, MaybeHandle<JSPluralRules>());
Intl::NumberFormatDigitOptions digit_options = maybe_digit_options.FromJust();
-
- icu_decimal_format->setRoundingMode(icu::DecimalFormat::kRoundHalfUp);
- icu_decimal_format->setMinimumIntegerDigits(
- digit_options.minimum_integer_digits);
- icu_decimal_format->setMinimumFractionDigits(
- digit_options.minimum_fraction_digits);
- icu_decimal_format->setMaximumFractionDigits(
- digit_options.maximum_fraction_digits);
- if (digit_options.minimum_significant_digits > 0) {
- icu_decimal_format->setMinimumSignificantDigits(
- digit_options.minimum_significant_digits);
- icu_decimal_format->setMaximumSignificantDigits(
- digit_options.maximum_significant_digits);
- }
+ icu_number_formatter = JSNumberFormat::SetDigitOptionsToFormatter(
+ icu_number_formatter, digit_options);
Handle<Managed<icu::PluralRules>> managed_plural_rules =
Managed<icu::PluralRules>::FromUniquePtr(isolate, 0,
std::move(icu_plural_rules));
- plural_rules->set_icu_plural_rules(*managed_plural_rules);
- Handle<Managed<icu::DecimalFormat>> managed_decimal_format =
- Managed<icu::DecimalFormat>::FromUniquePtr(isolate, 0,
- std::move(icu_decimal_format));
- plural_rules->set_icu_decimal_format(*managed_decimal_format);
+ Handle<Managed<icu::number::LocalizedNumberFormatter>>
+ managed_number_formatter =
+ Managed<icu::number::LocalizedNumberFormatter>::FromRawPtr(
+ isolate, 0,
+ new icu::number::LocalizedNumberFormatter(icu_number_formatter));
+
+ // Now all properties are ready, so we can allocate the result object.
+ Handle<JSPluralRules> plural_rules = Handle<JSPluralRules>::cast(
+ isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
+ DisallowHeapAllocation no_gc;
+ plural_rules->set_flags(0);
+
+ // 8. Set pluralRules.[[Type]] to t.
+ plural_rules->set_type(type);
+
+ // 12. Set pluralRules.[[Locale]] to the value of r.[[locale]].
+ plural_rules->set_locale(*locale_str);
+
+ plural_rules->set_icu_plural_rules(*managed_plural_rules);
+ plural_rules->set_icu_number_formatter(*managed_number_formatter);
// 13. Return pluralRules.
return plural_rules;
@@ -202,31 +182,20 @@ MaybeHandle<String> JSPluralRules::ResolvePlural(
icu::PluralRules* icu_plural_rules = plural_rules->icu_plural_rules().raw();
CHECK_NOT_NULL(icu_plural_rules);
- icu::DecimalFormat* icu_decimal_format =
- plural_rules->icu_decimal_format().raw();
- CHECK_NOT_NULL(icu_decimal_format);
+ icu::number::LocalizedNumberFormatter* fmt =
+ plural_rules->icu_number_formatter().raw();
+ CHECK_NOT_NULL(fmt);
- // Currently, PluralRules doesn't implement all the options for rounding that
- // the Intl spec provides; format and parse the number to round to the
- // appropriate amount, then apply PluralRules.
- //
- // TODO(littledan): If a future ICU version supports an extended API to avoid
- // this step, then switch to that API. Bug thread:
- // http://bugs.icu-project.org/trac/ticket/12763
- icu::UnicodeString rounded_string;
- icu_decimal_format->format(number, rounded_string);
-
- icu::Formattable formattable;
UErrorCode status = U_ZERO_ERROR;
- icu_decimal_format->parse(rounded_string, formattable, status);
+ icu::number::FormattedNumber formatted_number =
+ fmt->formatDouble(number, status);
CHECK(U_SUCCESS(status));
- double rounded = formattable.getDouble(status);
+ icu::UnicodeString result =
+ icu_plural_rules->select(formatted_number, status);
CHECK(U_SUCCESS(status));
- icu::UnicodeString result = icu_plural_rules->select(rounded);
- return isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>(
- reinterpret_cast<const uint16_t*>(result.getBuffer()), result.length()));
+ return Intl::ToString(isolate, result);
}
namespace {
@@ -261,36 +230,27 @@ Handle<JSObject> JSPluralRules::ResolvedOptions(
CreateDataPropertyForOptions(isolate, options, plural_rules->TypeAsString(),
"type");
- icu::DecimalFormat* icu_decimal_format =
- plural_rules->icu_decimal_format().raw();
- CHECK_NOT_NULL(icu_decimal_format);
-
- // This is a safe upcast as icu::DecimalFormat inherits from
- // icu::NumberFormat.
- icu::NumberFormat* icu_number_format =
- static_cast<icu::NumberFormat*>(icu_decimal_format);
+ UErrorCode status = U_ZERO_ERROR;
+ icu::number::LocalizedNumberFormatter* icu_number_formatter =
+ plural_rules->icu_number_formatter().raw();
+ icu::UnicodeString skeleton = icu_number_formatter->toSkeleton(status);
+ CHECK(U_SUCCESS(status));
- int min_int_digits = icu_number_format->getMinimumIntegerDigits();
- CreateDataPropertyForOptions(isolate, options, min_int_digits,
- "minimumIntegerDigits");
+ CreateDataPropertyForOptions(
+ isolate, options,
+ JSNumberFormat::MinimumIntegerDigitsFromSkeleton(skeleton),
+ "minimumIntegerDigits");
+ int32_t min = 0, max = 0;
+ JSNumberFormat::FractionDigitsFromSkeleton(skeleton, &min, &max);
- int min_fraction_digits = icu_number_format->getMinimumFractionDigits();
- CreateDataPropertyForOptions(isolate, options, min_fraction_digits,
- "minimumFractionDigits");
+ CreateDataPropertyForOptions(isolate, options, min, "minimumFractionDigits");
- int max_fraction_digits = icu_number_format->getMaximumFractionDigits();
- CreateDataPropertyForOptions(isolate, options, max_fraction_digits,
- "maximumFractionDigits");
+ CreateDataPropertyForOptions(isolate, options, max, "maximumFractionDigits");
- if (icu_decimal_format->areSignificantDigitsUsed()) {
- int min_significant_digits =
- icu_decimal_format->getMinimumSignificantDigits();
- CreateDataPropertyForOptions(isolate, options, min_significant_digits,
+ if (JSNumberFormat::SignificantDigitsFromSkeleton(skeleton, &min, &max)) {
+ CreateDataPropertyForOptions(isolate, options, min,
"minimumSignificantDigits");
-
- int max_significant_digits =
- icu_decimal_format->getMaximumSignificantDigits();
- CreateDataPropertyForOptions(isolate, options, max_significant_digits,
+ CreateDataPropertyForOptions(isolate, options, max,
"maximumSignificantDigits");
}
@@ -299,7 +259,6 @@ Handle<JSObject> JSPluralRules::ResolvedOptions(
icu::PluralRules* icu_plural_rules = plural_rules->icu_plural_rules().raw();
CHECK_NOT_NULL(icu_plural_rules);
- UErrorCode status = U_ZERO_ERROR;
std::unique_ptr<icu::StringEnumeration> categories(
icu_plural_rules->getKeywords(status));
CHECK(U_SUCCESS(status));
@@ -329,13 +288,39 @@ Handle<JSObject> JSPluralRules::ResolvedOptions(
return options;
}
+namespace {
+
+class PluralRulesAvailableLocales {
+ public:
+ PluralRulesAvailableLocales() {
+ UErrorCode status = U_ZERO_ERROR;
+ std::unique_ptr<icu::StringEnumeration> locales(
+ icu::PluralRules::getAvailableLocales(status));
+ CHECK(U_SUCCESS(status));
+ int32_t len = 0;
+ const char* locale = nullptr;
+ while ((locale = locales->next(&len, status)) != nullptr &&
+ U_SUCCESS(status)) {
+ std::string str(locale);
+ if (len > 3) {
+ std::replace(str.begin(), str.end(), '_', '-');
+ }
+ set_.insert(std::move(str));
+ }
+ }
+ const std::set<std::string>& Get() const { return set_; }
+
+ private:
+ std::set<std::string> set_;
+};
+
+} // namespace
+
const std::set<std::string>& JSPluralRules::GetAvailableLocales() {
- // TODO(ftang): For PluralRules, filter out locales that
- // don't support PluralRules.
- // PluralRules is missing an appropriate getAvailableLocales method,
- // so we should filter from all locales, but it's not clear how; see
- // https://ssl.icu-project.org/trac/ticket/12756
- return Intl::GetAvailableLocalesForLocale();
+ static base::LazyInstance<PluralRulesAvailableLocales>::type
+ available_locales = LAZY_INSTANCE_INITIALIZER;
+ return available_locales.Pointer()->Get();
+ // return Intl::GetAvailableLocalesForLocale();
}
} // namespace internal
diff --git a/deps/v8/src/objects/js-plural-rules.h b/deps/v8/src/objects/js-plural-rules.h
index 249090bdf6..840efb07ed 100644
--- a/deps/v8/src/objects/js-plural-rules.h
+++ b/deps/v8/src/objects/js-plural-rules.h
@@ -22,8 +22,10 @@
#include "src/objects/object-macros.h"
namespace U_ICU_NAMESPACE {
-class DecimalFormat;
class PluralRules;
+namespace number {
+class LocalizedNumberFormatter;
+} // namespace number
} // namespace U_ICU_NAMESPACE
namespace v8 {
@@ -31,9 +33,9 @@ namespace internal {
class JSPluralRules : public JSObject {
public:
- V8_WARN_UNUSED_RESULT static MaybeHandle<JSPluralRules> Initialize(
- Isolate* isolate, Handle<JSPluralRules> plural_rules,
- Handle<Object> locales, Handle<Object> options);
+ V8_WARN_UNUSED_RESULT static MaybeHandle<JSPluralRules> New(
+ Isolate* isolate, Handle<Map> map, Handle<Object> locales,
+ Handle<Object> options);
static Handle<JSObject> ResolvedOptions(Isolate* isolate,
Handle<JSPluralRules> plural_rules);
@@ -45,12 +47,7 @@ class JSPluralRules : public JSObject {
// [[Type]] is one of the values "cardinal" or "ordinal",
// identifying the plural rules used.
- enum class Type {
- CARDINAL,
- ORDINAL,
-
- COUNT
- };
+ enum class Type { CARDINAL, ORDINAL };
inline void set_type(Type type);
inline Type type() const;
@@ -76,7 +73,8 @@ class JSPluralRules : public JSObject {
DECL_ACCESSORS(locale, String)
DECL_INT_ACCESSORS(flags)
DECL_ACCESSORS(icu_plural_rules, Managed<icu::PluralRules>)
- DECL_ACCESSORS(icu_decimal_format, Managed<icu::DecimalFormat>)
+ DECL_ACCESSORS(icu_number_formatter,
+ Managed<icu::number::LocalizedNumberFormatter>)
OBJECT_CONSTRUCTORS(JSPluralRules, JSObject);
};
diff --git a/deps/v8/src/objects/js-proxy-inl.h b/deps/v8/src/objects/js-proxy-inl.h
index f33628b5c2..0683cfeec8 100644
--- a/deps/v8/src/objects/js-proxy-inl.h
+++ b/deps/v8/src/objects/js-proxy-inl.h
@@ -15,12 +15,7 @@
namespace v8 {
namespace internal {
-OBJECT_CONSTRUCTORS_IMPL(JSProxy, JSReceiver)
-
-CAST_ACCESSOR(JSProxy)
-
-ACCESSORS(JSProxy, target, Object, kTargetOffset)
-ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
+TQ_OBJECT_CONSTRUCTORS_IMPL(JSProxy)
bool JSProxy::IsRevoked() const { return !handler().IsJSReceiver(); }
diff --git a/deps/v8/src/objects/js-proxy.h b/deps/v8/src/objects/js-proxy.h
index c4f98927e9..8e29c08bc1 100644
--- a/deps/v8/src/objects/js-proxy.h
+++ b/deps/v8/src/objects/js-proxy.h
@@ -15,21 +15,14 @@ namespace v8 {
namespace internal {
// The JSProxy describes EcmaScript Harmony proxies
-class JSProxy : public JSReceiver {
+class JSProxy : public TorqueGeneratedJSProxy<JSProxy, JSReceiver> {
public:
V8_WARN_UNUSED_RESULT static MaybeHandle<JSProxy> New(Isolate* isolate,
Handle<Object>,
Handle<Object>);
- // [handler]: The handler property.
- DECL_ACCESSORS(handler, Object)
- // [target]: The target property.
- DECL_ACCESSORS(target, Object)
-
static MaybeHandle<NativeContext> GetFunctionRealm(Handle<JSProxy> proxy);
- DECL_CAST(JSProxy)
-
V8_INLINE bool IsRevoked() const;
static void Revoke(Handle<JSProxy> proxy);
@@ -70,6 +63,10 @@ class JSProxy : public JSReceiver {
V8_WARN_UNUSED_RESULT static Maybe<bool> CheckHasTrap(
Isolate* isolate, Handle<Name> name, Handle<JSReceiver> target);
+ // ES6 9.5.10
+ V8_WARN_UNUSED_RESULT static Maybe<bool> CheckDeleteTrap(
+ Isolate* isolate, Handle<Name> name, Handle<JSReceiver> target);
+
// ES6 9.5.8
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetProperty(
Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name,
@@ -106,10 +103,6 @@ class JSProxy : public JSReceiver {
static const int kMaxIterationLimit = 100 * 1024;
- // Layout description.
- DEFINE_FIELD_OFFSET_CONSTANTS(JSReceiver::kHeaderSize,
- TORQUE_GENERATED_JSPROXY_FIELDS)
-
// kTargetOffset aliases with the elements of JSObject. The fact that
// JSProxy::target is a Javascript value which cannot be confused with an
// elements backing store is exploited by loading from this offset from an
@@ -125,7 +118,7 @@ class JSProxy : public JSReceiver {
PropertyDescriptor* desc,
Maybe<ShouldThrow> should_throw);
- OBJECT_CONSTRUCTORS(JSProxy, JSReceiver);
+ TQ_OBJECT_CONSTRUCTORS(JSProxy)
};
// JSProxyRevocableResult is just a JSObject with a specific initial map.
diff --git a/deps/v8/src/objects/js-regexp.h b/deps/v8/src/objects/js-regexp.h
index e525c66e3e..18355079f8 100644
--- a/deps/v8/src/objects/js-regexp.h
+++ b/deps/v8/src/objects/js-regexp.h
@@ -37,13 +37,13 @@ class JSRegExp : public JSObject {
// IRREGEXP: Compiled with Irregexp.
enum Type { NOT_COMPILED, ATOM, IRREGEXP };
struct FlagShiftBit {
- static const int kGlobal = 0;
- static const int kIgnoreCase = 1;
- static const int kMultiline = 2;
- static const int kSticky = 3;
- static const int kUnicode = 4;
- static const int kDotAll = 5;
- static const int kInvalid = 7;
+ static constexpr int kGlobal = 0;
+ static constexpr int kIgnoreCase = 1;
+ static constexpr int kMultiline = 2;
+ static constexpr int kSticky = 3;
+ static constexpr int kUnicode = 4;
+ static constexpr int kDotAll = 5;
+ static constexpr int kInvalid = 6;
};
enum Flag : uint8_t {
kNone = 0,
@@ -57,28 +57,31 @@ class JSRegExp : public JSObject {
kInvalid = 1 << FlagShiftBit::kInvalid, // Not included in FlagCount.
};
using Flags = base::Flags<Flag>;
- static constexpr int FlagCount() { return 6; }
-
- static int FlagShiftBits(Flag flag) {
- switch (flag) {
- case kGlobal:
- return FlagShiftBit::kGlobal;
- case kIgnoreCase:
- return FlagShiftBit::kIgnoreCase;
- case kMultiline:
- return FlagShiftBit::kMultiline;
- case kSticky:
- return FlagShiftBit::kSticky;
- case kUnicode:
- return FlagShiftBit::kUnicode;
- case kDotAll:
- return FlagShiftBit::kDotAll;
- default:
- STATIC_ASSERT(FlagCount() == 6);
- UNREACHABLE();
- }
+
+ static constexpr int kFlagCount = 6;
+
+ static constexpr Flag FlagFromChar(char c) {
+ STATIC_ASSERT(kFlagCount == 6);
+ // clang-format off
+ return c == 'g' ? kGlobal
+ : c == 'i' ? kIgnoreCase
+ : c == 'm' ? kMultiline
+ : c == 'y' ? kSticky
+ : c == 'u' ? kUnicode
+ : c == 's' ? kDotAll
+ : kInvalid;
+ // clang-format on
}
+ STATIC_ASSERT(static_cast<int>(kNone) == v8::RegExp::kNone);
+ STATIC_ASSERT(static_cast<int>(kGlobal) == v8::RegExp::kGlobal);
+ STATIC_ASSERT(static_cast<int>(kIgnoreCase) == v8::RegExp::kIgnoreCase);
+ STATIC_ASSERT(static_cast<int>(kMultiline) == v8::RegExp::kMultiline);
+ STATIC_ASSERT(static_cast<int>(kSticky) == v8::RegExp::kSticky);
+ STATIC_ASSERT(static_cast<int>(kUnicode) == v8::RegExp::kUnicode);
+ STATIC_ASSERT(static_cast<int>(kDotAll) == v8::RegExp::kDotAll);
+ STATIC_ASSERT(kFlagCount == v8::RegExp::kFlagCount);
+
DECL_ACCESSORS(data, Object)
DECL_ACCESSORS(flags, Object)
DECL_ACCESSORS(last_index, Object)
diff --git a/deps/v8/src/objects/js-relative-time-format-inl.h b/deps/v8/src/objects/js-relative-time-format-inl.h
index 1ff66b1a12..fac3439b31 100644
--- a/deps/v8/src/objects/js-relative-time-format-inl.h
+++ b/deps/v8/src/objects/js-relative-time-format-inl.h
@@ -27,7 +27,7 @@ ACCESSORS(JSRelativeTimeFormat, icu_formatter,
SMI_ACCESSORS(JSRelativeTimeFormat, flags, kFlagsOffset)
inline void JSRelativeTimeFormat::set_style(Style style) {
- DCHECK_GT(Style::COUNT, style);
+ DCHECK_GE(StyleBits::kMax, style);
int hints = flags();
hints = StyleBits::update(hints, style);
set_flags(hints);
@@ -38,7 +38,7 @@ inline JSRelativeTimeFormat::Style JSRelativeTimeFormat::style() const {
}
inline void JSRelativeTimeFormat::set_numeric(Numeric numeric) {
- DCHECK_GT(Numeric::COUNT, numeric);
+ DCHECK_GE(NumericBits::kMax, numeric);
int hints = flags();
hints = NumericBits::update(hints, numeric);
set_flags(hints);
diff --git a/deps/v8/src/objects/js-relative-time-format.cc b/deps/v8/src/objects/js-relative-time-format.cc
index 59a3bf7ea0..28f8c757ee 100644
--- a/deps/v8/src/objects/js-relative-time-format.cc
+++ b/deps/v8/src/objects/js-relative-time-format.cc
@@ -34,9 +34,8 @@ UDateRelativeDateTimeFormatterStyle getIcuStyle(
return UDAT_STYLE_SHORT;
case JSRelativeTimeFormat::Style::NARROW:
return UDAT_STYLE_NARROW;
- case JSRelativeTimeFormat::Style::COUNT:
- UNREACHABLE();
}
+ UNREACHABLE();
}
} // namespace
@@ -54,11 +53,9 @@ JSRelativeTimeFormat::Numeric JSRelativeTimeFormat::getNumeric(
UNREACHABLE();
}
-MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize(
- Isolate* isolate, Handle<JSRelativeTimeFormat> relative_time_format_holder,
- Handle<Object> locales, Handle<Object> input_options) {
- relative_time_format_holder->set_flags(0);
-
+MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
+ Isolate* isolate, Handle<Map> map, Handle<Object> locales,
+ Handle<Object> input_options) {
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> maybe_requested_locales =
Intl::CanonicalizeLocaleList(isolate, locales);
@@ -125,7 +122,6 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize(
Handle<String> locale_str = isolate->factory()->NewStringFromAsciiChecked(
maybe_locale_str.FromJust().c_str());
- relative_time_format_holder->set_locale(*locale_str);
// 15. Let s be ? GetOption(options, "style", "string",
// «"long", "short", "narrow"», "long").
@@ -136,9 +132,6 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize(
MAYBE_RETURN(maybe_style, MaybeHandle<JSRelativeTimeFormat>());
Style style_enum = maybe_style.FromJust();
- // 16. Set relativeTimeFormat.[[Style]] to s.
- relative_time_format_holder->set_style(style_enum);
-
// 17. Let numeric be ? GetOption(options, "numeric", "string",
// «"always", "auto"», "always").
Maybe<Numeric> maybe_numeric = Intl::GetStringOption<Numeric>(
@@ -147,9 +140,6 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize(
MAYBE_RETURN(maybe_numeric, MaybeHandle<JSRelativeTimeFormat>());
Numeric numeric_enum = maybe_numeric.FromJust();
- // 18. Set relativeTimeFormat.[[Numeric]] to numeric.
- relative_time_format_holder->set_numeric(numeric_enum);
-
// 19. Let relativeTimeFormat.[[NumberFormat]] be
// ? Construct(%NumberFormat%, « nfLocale, nfOptions »).
icu::NumberFormat* number_format =
@@ -179,6 +169,21 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize(
Managed<icu::RelativeDateTimeFormatter>::FromRawPtr(isolate, 0,
icu_formatter);
+ // Now all properties are ready, so we can allocate the result object.
+ Handle<JSRelativeTimeFormat> relative_time_format_holder =
+ Handle<JSRelativeTimeFormat>::cast(
+ isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
+ DisallowHeapAllocation no_gc;
+ relative_time_format_holder->set_flags(0);
+
+ relative_time_format_holder->set_locale(*locale_str);
+
+ // 16. Set relativeTimeFormat.[[Style]] to s.
+ relative_time_format_holder->set_style(style_enum);
+
+ // 18. Set relativeTimeFormat.[[Numeric]] to numeric.
+ relative_time_format_holder->set_numeric(numeric_enum);
+
// 21. Set relativeTimeFormat.[[InitializedRelativeTimeFormat]] to true.
relative_time_format_holder->set_icu_formatter(*managed_formatter);
@@ -214,9 +219,8 @@ Handle<String> JSRelativeTimeFormat::StyleAsString() const {
return GetReadOnlyRoots().short_string_handle();
case Style::NARROW:
return GetReadOnlyRoots().narrow_string_handle();
- case Style::COUNT:
- UNREACHABLE();
}
+ UNREACHABLE();
}
Handle<String> JSRelativeTimeFormat::NumericAsString() const {
@@ -225,9 +229,8 @@ Handle<String> JSRelativeTimeFormat::NumericAsString() const {
return GetReadOnlyRoots().always_string_handle();
case Numeric::AUTO:
return GetReadOnlyRoots().auto_string_handle();
- case Numeric::COUNT:
- UNREACHABLE();
}
+ UNREACHABLE();
}
namespace {
diff --git a/deps/v8/src/objects/js-relative-time-format.h b/deps/v8/src/objects/js-relative-time-format.h
index 740336c29c..6e405e345e 100644
--- a/deps/v8/src/objects/js-relative-time-format.h
+++ b/deps/v8/src/objects/js-relative-time-format.h
@@ -30,12 +30,11 @@ namespace internal {
class JSRelativeTimeFormat : public JSObject {
public:
- // Initializes relative time format object with properties derived from input
+ // Creates relative time format object with properties derived from input
// locales and options.
- V8_WARN_UNUSED_RESULT static MaybeHandle<JSRelativeTimeFormat> Initialize(
- Isolate* isolate,
- Handle<JSRelativeTimeFormat> relative_time_format_holder,
- Handle<Object> locales, Handle<Object> options);
+ V8_WARN_UNUSED_RESULT static MaybeHandle<JSRelativeTimeFormat> New(
+ Isolate* isolate, Handle<Map> map, Handle<Object> locales,
+ Handle<Object> options);
V8_WARN_UNUSED_RESULT static Handle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSRelativeTimeFormat> format_holder);
@@ -67,10 +66,9 @@ class JSRelativeTimeFormat : public JSObject {
// ecma402/#sec-properties-of-intl-relativetimeformat-instances
enum class Style {
- LONG, // Everything spelled out.
- SHORT, // Abbreviations used when possible.
- NARROW, // Use the shortest possible form.
- COUNT
+ LONG, // Everything spelled out.
+ SHORT, // Abbreviations used when possible.
+ NARROW // Use the shortest possible form.
};
inline void set_style(Style style);
inline Style style() const;
@@ -82,9 +80,8 @@ class JSRelativeTimeFormat : public JSObject {
// ecma402/#sec-properties-of-intl-relativetimeformat-instances
enum class Numeric {
ALWAYS, // numerical descriptions are always used ("1 day ago")
- AUTO, // numerical descriptions are used only when no more specific
+ AUTO // numerical descriptions are used only when no more specific
// version is available ("yesterday")
- COUNT
};
inline void set_numeric(Numeric numeric);
inline Numeric numeric() const;
diff --git a/deps/v8/src/objects/js-segment-iterator-inl.h b/deps/v8/src/objects/js-segment-iterator-inl.h
index 24a827c030..b2d745179a 100644
--- a/deps/v8/src/objects/js-segment-iterator-inl.h
+++ b/deps/v8/src/objects/js-segment-iterator-inl.h
@@ -35,7 +35,7 @@ CAST_ACCESSOR(JSSegmentIterator)
inline void JSSegmentIterator::set_granularity(
JSSegmenter::Granularity granularity) {
- DCHECK_GT(JSSegmenter::Granularity::COUNT, granularity);
+ DCHECK_GE(GranularityBits::kMax, granularity);
int hints = flags();
hints = GranularityBits::update(hints, granularity);
set_flags(hints);
diff --git a/deps/v8/src/objects/js-segment-iterator.cc b/deps/v8/src/objects/js-segment-iterator.cc
index 3d2b19ca5c..509db37d44 100644
--- a/deps/v8/src/objects/js-segment-iterator.cc
+++ b/deps/v8/src/objects/js-segment-iterator.cc
@@ -37,9 +37,8 @@ Handle<String> JSSegmentIterator::GranularityAsString() const {
return GetReadOnlyRoots().word_string_handle();
case JSSegmenter::Granularity::SENTENCE:
return GetReadOnlyRoots().sentence_string_handle();
- case JSSegmenter::Granularity::COUNT:
- UNREACHABLE();
}
+ UNREACHABLE();
}
MaybeHandle<JSSegmentIterator> JSSegmentIterator::Create(
@@ -49,22 +48,25 @@ MaybeHandle<JSSegmentIterator> JSSegmentIterator::Create(
// 1. Let iterator be ObjectCreate(%SegmentIteratorPrototype%).
Handle<Map> map = Handle<Map>(
isolate->native_context()->intl_segment_iterator_map(), isolate);
- Handle<JSObject> result = isolate->factory()->NewJSObjectFromMap(map);
+ Handle<Managed<icu::BreakIterator>> managed_break_iterator =
+ Managed<icu::BreakIterator>::FromRawPtr(isolate, 0, break_iterator);
+ Handle<Managed<icu::UnicodeString>> unicode_string =
+ Intl::SetTextToBreakIterator(isolate, text, break_iterator);
+
+ // Now all properties are ready, so we can allocate the result object.
+ Handle<JSObject> result = isolate->factory()->NewJSObjectFromMap(map);
+ DisallowHeapAllocation no_gc;
Handle<JSSegmentIterator> segment_iterator =
Handle<JSSegmentIterator>::cast(result);
segment_iterator->set_flags(0);
segment_iterator->set_granularity(granularity);
// 2. Let iterator.[[SegmentIteratorSegmenter]] be segmenter.
- Handle<Managed<icu::BreakIterator>> managed_break_iterator =
- Managed<icu::BreakIterator>::FromRawPtr(isolate, 0, break_iterator);
segment_iterator->set_icu_break_iterator(*managed_break_iterator);
// 3. Let iterator.[[SegmentIteratorString]] be string.
- Managed<icu::UnicodeString> unicode_string =
- Intl::SetTextToBreakIterator(isolate, text, break_iterator);
- segment_iterator->set_unicode_string(unicode_string);
+ segment_iterator->set_unicode_string(*unicode_string);
// 4. Let iterator.[[SegmentIteratorIndex]] be 0.
// step 4 is stored inside break_iterator.
@@ -119,9 +121,8 @@ Handle<Object> JSSegmentIterator::BreakType() const {
return GetReadOnlyRoots().sep_string_handle();
}
return GetReadOnlyRoots().undefined_value_handle();
- case JSSegmenter::Granularity::COUNT:
- UNREACHABLE();
}
+ UNREACHABLE();
}
// ecma402 #sec-segment-iterator-prototype-index
diff --git a/deps/v8/src/objects/js-segmenter-inl.h b/deps/v8/src/objects/js-segmenter-inl.h
index b4adf4c8e6..a31de29c25 100644
--- a/deps/v8/src/objects/js-segmenter-inl.h
+++ b/deps/v8/src/objects/js-segmenter-inl.h
@@ -27,7 +27,7 @@ ACCESSORS(JSSegmenter, icu_break_iterator, Managed<icu::BreakIterator>,
SMI_ACCESSORS(JSSegmenter, flags, kFlagsOffset)
inline void JSSegmenter::set_granularity(Granularity granularity) {
- DCHECK_GT(Granularity::COUNT, granularity);
+ DCHECK_GE(GranularityBits::kMax, granularity);
int hints = flags();
hints = GranularityBits::update(hints, granularity);
set_flags(hints);
diff --git a/deps/v8/src/objects/js-segmenter.cc b/deps/v8/src/objects/js-segmenter.cc
index 5321334678..7985cf1c99 100644
--- a/deps/v8/src/objects/js-segmenter.cc
+++ b/deps/v8/src/objects/js-segmenter.cc
@@ -30,11 +30,9 @@ JSSegmenter::Granularity JSSegmenter::GetGranularity(const char* str) {
UNREACHABLE();
}
-MaybeHandle<JSSegmenter> JSSegmenter::Initialize(
- Isolate* isolate, Handle<JSSegmenter> segmenter_holder,
- Handle<Object> locales, Handle<Object> input_options) {
- segmenter_holder->set_flags(0);
-
+MaybeHandle<JSSegmenter> JSSegmenter::New(Isolate* isolate, Handle<Map> map,
+ Handle<Object> locales,
+ Handle<Object> input_options) {
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> maybe_requested_locales =
Intl::CanonicalizeLocaleList(isolate, locales);
@@ -69,11 +67,8 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize(
Intl::ResolvedLocale r =
Intl::ResolveLocale(isolate, JSSegmenter::GetAvailableLocales(),
requested_locales, matcher, {});
-
- // 10. Set segmenter.[[Locale]] to the value of r.[[Locale]].
Handle<String> locale_str =
isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
- segmenter_holder->set_locale(*locale_str);
// 13. Let granularity be ? GetOption(options, "granularity", "string", «
// "grapheme", "word", "sentence" », "grapheme").
@@ -85,9 +80,6 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize(
MAYBE_RETURN(maybe_granularity, MaybeHandle<JSSegmenter>());
Granularity granularity_enum = maybe_granularity.FromJust();
- // 14. Set segmenter.[[SegmenterGranularity]] to granularity.
- segmenter_holder->set_granularity(granularity_enum);
-
icu::Locale icu_locale = r.icu_locale;
DCHECK(!icu_locale.isBogus());
@@ -107,8 +99,6 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize(
icu_break_iterator.reset(
icu::BreakIterator::createSentenceInstance(icu_locale, status));
break;
- case Granularity::COUNT:
- UNREACHABLE();
}
CHECK(U_SUCCESS(status));
@@ -118,6 +108,18 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize(
Managed<icu::BreakIterator>::FromUniquePtr(isolate, 0,
std::move(icu_break_iterator));
+ // Now all properties are ready, so we can allocate the result object.
+ Handle<JSSegmenter> segmenter_holder = Handle<JSSegmenter>::cast(
+ isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
+ DisallowHeapAllocation no_gc;
+ segmenter_holder->set_flags(0);
+
+ // 10. Set segmenter.[[Locale]] to the value of r.[[Locale]].
+ segmenter_holder->set_locale(*locale_str);
+
+ // 14. Set segmenter.[[SegmenterGranularity]] to granularity.
+ segmenter_holder->set_granularity(granularity_enum);
+
segmenter_holder->set_icu_break_iterator(*managed_break_iterator);
return segmenter_holder;
}
@@ -157,9 +159,8 @@ Handle<String> JSSegmenter::GranularityAsString() const {
return GetReadOnlyRoots().word_string_handle();
case Granularity::SENTENCE:
return GetReadOnlyRoots().sentence_string_handle();
- case Granularity::COUNT:
- UNREACHABLE();
}
+ UNREACHABLE();
}
const std::set<std::string>& JSSegmenter::GetAvailableLocales() {
diff --git a/deps/v8/src/objects/js-segmenter.h b/deps/v8/src/objects/js-segmenter.h
index 423dd67497..641cf106fb 100644
--- a/deps/v8/src/objects/js-segmenter.h
+++ b/deps/v8/src/objects/js-segmenter.h
@@ -30,11 +30,11 @@ namespace internal {
class JSSegmenter : public JSObject {
public:
- // Initializes segmenter object with properties derived from input
- // locales and options.
- V8_WARN_UNUSED_RESULT static MaybeHandle<JSSegmenter> Initialize(
- Isolate* isolate, Handle<JSSegmenter> segmenter_holder,
- Handle<Object> locales, Handle<Object> options);
+ // Creates segmenter object with properties derived from input locales and
+ // options.
+ V8_WARN_UNUSED_RESULT static MaybeHandle<JSSegmenter> New(
+ Isolate* isolate, Handle<Map> map, Handle<Object> locales,
+ Handle<Object> options);
V8_WARN_UNUSED_RESULT static Handle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSSegmenter> segmenter_holder);
@@ -56,8 +56,7 @@ class JSSegmenter : public JSObject {
enum class Granularity {
GRAPHEME, // for character-breaks
WORD, // for word-breaks
- SENTENCE, // for sentence-breaks
- COUNT
+ SENTENCE // for sentence-breaks
};
inline void set_granularity(Granularity granularity);
inline Granularity granularity() const;
diff --git a/deps/v8/src/objects/js-weak-refs-inl.h b/deps/v8/src/objects/js-weak-refs-inl.h
index 6632a31002..46f28e883e 100644
--- a/deps/v8/src/objects/js-weak-refs-inl.h
+++ b/deps/v8/src/objects/js-weak-refs-inl.h
@@ -97,16 +97,16 @@ void JSFinalizationGroup::Register(
}
}
-void JSFinalizationGroup::Unregister(
- Handle<JSFinalizationGroup> finalization_group, Handle<Object> key,
- Isolate* isolate) {
+bool JSFinalizationGroup::Unregister(
+ Handle<JSFinalizationGroup> finalization_group,
+ Handle<JSReceiver> unregister_token, Isolate* isolate) {
// Iterate through the doubly linked list of WeakCells associated with the
// key. Each WeakCell will be in the "active_cells" or "cleared_cells" list of
// its FinalizationGroup; remove it from there.
if (!finalization_group->key_map().IsUndefined(isolate)) {
Handle<ObjectHashTable> key_map =
handle(ObjectHashTable::cast(finalization_group->key_map()), isolate);
- Object value = key_map->Lookup(key);
+ Object value = key_map->Lookup(unregister_token);
Object undefined = ReadOnlyRoots(isolate).undefined_value();
while (value.IsWeakCell()) {
WeakCell weak_cell = WeakCell::cast(value);
@@ -116,9 +116,13 @@ void JSFinalizationGroup::Unregister(
weak_cell.set_key_list_next(undefined);
}
bool was_present;
- key_map = ObjectHashTable::Remove(isolate, key_map, key, &was_present);
+ key_map = ObjectHashTable::Remove(isolate, key_map, unregister_token,
+ &was_present);
finalization_group->set_key_map(*key_map);
+ return was_present;
}
+
+ return false;
}
bool JSFinalizationGroup::NeedsCleanup() const {
diff --git a/deps/v8/src/objects/js-weak-refs.h b/deps/v8/src/objects/js-weak-refs.h
index b846c2e608..6a401fecee 100644
--- a/deps/v8/src/objects/js-weak-refs.h
+++ b/deps/v8/src/objects/js-weak-refs.h
@@ -41,8 +41,9 @@ class JSFinalizationGroup : public JSObject {
Handle<JSReceiver> target,
Handle<Object> holdings, Handle<Object> key,
Isolate* isolate);
- inline static void Unregister(Handle<JSFinalizationGroup> finalization_group,
- Handle<Object> key, Isolate* isolate);
+ inline static bool Unregister(Handle<JSFinalizationGroup> finalization_group,
+ Handle<JSReceiver> unregister_token,
+ Isolate* isolate);
// Returns true if the cleared_cells list is non-empty.
inline bool NeedsCleanup() const;
@@ -57,24 +58,13 @@ class JSFinalizationGroup : public JSObject {
// Constructs an iterator for the WeakCells in the cleared_cells list and
// calls the user's cleanup function.
- static void Cleanup(Handle<JSFinalizationGroup> finalization_group,
- Isolate* isolate);
-
-// Layout description.
-#define JS_FINALIZATION_GROUP_FIELDS(V) \
- V(kNativeContextOffset, kTaggedSize) \
- V(kCleanupOffset, kTaggedSize) \
- V(kActiveCellsOffset, kTaggedSize) \
- V(kClearedCellsOffset, kTaggedSize) \
- V(kKeyMapOffset, kTaggedSize) \
- V(kNextOffset, kTaggedSize) \
- V(kFlagsOffset, kTaggedSize) \
- /* Header size. */ \
- V(kSize, 0)
+ static void Cleanup(Isolate* isolate,
+ Handle<JSFinalizationGroup> finalization_group,
+ Handle<Object> callback);
+ // Layout description.
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
- JS_FINALIZATION_GROUP_FIELDS)
-#undef JS_FINALIZATION_GROUP_FIELDS
+ TORQUE_GENERATED_JSFINALIZATION_GROUP_FIELDS)
// Bitfields in flags.
class ScheduledForCleanupField : public BitField<bool, 0, 1> {};
@@ -106,21 +96,9 @@ class WeakCell : public HeapObject {
DECL_ACCESSORS(key_list_prev, Object)
DECL_ACCESSORS(key_list_next, Object)
-// Layout description.
-#define WEAK_CELL_FIELDS(V) \
- V(kFinalizationGroupOffset, kTaggedSize) \
- V(kTargetOffset, kTaggedSize) \
- V(kHoldingsOffset, kTaggedSize) \
- V(kPrevOffset, kTaggedSize) \
- V(kNextOffset, kTaggedSize) \
- V(kKeyOffset, kTaggedSize) \
- V(kKeyListPrevOffset, kTaggedSize) \
- V(kKeyListNextOffset, kTaggedSize) \
- /* Header size. */ \
- V(kSize, 0)
-
- DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, WEAK_CELL_FIELDS)
-#undef WEAK_CELL_FIELDS
+ // Layout description.
+ DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
+ TORQUE_GENERATED_WEAK_CELL_FIELDS)
class BodyDescriptor;
@@ -146,14 +124,9 @@ class JSWeakRef : public JSObject {
DECL_ACCESSORS(target, HeapObject)
-// Layout description.
-#define JS_WEAK_REF_FIELDS(V) \
- V(kTargetOffset, kTaggedSize) \
- /* Header size. */ \
- V(kSize, 0)
-
- DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_WEAK_REF_FIELDS)
-#undef JS_WEAK_REF_FIELDS
+ // Layout description.
+ DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
+ TORQUE_GENERATED_JSWEAK_REF_FIELDS)
class BodyDescriptor;
@@ -189,15 +162,10 @@ class JSFinalizationGroupCleanupIterator : public JSObject {
DECL_ACCESSORS(finalization_group, JSFinalizationGroup)
-// Layout description.
-#define JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_FIELDS(V) \
- V(kFinalizationGroupOffset, kTaggedSize) \
- /* Header size. */ \
- V(kSize, 0)
-
- DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
- JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_FIELDS)
-#undef JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_FIELDS
+ // Layout description.
+ DEFINE_FIELD_OFFSET_CONSTANTS(
+ JSObject::kHeaderSize,
+ TORQUE_GENERATED_JSFINALIZATION_GROUP_CLEANUP_ITERATOR_FIELDS)
OBJECT_CONSTRUCTORS(JSFinalizationGroupCleanupIterator, JSObject);
};
diff --git a/deps/v8/src/objects/keys.cc b/deps/v8/src/objects/keys.cc
index d3a1f6bdc2..18b38ed744 100644
--- a/deps/v8/src/objects/keys.cc
+++ b/deps/v8/src/objects/keys.cc
@@ -395,6 +395,11 @@ MaybeHandle<FixedArray> GetOwnKeysWithElements(Isolate* isolate,
MaybeHandle<FixedArray> FastKeyAccumulator::GetKeys(
GetKeysConversion keys_conversion) {
+ // TODO(v8:9401): We should extend the fast path of KeyAccumulator::GetKeys to
+ // also use fast path even when filter = SKIP_SYMBOLS. We used to pass wrong
+ // filter to use fast path in cases where we tried to verify all properties
+ // are enumerable. However these checks weren't correct and passing the wrong
+ // filter led to wrong behaviour.
if (filter_ == ENUMERABLE_STRINGS) {
Handle<FixedArray> keys;
if (GetKeysFast(keys_conversion).ToHandle(&keys)) {
diff --git a/deps/v8/src/objects/layout-descriptor-inl.h b/deps/v8/src/objects/layout-descriptor-inl.h
index 49683da267..ad0a058a92 100644
--- a/deps/v8/src/objects/layout-descriptor-inl.h
+++ b/deps/v8/src/objects/layout-descriptor-inl.h
@@ -209,11 +209,11 @@ int LayoutDescriptor::number_of_layout_words() {
}
uint32_t LayoutDescriptor::get_layout_word(int index) const {
- return get_uint32(index);
+ return get_uint32_relaxed(index);
}
void LayoutDescriptor::set_layout_word(int index, uint32_t value) {
- set_uint32(index, value);
+ set_uint32_relaxed(index, value);
}
// LayoutDescriptorHelper is a helper class for querying whether inobject
diff --git a/deps/v8/src/objects/literal-objects-inl.h b/deps/v8/src/objects/literal-objects-inl.h
index 1ddb333cff..32b43cd8f7 100644
--- a/deps/v8/src/objects/literal-objects-inl.h
+++ b/deps/v8/src/objects/literal-objects-inl.h
@@ -15,6 +15,10 @@
namespace v8 {
namespace internal {
+//
+// ObjectBoilerplateDescription
+//
+
OBJECT_CONSTRUCTORS_IMPL(ObjectBoilerplateDescription, FixedArray)
CAST_ACCESSOR(ObjectBoilerplateDescription)
@@ -22,6 +26,70 @@ CAST_ACCESSOR(ObjectBoilerplateDescription)
SMI_ACCESSORS(ObjectBoilerplateDescription, flags,
FixedArray::OffsetOfElementAt(kLiteralTypeOffset))
+Object ObjectBoilerplateDescription::name(int index) const {
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return name(isolate, index);
+}
+
+Object ObjectBoilerplateDescription::name(Isolate* isolate, int index) const {
+ // get() already checks for out of bounds access, but we do not want to allow
+ // access to the last element, if it is the number of properties.
+ DCHECK_NE(size(), index);
+ return get(isolate, 2 * index + kDescriptionStartIndex);
+}
+
+Object ObjectBoilerplateDescription::value(int index) const {
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return value(isolate, index);
+}
+
+Object ObjectBoilerplateDescription::value(Isolate* isolate, int index) const {
+ return get(isolate, 2 * index + 1 + kDescriptionStartIndex);
+}
+
+void ObjectBoilerplateDescription::set_key_value(int index, Object key,
+ Object value) {
+ DCHECK_LT(index, size());
+ DCHECK_GE(index, 0);
+ set(2 * index + kDescriptionStartIndex, key);
+ set(2 * index + 1 + kDescriptionStartIndex, value);
+}
+
+int ObjectBoilerplateDescription::size() const {
+ DCHECK_EQ(0, (length() - kDescriptionStartIndex -
+ (this->has_number_of_properties() ? 1 : 0)) %
+ 2);
+ // Rounding is intended.
+ return (length() - kDescriptionStartIndex) / 2;
+}
+
+bool ObjectBoilerplateDescription::has_number_of_properties() const {
+ return (length() - kDescriptionStartIndex) % 2 != 0;
+}
+
+int ObjectBoilerplateDescription::backing_store_size() const {
+ if (has_number_of_properties()) {
+ // If present, the last entry contains the number of properties.
+ return Smi::ToInt(this->get(length() - 1));
+ }
+ // If the number is not given explicitly, we assume there are no
+ // properties with computed names.
+ return size();
+}
+
+void ObjectBoilerplateDescription::set_backing_store_size(
+ int backing_store_size) {
+ DCHECK(has_number_of_properties());
+ DCHECK_NE(size(), backing_store_size);
+ CHECK(Smi::IsValid(backing_store_size));
+ // TODO(ishell): move this value to the header
+ set(length() - 1, Smi::FromInt(backing_store_size));
+}
+
+//
+// ClassBoilerplate
+//
+
OBJECT_CONSTRUCTORS_IMPL(ClassBoilerplate, FixedArray)
CAST_ACCESSOR(ClassBoilerplate)
@@ -52,6 +120,10 @@ ACCESSORS(ClassBoilerplate, instance_elements_template, Object,
ACCESSORS(ClassBoilerplate, instance_computed_properties, FixedArray,
FixedArray::OffsetOfElementAt(kPrototypeComputedPropertiesIndex))
+//
+// ArrayBoilerplateDescription
+//
+
OBJECT_CONSTRUCTORS_IMPL(ArrayBoilerplateDescription, Struct)
CAST_ACCESSOR(ArrayBoilerplateDescription)
diff --git a/deps/v8/src/objects/literal-objects.cc b/deps/v8/src/objects/literal-objects.cc
index bfdbd9317b..7328c11f31 100644
--- a/deps/v8/src/objects/literal-objects.cc
+++ b/deps/v8/src/objects/literal-objects.cc
@@ -17,56 +17,6 @@
namespace v8 {
namespace internal {
-Object ObjectBoilerplateDescription::name(int index) const {
- // get() already checks for out of bounds access, but we do not want to allow
- // access to the last element, if it is the number of properties.
- DCHECK_NE(size(), index);
- return get(2 * index + kDescriptionStartIndex);
-}
-
-Object ObjectBoilerplateDescription::value(int index) const {
- return get(2 * index + 1 + kDescriptionStartIndex);
-}
-
-void ObjectBoilerplateDescription::set_key_value(int index, Object key,
- Object value) {
- DCHECK_LT(index, size());
- DCHECK_GE(index, 0);
- set(2 * index + kDescriptionStartIndex, key);
- set(2 * index + 1 + kDescriptionStartIndex, value);
-}
-
-int ObjectBoilerplateDescription::size() const {
- DCHECK_EQ(0, (length() - kDescriptionStartIndex -
- (this->has_number_of_properties() ? 1 : 0)) %
- 2);
- // Rounding is intended.
- return (length() - kDescriptionStartIndex) / 2;
-}
-
-int ObjectBoilerplateDescription::backing_store_size() const {
- if (has_number_of_properties()) {
- // If present, the last entry contains the number of properties.
- return Smi::ToInt(this->get(length() - 1));
- }
- // If the number is not given explicitly, we assume there are no
- // properties with computed names.
- return size();
-}
-
-void ObjectBoilerplateDescription::set_backing_store_size(
- Isolate* isolate, int backing_store_size) {
- DCHECK(has_number_of_properties());
- DCHECK_NE(size(), backing_store_size);
- Handle<Object> backing_store_size_obj =
- isolate->factory()->NewNumberFromInt(backing_store_size);
- set(length() - 1, *backing_store_size_obj);
-}
-
-bool ObjectBoilerplateDescription::has_number_of_properties() const {
- return (length() - kDescriptionStartIndex) % 2 != 0;
-}
-
namespace {
inline int EncodeComputedEntry(ClassBoilerplate::ValueKind value_kind,
@@ -306,8 +256,12 @@ class ObjectDescriptor {
void IncPropertiesCount() { ++property_count_; }
void IncElementsCount() { ++element_count_; }
+ explicit ObjectDescriptor(int property_slack)
+ : property_slack_(property_slack) {}
+
bool HasDictionaryProperties() const {
- return computed_count_ > 0 || property_count_ > kMaxNumberOfDescriptors;
+ return computed_count_ > 0 ||
+ (property_count_ + property_slack_) > kMaxNumberOfDescriptors;
}
Handle<Object> properties_template() const {
@@ -324,17 +278,17 @@ class ObjectDescriptor {
return computed_properties_;
}
- void CreateTemplates(Isolate* isolate, int slack) {
+ void CreateTemplates(Isolate* isolate) {
Factory* factory = isolate->factory();
descriptor_array_template_ = factory->empty_descriptor_array();
properties_dictionary_template_ = factory->empty_property_dictionary();
- if (property_count_ || HasDictionaryProperties() || slack) {
+ if (property_count_ || computed_count_ || property_slack_) {
if (HasDictionaryProperties()) {
properties_dictionary_template_ = NameDictionary::New(
- isolate, property_count_ + computed_count_ + slack);
+ isolate, property_count_ + computed_count_ + property_slack_);
} else {
- descriptor_array_template_ =
- DescriptorArray::Allocate(isolate, 0, property_count_ + slack);
+ descriptor_array_template_ = DescriptorArray::Allocate(
+ isolate, 0, property_count_ + property_slack_);
}
}
elements_dictionary_template_ =
@@ -419,6 +373,7 @@ class ObjectDescriptor {
}
private:
+ const int property_slack_;
int property_count_ = 0;
int next_enumeration_index_ = PropertyDetails::kInitialIndex;
int element_count_ = 0;
@@ -454,8 +409,8 @@ Handle<ClassBoilerplate> ClassBoilerplate::BuildClassBoilerplate(
// in CanonicalHandleScope.
HandleScope scope(isolate);
Factory* factory = isolate->factory();
- ObjectDescriptor static_desc;
- ObjectDescriptor instance_desc;
+ ObjectDescriptor static_desc(kMinimumClassPropertiesCount);
+ ObjectDescriptor instance_desc(kMinimumPrototypePropertiesCount);
for (int i = 0; i < expr->properties()->length(); i++) {
ClassLiteral::Property* property = expr->properties()->at(i);
@@ -475,7 +430,7 @@ Handle<ClassBoilerplate> ClassBoilerplate::BuildClassBoilerplate(
//
// Initialize class object template.
//
- static_desc.CreateTemplates(isolate, kMinimumClassPropertiesCount);
+ static_desc.CreateTemplates(isolate);
STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0);
{
// Add length_accessor.
@@ -509,7 +464,7 @@ Handle<ClassBoilerplate> ClassBoilerplate::BuildClassBoilerplate(
//
// Initialize prototype object template.
//
- instance_desc.CreateTemplates(isolate, kMinimumPrototypePropertiesCount);
+ instance_desc.CreateTemplates(isolate);
{
Handle<Object> value(
Smi::FromInt(ClassBoilerplate::kConstructorArgumentIndex), isolate);
diff --git a/deps/v8/src/objects/literal-objects.h b/deps/v8/src/objects/literal-objects.h
index 35ae98a05b..f009a54f8a 100644
--- a/deps/v8/src/objects/literal-objects.h
+++ b/deps/v8/src/objects/literal-objects.h
@@ -21,20 +21,23 @@ class ClassLiteral;
// of properties in the backing store. This number includes properties with
// computed names that are not
// in the list.
+// TODO(ishell): Don't derive from FixedArray as it already has its own map.
class ObjectBoilerplateDescription : public FixedArray {
public:
- Object name(int index) const;
- Object value(int index) const;
+ inline Object name(int index) const;
+ inline Object name(Isolate* isolate, int index) const;
- void set_key_value(int index, Object key, Object value);
+ inline Object value(int index) const;
+ inline Object value(Isolate* isolate, int index) const;
+
+ inline void set_key_value(int index, Object key, Object value);
// The number of boilerplate properties.
- int size() const;
+ inline int size() const;
// Number of boilerplate properties and properties with computed names.
- int backing_store_size() const;
-
- void set_backing_store_size(Isolate* isolate, int backing_store_size);
+ inline int backing_store_size() const;
+ inline void set_backing_store_size(int backing_store_size);
// Used to encode ObjectLiteral::Flags for nested object literals
// Stored as the first element of the fixed array
@@ -47,7 +50,7 @@ class ObjectBoilerplateDescription : public FixedArray {
DECL_PRINTER(ObjectBoilerplateDescription)
private:
- bool has_number_of_properties() const;
+ inline bool has_number_of_properties() const;
OBJECT_CONSTRUCTORS(ObjectBoilerplateDescription, FixedArray);
};
diff --git a/deps/v8/src/objects/lookup-inl.h b/deps/v8/src/objects/lookup-inl.h
index 5b2dbff258..648398be5e 100644
--- a/deps/v8/src/objects/lookup-inl.h
+++ b/deps/v8/src/objects/lookup-inl.h
@@ -31,7 +31,7 @@ LookupIterator::LookupIterator(Handle<Object> receiver, Handle<Name> name,
LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
Handle<Name> name, Handle<JSReceiver> holder,
Configuration configuration)
- : configuration_(ComputeConfiguration(configuration, name)),
+ : configuration_(ComputeConfiguration(isolate, configuration, name)),
interceptor_state_(InterceptorState::kUninitialized),
property_details_(PropertyDetails::Empty()),
isolate_(isolate),
@@ -90,7 +90,7 @@ Handle<Name> LookupIterator::GetName() {
}
bool LookupIterator::is_dictionary_holder() const {
- return !holder_->HasFastProperties();
+ return !holder_->HasFastProperties(isolate_);
}
Handle<Map> LookupIterator::transition_map() const {
@@ -111,23 +111,23 @@ Handle<T> LookupIterator::GetHolder() const {
bool LookupIterator::ExtendingNonExtensible(Handle<JSReceiver> receiver) {
DCHECK(receiver.is_identical_to(GetStoreTarget<JSReceiver>()));
- return !receiver->map().is_extensible() &&
- (IsElement() || !name_->IsPrivate());
+ return !receiver->map(isolate_).is_extensible() &&
+ (IsElement() || !name_->IsPrivate(isolate_));
}
bool LookupIterator::IsCacheableTransition() {
DCHECK_EQ(TRANSITION, state_);
- return transition_->IsPropertyCell() ||
+ return transition_->IsPropertyCell(isolate_) ||
(transition_map()->is_dictionary_map() &&
- !GetStoreTarget<JSReceiver>()->HasFastProperties()) ||
- transition_map()->GetBackPointer().IsMap();
+ !GetStoreTarget<JSReceiver>()->HasFastProperties(isolate_)) ||
+ transition_map()->GetBackPointer(isolate_).IsMap(isolate_);
}
void LookupIterator::UpdateProtector() {
if (IsElement()) return;
// This list must be kept in sync with
// CodeStubAssembler::CheckForAssociatedProtector!
- ReadOnlyRoots roots(heap());
+ ReadOnlyRoots roots(isolate_);
if (*name_ == roots.is_concat_spreadable_symbol() ||
*name_ == roots.constructor_string() || *name_ == roots.next_string() ||
*name_ == roots.species_symbol() || *name_ == roots.iterator_symbol() ||
@@ -139,52 +139,59 @@ void LookupIterator::UpdateProtector() {
int LookupIterator::descriptor_number() const {
DCHECK(!IsElement());
DCHECK(has_property_);
- DCHECK(holder_->HasFastProperties());
+ DCHECK(holder_->HasFastProperties(isolate_));
return number_;
}
int LookupIterator::dictionary_entry() const {
DCHECK(!IsElement());
DCHECK(has_property_);
- DCHECK(!holder_->HasFastProperties());
+ DCHECK(!holder_->HasFastProperties(isolate_));
return number_;
}
+// static
LookupIterator::Configuration LookupIterator::ComputeConfiguration(
- Configuration configuration, Handle<Name> name) {
- return name->IsPrivate() ? OWN_SKIP_INTERCEPTOR : configuration;
+ Isolate* isolate, Configuration configuration, Handle<Name> name) {
+ return name->IsPrivate(isolate) ? OWN_SKIP_INTERCEPTOR : configuration;
}
+// static
Handle<JSReceiver> LookupIterator::GetRoot(Isolate* isolate,
Handle<Object> receiver,
uint32_t index) {
- if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver);
+ if (receiver->IsJSReceiver(isolate))
+ return Handle<JSReceiver>::cast(receiver);
return GetRootForNonJSReceiver(isolate, receiver, index);
}
template <class T>
Handle<T> LookupIterator::GetStoreTarget() const {
- DCHECK(receiver_->IsJSReceiver());
- if (receiver_->IsJSGlobalProxy()) {
- Map map = JSGlobalProxy::cast(*receiver_).map();
- if (map.has_hidden_prototype()) {
- return handle(JSGlobalObject::cast(map.prototype()), isolate_);
+ DCHECK(receiver_->IsJSReceiver(isolate_));
+ if (receiver_->IsJSGlobalProxy(isolate_)) {
+ HeapObject prototype =
+ JSGlobalProxy::cast(*receiver_).map(isolate_).prototype(isolate_);
+ if (prototype.IsJSGlobalObject(isolate_)) {
+ return handle(JSGlobalObject::cast(prototype), isolate_);
}
}
return Handle<T>::cast(receiver_);
}
+// static
template <bool is_element>
-InterceptorInfo LookupIterator::GetInterceptor(JSObject holder) {
- return is_element ? holder.GetIndexedInterceptor()
- : holder.GetNamedInterceptor();
+InterceptorInfo LookupIterator::GetInterceptor(Isolate* isolate,
+ JSObject holder) {
+ return is_element ? holder.GetIndexedInterceptor(isolate)
+ : holder.GetNamedInterceptor(isolate);
}
inline Handle<InterceptorInfo> LookupIterator::GetInterceptor() const {
DCHECK_EQ(INTERCEPTOR, state_);
- InterceptorInfo result =
- IsElement() ? GetInterceptor<true>(JSObject::cast(*holder_))
- : GetInterceptor<false>(JSObject::cast(*holder_));
+ JSObject holder = JSObject::cast(*holder_);
+ InterceptorInfo result = IsElement()
+ ? GetInterceptor<true>(isolate_, holder)
+ : GetInterceptor<false>(isolate_, holder);
return handle(result, isolate_);
}
diff --git a/deps/v8/src/objects/lookup.cc b/deps/v8/src/objects/lookup.cc
index 744cf67482..33130aafe5 100644
--- a/deps/v8/src/objects/lookup.cc
+++ b/deps/v8/src/objects/lookup.cc
@@ -80,50 +80,6 @@ LookupIterator LookupIterator::PropertyOrElement(Isolate* isolate,
return LookupIterator(isolate, receiver, name, configuration);
}
-// TODO(ishell): Consider removing this way of LookupIterator creation.
-// static
-LookupIterator LookupIterator::ForTransitionHandler(
- Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
- Handle<Object> value, MaybeHandle<Map> maybe_transition_map) {
- Handle<Map> transition_map;
- if (!maybe_transition_map.ToHandle(&transition_map) ||
- !transition_map->IsPrototypeValidityCellValid()) {
- // This map is not a valid transition handler, so full lookup is required.
- return LookupIterator(isolate, receiver, name);
- }
-
- PropertyDetails details = PropertyDetails::Empty();
- bool has_property;
- if (transition_map->is_dictionary_map()) {
- details = PropertyDetails(kData, NONE, PropertyCellType::kNoCell);
- has_property = false;
- } else {
- details = transition_map->GetLastDescriptorDetails();
- has_property = true;
- }
-#ifdef DEBUG
- if (name->IsPrivate()) {
- DCHECK_EQ(DONT_ENUM, details.attributes());
- } else {
- DCHECK_EQ(NONE, details.attributes());
- }
-#endif
- LookupIterator it(isolate, receiver, name, transition_map, details,
- has_property);
-
- if (!transition_map->is_dictionary_map()) {
- int descriptor_number = transition_map->LastAdded();
- Handle<Map> new_map =
- Map::PrepareForDataProperty(isolate, transition_map, descriptor_number,
- PropertyConstness::kConst, value);
- // Reload information; this is no-op if nothing changed.
- it.property_details_ =
- new_map->instance_descriptors().GetDetails(descriptor_number);
- it.transition_ = new_map;
- }
- return it;
-}
-
LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
Handle<Name> name, Handle<Map> transition_map,
PropertyDetails details, bool has_property)
@@ -151,7 +107,7 @@ void LookupIterator::Start() {
holder_ = initial_holder_;
JSReceiver holder = *holder_;
- Map map = holder.map();
+ Map map = holder.map(isolate_);
state_ = LookupInHolder<is_element>(map, holder);
if (IsFound()) return;
@@ -169,7 +125,7 @@ void LookupIterator::Next() {
has_property_ = false;
JSReceiver holder = *holder_;
- Map map = holder.map();
+ Map map = holder.map(isolate_);
if (map.IsSpecialReceiverMap()) {
state_ = IsElement() ? LookupInSpecialHolder<true>(map, holder)
@@ -195,7 +151,7 @@ void LookupIterator::NextInternal(Map map, JSReceiver holder) {
return;
}
holder = maybe_holder;
- map = holder.map();
+ map = holder.map(isolate_);
state_ = LookupInHolder<is_element>(map, holder);
} while (!IsFound());
@@ -218,17 +174,17 @@ Handle<JSReceiver> LookupIterator::GetRootForNonJSReceiver(
Isolate* isolate, Handle<Object> receiver, uint32_t index) {
// Strings are the only objects with properties (only elements) directly on
// the wrapper. Hence we can skip generating the wrapper for all other cases.
- if (receiver->IsString() &&
+ if (receiver->IsString(isolate) &&
index < static_cast<uint32_t>(String::cast(*receiver).length())) {
// TODO(verwaest): Speed this up. Perhaps use a cached wrapper on the native
// context, ensuring that we don't leak it into JS?
Handle<JSFunction> constructor = isolate->string_function();
Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
- Handle<JSValue>::cast(result)->set_value(*receiver);
+ Handle<JSPrimitiveWrapper>::cast(result)->set_value(*receiver);
return result;
}
- auto root =
- handle(receiver->GetPrototypeChainRootMap(isolate).prototype(), isolate);
+ auto root = handle(
+ receiver->GetPrototypeChainRootMap(isolate).prototype(isolate), isolate);
if (root->IsNull(isolate)) {
isolate->PushStackTraceAndDie(reinterpret_cast<void*>(receiver->ptr()));
}
@@ -236,8 +192,8 @@ Handle<JSReceiver> LookupIterator::GetRootForNonJSReceiver(
}
Handle<Map> LookupIterator::GetReceiverMap() const {
- if (receiver_->IsNumber()) return factory()->heap_number_map();
- return handle(Handle<HeapObject>::cast(receiver_)->map(), isolate_);
+ if (receiver_->IsNumber(isolate_)) return factory()->heap_number_map();
+ return handle(Handle<HeapObject>::cast(receiver_)->map(isolate_), isolate_);
}
bool LookupIterator::HasAccess() const {
@@ -250,13 +206,13 @@ template <bool is_element>
void LookupIterator::ReloadPropertyInformation() {
state_ = BEFORE_PROPERTY;
interceptor_state_ = InterceptorState::kUninitialized;
- state_ = LookupInHolder<is_element>(holder_->map(), *holder_);
- DCHECK(IsFound() || !holder_->HasFastProperties());
+ state_ = LookupInHolder<is_element>(holder_->map(isolate_), *holder_);
+ DCHECK(IsFound() || !holder_->HasFastProperties(isolate_));
}
namespace {
-bool IsTypedArrayFunctionInAnyContext(Isolate* isolate, JSReceiver holder) {
+bool IsTypedArrayFunctionInAnyContext(Isolate* isolate, HeapObject object) {
static uint32_t context_slots[] = {
#define TYPED_ARRAY_CONTEXT_SLOTS(Type, type, TYPE, ctype) \
Context::TYPE##_ARRAY_FUN_INDEX,
@@ -265,91 +221,99 @@ bool IsTypedArrayFunctionInAnyContext(Isolate* isolate, JSReceiver holder) {
#undef TYPED_ARRAY_CONTEXT_SLOTS
};
- if (!holder.IsJSFunction()) return false;
+ if (!object.IsJSFunction(isolate)) return false;
return std::any_of(
std::begin(context_slots), std::end(context_slots),
- [=](uint32_t slot) { return isolate->IsInAnyContext(holder, slot); });
+ [=](uint32_t slot) { return isolate->IsInAnyContext(object, slot); });
}
} // namespace
void LookupIterator::InternalUpdateProtector() {
if (isolate_->bootstrapper()->IsActive()) return;
+ if (!receiver_->IsHeapObject()) return;
+ Handle<HeapObject> receiver = Handle<HeapObject>::cast(receiver_);
- ReadOnlyRoots roots(heap());
+ Handle<NativeContext> native_context = isolate_->native_context();
+
+ ReadOnlyRoots roots(isolate_);
if (*name_ == roots.constructor_string()) {
if (!isolate_->IsArraySpeciesLookupChainIntact() &&
!isolate_->IsPromiseSpeciesLookupChainIntact() &&
- !isolate_->IsRegExpSpeciesLookupChainIntact() &&
+ !isolate_->IsRegExpSpeciesLookupChainIntact(native_context) &&
!isolate_->IsTypedArraySpeciesLookupChainIntact()) {
return;
}
// Setting the constructor property could change an instance's @@species
- if (holder_->IsJSArray()) {
+ if (receiver->IsJSArray(isolate_)) {
if (!isolate_->IsArraySpeciesLookupChainIntact()) return;
isolate_->CountUsage(
v8::Isolate::UseCounterFeature::kArrayInstanceConstructorModified);
isolate_->InvalidateArraySpeciesProtector();
return;
- } else if (holder_->IsJSPromise()) {
+ } else if (receiver->IsJSPromise(isolate_)) {
if (!isolate_->IsPromiseSpeciesLookupChainIntact()) return;
isolate_->InvalidatePromiseSpeciesProtector();
return;
- } else if (holder_->IsJSRegExp()) {
- if (!isolate_->IsRegExpSpeciesLookupChainIntact()) return;
- isolate_->InvalidateRegExpSpeciesProtector();
+ } else if (receiver->IsJSRegExp(isolate_)) {
+ if (!isolate_->IsRegExpSpeciesLookupChainIntact(native_context)) return;
+ isolate_->InvalidateRegExpSpeciesProtector(native_context);
return;
- } else if (holder_->IsJSTypedArray()) {
+ } else if (receiver->IsJSTypedArray(isolate_)) {
if (!isolate_->IsTypedArraySpeciesLookupChainIntact()) return;
isolate_->InvalidateTypedArraySpeciesProtector();
return;
}
- if (holder_->map().is_prototype_map()) {
+ if (receiver->map(isolate_).is_prototype_map()) {
DisallowHeapAllocation no_gc;
// Setting the constructor of any prototype with the @@species protector
// (of any realm) also needs to invalidate the protector.
- // For typed arrays, we check a prototype of this holder since TypedArrays
- // have different prototypes for each type, and their parent prototype is
- // pointing the same TYPED_ARRAY_PROTOTYPE.
- if (isolate_->IsInAnyContext(*holder_,
+ // For typed arrays, we check a prototype of this receiver since
+ // TypedArrays have different prototypes for each type, and their parent
+ // prototype is pointing the same TYPED_ARRAY_PROTOTYPE.
+ if (isolate_->IsInAnyContext(*receiver,
Context::INITIAL_ARRAY_PROTOTYPE_INDEX)) {
if (!isolate_->IsArraySpeciesLookupChainIntact()) return;
isolate_->CountUsage(
v8::Isolate::UseCounterFeature::kArrayPrototypeConstructorModified);
isolate_->InvalidateArraySpeciesProtector();
- } else if (isolate_->IsInAnyContext(*holder_,
+ } else if (isolate_->IsInAnyContext(*receiver,
Context::PROMISE_PROTOTYPE_INDEX)) {
if (!isolate_->IsPromiseSpeciesLookupChainIntact()) return;
isolate_->InvalidatePromiseSpeciesProtector();
- } else if (isolate_->IsInAnyContext(*holder_,
+ } else if (isolate_->IsInAnyContext(*receiver,
Context::REGEXP_PROTOTYPE_INDEX)) {
- if (!isolate_->IsRegExpSpeciesLookupChainIntact()) return;
- isolate_->InvalidateRegExpSpeciesProtector();
+ if (!isolate_->IsRegExpSpeciesLookupChainIntact(native_context)) return;
+ isolate_->InvalidateRegExpSpeciesProtector(native_context);
} else if (isolate_->IsInAnyContext(
- holder_->map().prototype(),
+ receiver->map(isolate_).prototype(isolate_),
Context::TYPED_ARRAY_PROTOTYPE_INDEX)) {
if (!isolate_->IsTypedArraySpeciesLookupChainIntact()) return;
isolate_->InvalidateTypedArraySpeciesProtector();
}
}
} else if (*name_ == roots.next_string()) {
- if (isolate_->IsInAnyContext(
- *holder_, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX)) {
+ if (receiver->IsJSArrayIterator() ||
+ isolate_->IsInAnyContext(
+ *receiver, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX)) {
// Setting the next property of %ArrayIteratorPrototype% also needs to
// invalidate the array iterator protector.
if (!isolate_->IsArrayIteratorLookupChainIntact()) return;
isolate_->InvalidateArrayIteratorProtector();
- } else if (isolate_->IsInAnyContext(
- *holder_, Context::INITIAL_MAP_ITERATOR_PROTOTYPE_INDEX)) {
+ } else if (receiver->IsJSMapIterator() ||
+ isolate_->IsInAnyContext(
+ *receiver, Context::INITIAL_MAP_ITERATOR_PROTOTYPE_INDEX)) {
if (!isolate_->IsMapIteratorLookupChainIntact()) return;
isolate_->InvalidateMapIteratorProtector();
- } else if (isolate_->IsInAnyContext(
- *holder_, Context::INITIAL_SET_ITERATOR_PROTOTYPE_INDEX)) {
+ } else if (receiver->IsJSSetIterator() ||
+ isolate_->IsInAnyContext(
+ *receiver, Context::INITIAL_SET_ITERATOR_PROTOTYPE_INDEX)) {
if (!isolate_->IsSetIteratorLookupChainIntact()) return;
isolate_->InvalidateSetIteratorProtector();
- } else if (isolate_->IsInAnyContext(
- *receiver_,
+ } else if (receiver->IsJSStringIterator() ||
+ isolate_->IsInAnyContext(
+ *receiver,
Context::INITIAL_STRING_ITERATOR_PROTOTYPE_INDEX)) {
// Setting the next property of %StringIteratorPrototype% invalidates the
// string iterator protector.
@@ -359,26 +323,26 @@ void LookupIterator::InternalUpdateProtector() {
} else if (*name_ == roots.species_symbol()) {
if (!isolate_->IsArraySpeciesLookupChainIntact() &&
!isolate_->IsPromiseSpeciesLookupChainIntact() &&
- !isolate_->IsRegExpSpeciesLookupChainIntact() &&
+ !isolate_->IsRegExpSpeciesLookupChainIntact(native_context) &&
!isolate_->IsTypedArraySpeciesLookupChainIntact()) {
return;
}
// Setting the Symbol.species property of any Array, Promise or TypedArray
// constructor invalidates the @@species protector
- if (isolate_->IsInAnyContext(*holder_, Context::ARRAY_FUNCTION_INDEX)) {
+ if (isolate_->IsInAnyContext(*receiver, Context::ARRAY_FUNCTION_INDEX)) {
if (!isolate_->IsArraySpeciesLookupChainIntact()) return;
isolate_->CountUsage(
v8::Isolate::UseCounterFeature::kArraySpeciesModified);
isolate_->InvalidateArraySpeciesProtector();
- } else if (isolate_->IsInAnyContext(*holder_,
+ } else if (isolate_->IsInAnyContext(*receiver,
Context::PROMISE_FUNCTION_INDEX)) {
if (!isolate_->IsPromiseSpeciesLookupChainIntact()) return;
isolate_->InvalidatePromiseSpeciesProtector();
- } else if (isolate_->IsInAnyContext(*holder_,
+ } else if (isolate_->IsInAnyContext(*receiver,
Context::REGEXP_FUNCTION_INDEX)) {
- if (!isolate_->IsRegExpSpeciesLookupChainIntact()) return;
- isolate_->InvalidateRegExpSpeciesProtector();
- } else if (IsTypedArrayFunctionInAnyContext(isolate_, *holder_)) {
+ if (!isolate_->IsRegExpSpeciesLookupChainIntact(native_context)) return;
+ isolate_->InvalidateRegExpSpeciesProtector(native_context);
+ } else if (IsTypedArrayFunctionInAnyContext(isolate_, *receiver)) {
if (!isolate_->IsTypedArraySpeciesLookupChainIntact()) return;
isolate_->InvalidateTypedArraySpeciesProtector();
}
@@ -386,23 +350,33 @@ void LookupIterator::InternalUpdateProtector() {
if (!isolate_->IsIsConcatSpreadableLookupChainIntact()) return;
isolate_->InvalidateIsConcatSpreadableProtector();
} else if (*name_ == roots.iterator_symbol()) {
- if (holder_->IsJSArray()) {
+ if (receiver->IsJSArray(isolate_)) {
if (!isolate_->IsArrayIteratorLookupChainIntact()) return;
isolate_->InvalidateArrayIteratorProtector();
+ } else if (receiver->IsJSSet(isolate_) || receiver->IsJSSetIterator() ||
+ isolate_->IsInAnyContext(
+ *receiver, Context::INITIAL_SET_ITERATOR_PROTOTYPE_INDEX) ||
+ isolate_->IsInAnyContext(*receiver,
+ Context::INITIAL_SET_PROTOTYPE_INDEX)) {
+ if (isolate_->IsSetIteratorLookupChainIntact()) {
+ isolate_->InvalidateSetIteratorProtector();
+ }
+ } else if (receiver->IsJSMapIterator() ||
+ isolate_->IsInAnyContext(
+ *receiver, Context::INITIAL_MAP_ITERATOR_PROTOTYPE_INDEX)) {
+ if (isolate_->IsMapIteratorLookupChainIntact()) {
+ isolate_->InvalidateMapIteratorProtector();
+ }
} else if (isolate_->IsInAnyContext(
- *holder_, Context::INITIAL_ITERATOR_PROTOTYPE_INDEX)) {
+ *receiver, Context::INITIAL_ITERATOR_PROTOTYPE_INDEX)) {
if (isolate_->IsMapIteratorLookupChainIntact()) {
isolate_->InvalidateMapIteratorProtector();
}
if (isolate_->IsSetIteratorLookupChainIntact()) {
isolate_->InvalidateSetIteratorProtector();
}
- } else if (isolate_->IsInAnyContext(*holder_,
- Context::INITIAL_SET_PROTOTYPE_INDEX)) {
- if (!isolate_->IsSetIteratorLookupChainIntact()) return;
- isolate_->InvalidateSetIteratorProtector();
} else if (isolate_->IsInAnyContext(
- *receiver_, Context::INITIAL_STRING_PROTOTYPE_INDEX)) {
+ *receiver, Context::INITIAL_STRING_PROTOTYPE_INDEX)) {
// Setting the Symbol.iterator property of String.prototype invalidates
// the string iterator protector. Symbol.iterator can also be set on a
// String wrapper, but not on a primitive string. We only support
@@ -414,7 +388,7 @@ void LookupIterator::InternalUpdateProtector() {
if (!isolate_->IsPromiseResolveLookupChainIntact()) return;
// Setting the "resolve" property on any %Promise% intrinsic object
// invalidates the Promise.resolve protector.
- if (isolate_->IsInAnyContext(*holder_, Context::PROMISE_FUNCTION_INDEX)) {
+ if (isolate_->IsInAnyContext(*receiver, Context::PROMISE_FUNCTION_INDEX)) {
isolate_->InvalidatePromiseResolveProtector();
}
} else if (*name_ == roots.then_string()) {
@@ -426,10 +400,10 @@ void LookupIterator::InternalUpdateProtector() {
// to guard the fast-path in AsyncGeneratorResolve, where we can skip
// the ResolvePromise step and go directly to FulfillPromise if we
// know that the Object.prototype doesn't contain a "then" method.
- if (holder_->IsJSPromise() ||
- isolate_->IsInAnyContext(*holder_,
+ if (receiver->IsJSPromise(isolate_) ||
+ isolate_->IsInAnyContext(*receiver,
Context::INITIAL_OBJECT_PROTOTYPE_INDEX) ||
- isolate_->IsInAnyContext(*holder_, Context::PROMISE_PROTOTYPE_INDEX)) {
+ isolate_->IsInAnyContext(*receiver, Context::PROMISE_PROTOTYPE_INDEX)) {
isolate_->InvalidatePromiseThenProtector();
}
}
@@ -441,15 +415,16 @@ void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
Handle<JSReceiver> holder = GetHolder<JSReceiver>();
// JSProxy does not have fast properties so we do an early return.
- DCHECK_IMPLIES(holder->IsJSProxy(), !holder->HasFastProperties());
- DCHECK_IMPLIES(holder->IsJSProxy(), name()->IsPrivate());
- if (holder->IsJSProxy()) return;
+ DCHECK_IMPLIES(holder->IsJSProxy(isolate_),
+ !holder->HasFastProperties(isolate_));
+ DCHECK_IMPLIES(holder->IsJSProxy(isolate_), name()->IsPrivate(isolate_));
+ if (holder->IsJSProxy(isolate_)) return;
Handle<JSObject> holder_obj = Handle<JSObject>::cast(holder);
if (IsElement()) {
- ElementsKind kind = holder_obj->GetElementsKind();
- ElementsKind to = value->OptimalElementsKind();
+ ElementsKind kind = holder_obj->GetElementsKind(isolate_);
+ ElementsKind to = value->OptimalElementsKind(isolate_);
if (IsHoleyElementsKind(kind)) to = GetHoleyElementsKind(to);
to = GetMoreGeneralElementsKind(kind, to);
@@ -464,17 +439,18 @@ void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
return;
}
- if (holder_obj->IsJSGlobalObject()) {
+ if (holder_obj->IsJSGlobalObject(isolate_)) {
Handle<GlobalDictionary> dictionary(
- JSGlobalObject::cast(*holder_obj).global_dictionary(), isolate());
- Handle<PropertyCell> cell(dictionary->CellAt(dictionary_entry()),
+ JSGlobalObject::cast(*holder_obj).global_dictionary(isolate_),
+ isolate());
+ Handle<PropertyCell> cell(dictionary->CellAt(isolate_, dictionary_entry()),
isolate());
property_details_ = cell->property_details();
PropertyCell::PrepareForValue(isolate(), dictionary, dictionary_entry(),
value, property_details_);
return;
}
- if (!holder_obj->HasFastProperties()) return;
+ if (!holder_obj->HasFastProperties(isolate_)) return;
PropertyConstness new_constness = PropertyConstness::kConst;
if (constness() == PropertyConstness::kConst) {
@@ -485,20 +461,28 @@ void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
new_constness = PropertyConstness::kMutable;
}
- Handle<Map> old_map(holder_obj->map(), isolate_);
- Handle<Map> new_map = Map::PrepareForDataProperty(
- isolate(), old_map, descriptor_number(), new_constness, value);
+ Handle<Map> old_map(holder_obj->map(isolate_), isolate_);
+ DCHECK(!old_map->is_dictionary_map());
- if (old_map.is_identical_to(new_map)) {
- // Update the property details if the representation was None.
- if (constness() != new_constness || representation().IsNone()) {
- property_details_ =
- new_map->instance_descriptors().GetDetails(descriptor_number());
+ Handle<Map> new_map = Map::Update(isolate_, old_map);
+ if (!new_map->is_dictionary_map()) {
+ new_map = Map::PrepareForDataProperty(
+ isolate(), new_map, descriptor_number(), new_constness, value);
+
+ if (old_map.is_identical_to(new_map)) {
+ // Update the property details if the representation was None.
+ if (constness() != new_constness || representation().IsNone()) {
+ property_details_ = new_map->instance_descriptors(isolate_).GetDetails(
+ descriptor_number());
+ }
+ return;
}
- return;
}
+ // We should only get here if the new_map is different from the old map,
+ // otherwise we would have falled through to the is_identical_to check above.
+ DCHECK_NE(*old_map, *new_map);
- JSObject::MigrateToMap(holder_obj, new_map);
+ JSObject::MigrateToMap(isolate_, holder_obj, new_map);
ReloadPropertyInformation<false>();
}
@@ -510,53 +494,59 @@ void LookupIterator::ReconfigureDataProperty(Handle<Object> value,
Handle<JSReceiver> holder = GetHolder<JSReceiver>();
// Property details can never change for private properties.
- if (holder->IsJSProxy()) {
- DCHECK(name()->IsPrivate());
+ if (holder->IsJSProxy(isolate_)) {
+ DCHECK(name()->IsPrivate(isolate_));
return;
}
Handle<JSObject> holder_obj = Handle<JSObject>::cast(holder);
if (IsElement()) {
- DCHECK(!holder_obj->HasTypedArrayElements());
- DCHECK(attributes != NONE || !holder_obj->HasFastElements());
- Handle<FixedArrayBase> elements(holder_obj->elements(), isolate());
- holder_obj->GetElementsAccessor()->Reconfigure(holder_obj, elements,
- number_, value, attributes);
+ DCHECK(!holder_obj->HasTypedArrayElements(isolate_));
+ DCHECK(attributes != NONE || !holder_obj->HasFastElements(isolate_));
+ Handle<FixedArrayBase> elements(holder_obj->elements(isolate_), isolate());
+ holder_obj->GetElementsAccessor(isolate_)->Reconfigure(
+ holder_obj, elements, number_, value, attributes);
ReloadPropertyInformation<true>();
- } else if (holder_obj->HasFastProperties()) {
- Handle<Map> old_map(holder_obj->map(), isolate_);
- Handle<Map> new_map = Map::ReconfigureExistingProperty(
- isolate_, old_map, descriptor_number(), i::kData, attributes);
+ } else if (holder_obj->HasFastProperties(isolate_)) {
+ Handle<Map> old_map(holder_obj->map(isolate_), isolate_);
// Force mutable to avoid changing constant value by reconfiguring
// kData -> kAccessor -> kData.
- new_map =
- Map::PrepareForDataProperty(isolate(), new_map, descriptor_number(),
- PropertyConstness::kMutable, value);
- JSObject::MigrateToMap(holder_obj, new_map);
+ Handle<Map> new_map = Map::ReconfigureExistingProperty(
+ isolate_, old_map, descriptor_number(), i::kData, attributes,
+ PropertyConstness::kMutable);
+ if (!new_map->is_dictionary_map()) {
+ // Make sure that the data property has a compatible representation.
+ // TODO(leszeks): Do this as part of ReconfigureExistingProperty.
+ new_map =
+ Map::PrepareForDataProperty(isolate(), new_map, descriptor_number(),
+ PropertyConstness::kMutable, value);
+ }
+ JSObject::MigrateToMap(isolate_, holder_obj, new_map);
ReloadPropertyInformation<false>();
}
- if (!IsElement() && !holder_obj->HasFastProperties()) {
+ if (!IsElement() && !holder_obj->HasFastProperties(isolate_)) {
PropertyDetails details(kData, attributes, PropertyCellType::kMutable);
- if (holder_obj->map().is_prototype_map() &&
+ if (holder_obj->map(isolate_).is_prototype_map() &&
(property_details_.attributes() & READ_ONLY) == 0 &&
(attributes & READ_ONLY) != 0) {
// Invalidate prototype validity cell when a property is reconfigured
// from writable to read-only as this may invalidate transitioning store
// IC handlers.
- JSObject::InvalidatePrototypeChains(holder->map());
+ JSObject::InvalidatePrototypeChains(holder->map(isolate_));
}
- if (holder_obj->IsJSGlobalObject()) {
+ if (holder_obj->IsJSGlobalObject(isolate_)) {
Handle<GlobalDictionary> dictionary(
- JSGlobalObject::cast(*holder_obj).global_dictionary(), isolate());
+ JSGlobalObject::cast(*holder_obj).global_dictionary(isolate_),
+ isolate());
Handle<PropertyCell> cell = PropertyCell::PrepareForValue(
isolate(), dictionary, dictionary_entry(), value, details);
cell->set_value(*value);
property_details_ = cell->property_details();
} else {
- Handle<NameDictionary> dictionary(holder_obj->property_dictionary(),
- isolate());
+ Handle<NameDictionary> dictionary(
+ holder_obj->property_dictionary(isolate_), isolate());
PropertyDetails original_details =
dictionary->DetailsAt(dictionary_entry());
int enumeration_index = original_details.dictionary_index();
@@ -583,21 +573,21 @@ void LookupIterator::ReconfigureDataProperty(Handle<Object> value,
void LookupIterator::PrepareTransitionToDataProperty(
Handle<JSReceiver> receiver, Handle<Object> value,
PropertyAttributes attributes, StoreOrigin store_origin) {
- DCHECK_IMPLIES(receiver->IsJSProxy(), name()->IsPrivate());
+ DCHECK_IMPLIES(receiver->IsJSProxy(isolate_), name()->IsPrivate(isolate_));
DCHECK(receiver.is_identical_to(GetStoreTarget<JSReceiver>()));
if (state_ == TRANSITION) return;
- if (!IsElement() && name()->IsPrivate()) {
+ if (!IsElement() && name()->IsPrivate(isolate_)) {
attributes = static_cast<PropertyAttributes>(attributes | DONT_ENUM);
}
DCHECK(state_ != LookupIterator::ACCESSOR ||
- (GetAccessors()->IsAccessorInfo() &&
+ (GetAccessors()->IsAccessorInfo(isolate_) &&
AccessorInfo::cast(*GetAccessors()).is_special_data_property()));
DCHECK_NE(INTEGER_INDEXED_EXOTIC, state_);
DCHECK(state_ == NOT_FOUND || !HolderIsReceiverOrHiddenPrototype());
- Handle<Map> map(receiver->map(), isolate_);
+ Handle<Map> map(receiver->map(isolate_), isolate_);
// Dictionary maps can always have additional data properties.
if (map->is_dictionary_map()) {
@@ -608,9 +598,9 @@ void LookupIterator::PrepareTransitionToDataProperty(
int entry;
Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell(
global, name(), PropertyCellType::kUninitialized, &entry);
- Handle<GlobalDictionary> dictionary(global->global_dictionary(),
+ Handle<GlobalDictionary> dictionary(global->global_dictionary(isolate_),
isolate_);
- DCHECK(cell->value().IsTheHole(isolate_));
+ DCHECK(cell->value(isolate_).IsTheHole(isolate_));
DCHECK(!value->IsTheHole(isolate_));
transition_ = cell;
// Assign an enumeration index to the property and update
@@ -645,7 +635,7 @@ void LookupIterator::PrepareTransitionToDataProperty(
property_details_ =
PropertyDetails(kData, attributes, PropertyCellType::kNoCell);
} else {
- property_details_ = transition->GetLastDescriptorDetails();
+ property_details_ = transition->GetLastDescriptorDetails(isolate_);
has_property_ = true;
}
}
@@ -656,13 +646,14 @@ void LookupIterator::ApplyTransitionToDataProperty(
DCHECK(receiver.is_identical_to(GetStoreTarget<JSReceiver>()));
holder_ = receiver;
- if (receiver->IsJSGlobalObject()) {
- JSObject::InvalidatePrototypeChains(receiver->map());
+ if (receiver->IsJSGlobalObject(isolate_)) {
+ JSObject::InvalidatePrototypeChains(receiver->map(isolate_));
state_ = DATA;
return;
}
Handle<Map> transition = transition_map();
- bool simple_transition = transition->GetBackPointer() == receiver->map();
+ bool simple_transition =
+ transition->GetBackPointer(isolate_) == receiver->map(isolate_);
if (configuration_ == DEFAULT && !transition->is_dictionary_map() &&
!transition->IsPrototypeValidityCellValid()) {
@@ -673,21 +664,23 @@ void LookupIterator::ApplyTransitionToDataProperty(
transition->set_prototype_validity_cell(*validity_cell);
}
- if (!receiver->IsJSProxy()) {
- JSObject::MigrateToMap(Handle<JSObject>::cast(receiver), transition);
+ if (!receiver->IsJSProxy(isolate_)) {
+ JSObject::MigrateToMap(isolate_, Handle<JSObject>::cast(receiver),
+ transition);
}
if (simple_transition) {
int number = transition->LastAdded();
number_ = static_cast<uint32_t>(number);
- property_details_ = transition->GetLastDescriptorDetails();
+ property_details_ = transition->GetLastDescriptorDetails(isolate_);
state_ = DATA;
- } else if (receiver->map().is_dictionary_map()) {
- Handle<NameDictionary> dictionary(receiver->property_dictionary(),
+ } else if (receiver->map(isolate_).is_dictionary_map()) {
+ Handle<NameDictionary> dictionary(receiver->property_dictionary(isolate_),
isolate_);
int entry;
- if (receiver->map().is_prototype_map() && receiver->IsJSObject()) {
- JSObject::InvalidatePrototypeChains(receiver->map());
+ if (receiver->map(isolate_).is_prototype_map() &&
+ receiver->IsJSObject(isolate_)) {
+ JSObject::InvalidatePrototypeChains(receiver->map(isolate_));
}
dictionary = NameDictionary::Add(isolate(), dictionary, name(),
isolate_->factory()->uninitialized_value(),
@@ -708,11 +701,11 @@ void LookupIterator::Delete() {
Handle<JSReceiver> holder = Handle<JSReceiver>::cast(holder_);
if (IsElement()) {
Handle<JSObject> object = Handle<JSObject>::cast(holder);
- ElementsAccessor* accessor = object->GetElementsAccessor();
+ ElementsAccessor* accessor = object->GetElementsAccessor(isolate_);
accessor->Delete(object, number_);
} else {
- DCHECK(!name()->IsPrivateName());
- bool is_prototype_map = holder->map().is_prototype_map();
+ DCHECK(!name()->IsPrivateName(isolate_));
+ bool is_prototype_map = holder->map(isolate_).is_prototype_map();
RuntimeCallTimerScope stats_scope(
isolate_, is_prototype_map
? RuntimeCallCounterId::kPrototypeObject_DeleteProperty
@@ -721,13 +714,13 @@ void LookupIterator::Delete() {
PropertyNormalizationMode mode =
is_prototype_map ? KEEP_INOBJECT_PROPERTIES : CLEAR_INOBJECT_PROPERTIES;
- if (holder->HasFastProperties()) {
- JSObject::NormalizeProperties(Handle<JSObject>::cast(holder), mode, 0,
- "DeletingProperty");
+ if (holder->HasFastProperties(isolate_)) {
+ JSObject::NormalizeProperties(isolate_, Handle<JSObject>::cast(holder),
+ mode, 0, "DeletingProperty");
ReloadPropertyInformation<false>();
}
JSReceiver::DeleteNormalizedProperty(holder, number_);
- if (holder->IsJSObject()) {
+ if (holder->IsJSObject(isolate_)) {
JSObject::ReoptimizeIfPrototype(Handle<JSObject>::cast(holder));
}
}
@@ -742,12 +735,12 @@ void LookupIterator::TransitionToAccessorProperty(
// handled via a trap. Adding properties to primitive values is not
// observable.
Handle<JSObject> receiver = GetStoreTarget<JSObject>();
- if (!IsElement() && name()->IsPrivate()) {
+ if (!IsElement() && name()->IsPrivate(isolate_)) {
attributes = static_cast<PropertyAttributes>(attributes | DONT_ENUM);
}
- if (!IsElement() && !receiver->map().is_dictionary_map()) {
- Handle<Map> old_map(receiver->map(), isolate_);
+ if (!IsElement() && !receiver->map(isolate_).is_dictionary_map()) {
+ Handle<Map> old_map(receiver->map(isolate_), isolate_);
if (!holder_.is_identical_to(receiver)) {
holder_ = receiver;
@@ -760,13 +753,14 @@ void LookupIterator::TransitionToAccessorProperty(
Handle<Map> new_map = Map::TransitionToAccessorProperty(
isolate_, old_map, name_, descriptor, getter, setter, attributes);
- bool simple_transition = new_map->GetBackPointer() == receiver->map();
- JSObject::MigrateToMap(receiver, new_map);
+ bool simple_transition =
+ new_map->GetBackPointer(isolate_) == receiver->map(isolate_);
+ JSObject::MigrateToMap(isolate_, receiver, new_map);
if (simple_transition) {
int number = new_map->LastAdded();
number_ = static_cast<uint32_t>(number);
- property_details_ = new_map->GetLastDescriptorDetails();
+ property_details_ = new_map->GetLastDescriptorDetails(isolate_);
state_ = ACCESSOR;
return;
}
@@ -776,7 +770,7 @@ void LookupIterator::TransitionToAccessorProperty(
}
Handle<AccessorPair> pair;
- if (state() == ACCESSOR && GetAccessors()->IsAccessorPair()) {
+ if (state() == ACCESSOR && GetAccessors()->IsAccessorPair(isolate_)) {
pair = Handle<AccessorPair>::cast(GetAccessors());
// If the component and attributes are identical, nothing has to be done.
if (pair->Equals(*getter, *setter)) {
@@ -818,13 +812,14 @@ void LookupIterator::TransitionToAccessorPair(Handle<Object> pair,
receiver, details);
receiver->RequireSlowElements(*dictionary);
- if (receiver->HasSlowArgumentsElements()) {
- FixedArray parameter_map = FixedArray::cast(receiver->elements());
+ if (receiver->HasSlowArgumentsElements(isolate_)) {
+ FixedArray parameter_map = FixedArray::cast(receiver->elements(isolate_));
uint32_t length = parameter_map.length() - 2;
if (number_ < length) {
- parameter_map.set(number_ + 2, ReadOnlyRoots(heap()).the_hole_value());
+ parameter_map.set(number_ + 2,
+ ReadOnlyRoots(isolate_).the_hole_value());
}
- FixedArray::cast(receiver->elements()).set(1, *dictionary);
+ FixedArray::cast(receiver->elements(isolate_)).set(1, *dictionary);
} else {
receiver->set_elements(*dictionary);
}
@@ -832,13 +827,13 @@ void LookupIterator::TransitionToAccessorPair(Handle<Object> pair,
ReloadPropertyInformation<true>();
} else {
PropertyNormalizationMode mode = CLEAR_INOBJECT_PROPERTIES;
- if (receiver->map().is_prototype_map()) {
- JSObject::InvalidatePrototypeChains(receiver->map());
+ if (receiver->map(isolate_).is_prototype_map()) {
+ JSObject::InvalidatePrototypeChains(receiver->map(isolate_));
mode = KEEP_INOBJECT_PROPERTIES;
}
// Normalize object to make this operation simple.
- JSObject::NormalizeProperties(receiver, mode, 0,
+ JSObject::NormalizeProperties(isolate_, receiver, mode, 0,
"TransitionToAccessorPair");
JSObject::SetNormalizedProperty(receiver, name_, pair, details);
@@ -859,61 +854,54 @@ bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const {
DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY);
// Optimization that only works if configuration_ is not mutable.
if (!check_prototype_chain()) return true;
- DisallowHeapAllocation no_gc;
if (*receiver_ == *holder_) return true;
- if (!receiver_->IsJSReceiver()) return false;
- JSReceiver current = JSReceiver::cast(*receiver_);
- JSReceiver object = *holder_;
- if (!current.map().has_hidden_prototype()) return false;
- // JSProxy do not occur as hidden prototypes.
- if (object.IsJSProxy()) return false;
- PrototypeIterator iter(isolate(), current, kStartAtPrototype,
- PrototypeIterator::END_AT_NON_HIDDEN);
- while (!iter.IsAtEnd()) {
- if (iter.GetCurrent<JSReceiver>() == object) return true;
- iter.Advance();
- }
- return false;
+ if (!receiver_->IsJSGlobalProxy(isolate_)) return false;
+ return Handle<JSGlobalProxy>::cast(receiver_)->map(isolate_).prototype(
+ isolate_) == *holder_;
}
Handle<Object> LookupIterator::FetchValue() const {
Object result;
if (IsElement()) {
Handle<JSObject> holder = GetHolder<JSObject>();
- ElementsAccessor* accessor = holder->GetElementsAccessor();
+ ElementsAccessor* accessor = holder->GetElementsAccessor(isolate_);
return accessor->Get(holder, number_);
- } else if (holder_->IsJSGlobalObject()) {
+ } else if (holder_->IsJSGlobalObject(isolate_)) {
Handle<JSGlobalObject> holder = GetHolder<JSGlobalObject>();
- result = holder->global_dictionary().ValueAt(number_);
- } else if (!holder_->HasFastProperties()) {
- result = holder_->property_dictionary().ValueAt(number_);
+ result = holder->global_dictionary(isolate_).ValueAt(isolate_, number_);
+ } else if (!holder_->HasFastProperties(isolate_)) {
+ result = holder_->property_dictionary(isolate_).ValueAt(isolate_, number_);
} else if (property_details_.location() == kField) {
DCHECK_EQ(kData, property_details_.kind());
Handle<JSObject> holder = GetHolder<JSObject>();
- FieldIndex field_index = FieldIndex::ForDescriptor(holder->map(), number_);
+ FieldIndex field_index =
+ FieldIndex::ForDescriptor(holder->map(isolate_), number_);
return JSObject::FastPropertyAt(holder, property_details_.representation(),
field_index);
} else {
- result = holder_->map().instance_descriptors().GetStrongValue(number_);
+ result =
+ holder_->map(isolate_).instance_descriptors(isolate_).GetStrongValue(
+ isolate_, number_);
}
return handle(result, isolate_);
}
bool LookupIterator::IsConstFieldValueEqualTo(Object value) const {
DCHECK(!IsElement());
- DCHECK(holder_->HasFastProperties());
+ DCHECK(holder_->HasFastProperties(isolate_));
DCHECK_EQ(kField, property_details_.location());
DCHECK_EQ(PropertyConstness::kConst, property_details_.constness());
Handle<JSObject> holder = GetHolder<JSObject>();
- FieldIndex field_index = FieldIndex::ForDescriptor(holder->map(), number_);
+ FieldIndex field_index =
+ FieldIndex::ForDescriptor(holder->map(isolate_), number_);
if (property_details_.representation().IsDouble()) {
- if (!value.IsNumber()) return false;
+ if (!value.IsNumber(isolate_)) return false;
uint64_t bits;
- if (holder->IsUnboxedDoubleField(field_index)) {
+ if (holder->IsUnboxedDoubleField(isolate_, field_index)) {
bits = holder->RawFastDoublePropertyAsBitsAt(field_index);
} else {
- Object current_value = holder->RawFastPropertyAt(field_index);
- DCHECK(current_value.IsMutableHeapNumber());
+ Object current_value = holder->RawFastPropertyAt(isolate_, field_index);
+ DCHECK(current_value.IsMutableHeapNumber(isolate_));
bits = MutableHeapNumber::cast(current_value).value_as_bits();
}
// Use bit representation of double to to check for hole double, since
@@ -927,11 +915,11 @@ bool LookupIterator::IsConstFieldValueEqualTo(Object value) const {
}
return Object::SameNumberValue(bit_cast<double>(bits), value.Number());
} else {
- Object current_value = holder->RawFastPropertyAt(field_index);
+ Object current_value = holder->RawFastPropertyAt(isolate_, field_index);
if (current_value.IsUninitialized(isolate()) || current_value == value) {
return true;
}
- return current_value.IsNumber() && value.IsNumber() &&
+ return current_value.IsNumber(isolate_) && value.IsNumber(isolate_) &&
Object::SameNumberValue(current_value.Number(), value.Number());
}
}
@@ -946,7 +934,7 @@ int LookupIterator::GetFieldDescriptorIndex() const {
int LookupIterator::GetAccessorIndex() const {
DCHECK(has_property_);
- DCHECK(holder_->HasFastProperties());
+ DCHECK(holder_->HasFastProperties(isolate_));
DCHECK_EQ(kDescriptor, property_details_.location());
DCHECK_EQ(kAccessor, property_details_.kind());
return descriptor_number();
@@ -954,36 +942,38 @@ int LookupIterator::GetAccessorIndex() const {
Handle<Map> LookupIterator::GetFieldOwnerMap() const {
DCHECK(has_property_);
- DCHECK(holder_->HasFastProperties());
+ DCHECK(holder_->HasFastProperties(isolate_));
DCHECK_EQ(kField, property_details_.location());
DCHECK(!IsElement());
- Map holder_map = holder_->map();
+ Map holder_map = holder_->map(isolate_);
return handle(holder_map.FindFieldOwner(isolate(), descriptor_number()),
isolate_);
}
FieldIndex LookupIterator::GetFieldIndex() const {
DCHECK(has_property_);
- DCHECK(holder_->HasFastProperties());
+ DCHECK(holder_->HasFastProperties(isolate_));
DCHECK_EQ(kField, property_details_.location());
DCHECK(!IsElement());
- return FieldIndex::ForDescriptor(holder_->map(), descriptor_number());
+ return FieldIndex::ForDescriptor(holder_->map(isolate_), descriptor_number());
}
Handle<FieldType> LookupIterator::GetFieldType() const {
DCHECK(has_property_);
- DCHECK(holder_->HasFastProperties());
+ DCHECK(holder_->HasFastProperties(isolate_));
DCHECK_EQ(kField, property_details_.location());
return handle(
- holder_->map().instance_descriptors().GetFieldType(descriptor_number()),
+ holder_->map(isolate_).instance_descriptors(isolate_).GetFieldType(
+ isolate_, descriptor_number()),
isolate_);
}
Handle<PropertyCell> LookupIterator::GetPropertyCell() const {
DCHECK(!IsElement());
Handle<JSGlobalObject> holder = GetHolder<JSGlobalObject>();
- return handle(holder->global_dictionary().CellAt(dictionary_entry()),
- isolate_);
+ return handle(
+ holder->global_dictionary(isolate_).CellAt(isolate_, dictionary_entry()),
+ isolate_);
}
Handle<Object> LookupIterator::GetAccessors() const {
@@ -1003,9 +993,9 @@ void LookupIterator::WriteDataValue(Handle<Object> value,
Handle<JSReceiver> holder = GetHolder<JSReceiver>();
if (IsElement()) {
Handle<JSObject> object = Handle<JSObject>::cast(holder);
- ElementsAccessor* accessor = object->GetElementsAccessor();
+ ElementsAccessor* accessor = object->GetElementsAccessor(isolate_);
accessor->Set(object, number_, *value);
- } else if (holder->HasFastProperties()) {
+ } else if (holder->HasFastProperties(isolate_)) {
if (property_details_.location() == kField) {
// Check that in case of VariableMode::kConst field the existing value is
// equal to |value|.
@@ -1018,21 +1008,22 @@ void LookupIterator::WriteDataValue(Handle<Object> value,
DCHECK_EQ(kDescriptor, property_details_.location());
DCHECK_EQ(PropertyConstness::kConst, property_details_.constness());
}
- } else if (holder->IsJSGlobalObject()) {
+ } else if (holder->IsJSGlobalObject(isolate_)) {
GlobalDictionary dictionary =
- JSGlobalObject::cast(*holder).global_dictionary();
- dictionary.CellAt(dictionary_entry()).set_value(*value);
+ JSGlobalObject::cast(*holder).global_dictionary(isolate_);
+ dictionary.CellAt(isolate_, dictionary_entry()).set_value(*value);
} else {
- DCHECK_IMPLIES(holder->IsJSProxy(), name()->IsPrivate());
- NameDictionary dictionary = holder->property_dictionary();
+ DCHECK_IMPLIES(holder->IsJSProxy(isolate_), name()->IsPrivate(isolate_));
+ NameDictionary dictionary = holder->property_dictionary(isolate_);
dictionary.ValueAtPut(dictionary_entry(), *value);
}
}
template <bool is_element>
bool LookupIterator::SkipInterceptor(JSObject holder) {
- auto info = GetInterceptor<is_element>(holder);
- if (!is_element && name_->IsSymbol() && !info.can_intercept_symbols()) {
+ InterceptorInfo info = GetInterceptor<is_element>(isolate_, holder);
+ if (!is_element && name_->IsSymbol(isolate_) &&
+ !info.can_intercept_symbols()) {
return true;
}
if (info.non_masking()) {
@@ -1051,18 +1042,19 @@ bool LookupIterator::SkipInterceptor(JSObject holder) {
JSReceiver LookupIterator::NextHolder(Map map) {
DisallowHeapAllocation no_gc;
- if (map.prototype() == ReadOnlyRoots(heap()).null_value()) {
+ if (map.prototype(isolate_) == ReadOnlyRoots(isolate_).null_value()) {
return JSReceiver();
}
- if (!check_prototype_chain() && !map.has_hidden_prototype()) {
+ if (!check_prototype_chain() && !map.IsJSGlobalProxyMap()) {
return JSReceiver();
}
- return JSReceiver::cast(map.prototype());
+ return JSReceiver::cast(map.prototype(isolate_));
}
LookupIterator::State LookupIterator::NotFound(JSReceiver const holder) const {
DCHECK(!IsElement());
- if (!holder.IsJSTypedArray() || !name_->IsString()) return NOT_FOUND;
+ if (!holder.IsJSTypedArray(isolate_) || !name_->IsString(isolate_))
+ return NOT_FOUND;
return IsSpecialIndex(String::cast(*name_)) ? INTEGER_INDEXED_EXOTIC
: NOT_FOUND;
}
@@ -1084,27 +1076,27 @@ LookupIterator::State LookupIterator::LookupInSpecialHolder(
switch (state_) {
case NOT_FOUND:
if (map.IsJSProxyMap()) {
- if (is_element || !name_->IsPrivate()) return JSPROXY;
+ if (is_element || !name_->IsPrivate(isolate_)) return JSPROXY;
}
if (map.is_access_check_needed()) {
- if (is_element || !name_->IsPrivate()) return ACCESS_CHECK;
+ if (is_element || !name_->IsPrivate(isolate_)) return ACCESS_CHECK;
}
V8_FALLTHROUGH;
case ACCESS_CHECK:
if (check_interceptor() && HasInterceptor<is_element>(map) &&
!SkipInterceptor<is_element>(JSObject::cast(holder))) {
- if (is_element || !name_->IsPrivate()) return INTERCEPTOR;
+ if (is_element || !name_->IsPrivate(isolate_)) return INTERCEPTOR;
}
V8_FALLTHROUGH;
case INTERCEPTOR:
if (!is_element && map.IsJSGlobalObjectMap()) {
GlobalDictionary dict =
- JSGlobalObject::cast(holder).global_dictionary();
+ JSGlobalObject::cast(holder).global_dictionary(isolate_);
int number = dict.FindEntry(isolate(), name_);
if (number == GlobalDictionary::kNotFound) return NOT_FOUND;
number_ = static_cast<uint32_t>(number);
- PropertyCell cell = dict.CellAt(number_);
- if (cell.value().IsTheHole(isolate_)) return NOT_FOUND;
+ PropertyCell cell = dict.CellAt(isolate_, number_);
+ if (cell.value(isolate_).IsTheHole(isolate_)) return NOT_FOUND;
property_details_ = cell.property_details();
has_property_ = true;
switch (property_details_.kind()) {
@@ -1136,12 +1128,13 @@ LookupIterator::State LookupIterator::LookupInRegularHolder(
if (is_element) {
JSObject js_object = JSObject::cast(holder);
- ElementsAccessor* accessor = js_object.GetElementsAccessor();
- FixedArrayBase backing_store = js_object.elements();
+ ElementsAccessor* accessor = js_object.GetElementsAccessor(isolate_);
+ FixedArrayBase backing_store = js_object.elements(isolate_);
number_ =
accessor->GetEntryForIndex(isolate_, js_object, backing_store, index_);
if (number_ == kMaxUInt32) {
- return holder.IsJSTypedArray() ? INTEGER_INDEXED_EXOTIC : NOT_FOUND;
+ return holder.IsJSTypedArray(isolate_) ? INTEGER_INDEXED_EXOTIC
+ : NOT_FOUND;
}
property_details_ = accessor->GetDetails(js_object, number_);
if (map.has_frozen_or_sealed_elements()) {
@@ -1149,14 +1142,14 @@ LookupIterator::State LookupIterator::LookupInRegularHolder(
property_details_ = property_details_.CopyAddAttributes(attrs);
}
} else if (!map.is_dictionary_map()) {
- DescriptorArray descriptors = map.instance_descriptors();
+ DescriptorArray descriptors = map.instance_descriptors(isolate_);
int number = descriptors.SearchWithCache(isolate_, *name_, map);
if (number == DescriptorArray::kNotFound) return NotFound(holder);
number_ = static_cast<uint32_t>(number);
property_details_ = descriptors.GetDetails(number_);
} else {
- DCHECK_IMPLIES(holder.IsJSProxy(), name()->IsPrivate());
- NameDictionary dict = holder.property_dictionary();
+ DCHECK_IMPLIES(holder.IsJSProxy(isolate_), name()->IsPrivate(isolate_));
+ NameDictionary dict = holder.property_dictionary(isolate_);
int number = dict.FindEntry(isolate(), name_);
if (number == NameDictionary::kNotFound) return NotFound(holder);
number_ = static_cast<uint32_t>(number);
@@ -1191,15 +1184,15 @@ Handle<InterceptorInfo> LookupIterator::GetInterceptorForFailedAccessCheck()
bool LookupIterator::TryLookupCachedProperty() {
return state() == LookupIterator::ACCESSOR &&
- GetAccessors()->IsAccessorPair() && LookupCachedProperty();
+ GetAccessors()->IsAccessorPair(isolate_) && LookupCachedProperty();
}
bool LookupIterator::LookupCachedProperty() {
DCHECK_EQ(state(), LookupIterator::ACCESSOR);
- DCHECK(GetAccessors()->IsAccessorPair());
+ DCHECK(GetAccessors()->IsAccessorPair(isolate_));
AccessorPair accessor_pair = AccessorPair::cast(*GetAccessors());
- Handle<Object> getter(accessor_pair.getter(), isolate());
+ Handle<Object> getter(accessor_pair.getter(isolate_), isolate());
MaybeHandle<Name> maybe_name =
FunctionTemplateInfo::TryGetCachedPropertyName(isolate(), getter);
if (maybe_name.is_null()) return false;
diff --git a/deps/v8/src/objects/lookup.h b/deps/v8/src/objects/lookup.h
index 820b8ef9b0..565ea4bb75 100644
--- a/deps/v8/src/objects/lookup.h
+++ b/deps/v8/src/objects/lookup.h
@@ -93,10 +93,6 @@ class V8_EXPORT_PRIVATE LookupIterator final {
Isolate* isolate, Handle<Object> receiver, Handle<Object> key,
bool* success, Configuration configuration = DEFAULT);
- static LookupIterator ForTransitionHandler(
- Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
- Handle<Object> value, MaybeHandle<Map> maybe_transition_map);
-
void Restart() {
InterceptorState state = InterceptorState::kUninitialized;
IsElement() ? RestartInternal<true>(state) : RestartInternal<false>(state);
@@ -239,7 +235,8 @@ class V8_EXPORT_PRIVATE LookupIterator final {
template <bool is_element>
bool SkipInterceptor(JSObject holder);
template <bool is_element>
- static inline InterceptorInfo GetInterceptor(JSObject holder);
+ static inline InterceptorInfo GetInterceptor(Isolate* isolate,
+ JSObject holder);
bool check_interceptor() const {
return (configuration_ & kInterceptor) != 0;
@@ -247,7 +244,8 @@ class V8_EXPORT_PRIVATE LookupIterator final {
inline int descriptor_number() const;
inline int dictionary_entry() const;
- static inline Configuration ComputeConfiguration(Configuration configuration,
+ static inline Configuration ComputeConfiguration(Isolate* isolate,
+ Configuration configuration,
Handle<Name> name);
static Handle<JSReceiver> GetRootForNonJSReceiver(
diff --git a/deps/v8/src/objects/map-inl.h b/deps/v8/src/objects/map-inl.h
index 8c26196fb5..6a9359e3a0 100644
--- a/deps/v8/src/objects/map-inl.h
+++ b/deps/v8/src/objects/map-inl.h
@@ -30,20 +30,13 @@ namespace internal {
OBJECT_CONSTRUCTORS_IMPL(Map, HeapObject)
CAST_ACCESSOR(Map)
-DescriptorArray Map::instance_descriptors() const {
- return DescriptorArray::cast(READ_FIELD(*this, kInstanceDescriptorsOffset));
+DEF_GETTER(Map, instance_descriptors, DescriptorArray) {
+ return TaggedField<DescriptorArray, kInstanceDescriptorsOffset>::load(isolate,
+ *this);
}
-DescriptorArray Map::synchronized_instance_descriptors() const {
- return DescriptorArray::cast(
- ACQUIRE_READ_FIELD(*this, kInstanceDescriptorsOffset));
-}
-
-void Map::set_synchronized_instance_descriptors(DescriptorArray value,
- WriteBarrierMode mode) {
- RELEASE_WRITE_FIELD(*this, kInstanceDescriptorsOffset, value);
- CONDITIONAL_WRITE_BARRIER(*this, kInstanceDescriptorsOffset, value, mode);
-}
+SYNCHRONIZED_ACCESSORS(Map, synchronized_instance_descriptors, DescriptorArray,
+ kInstanceDescriptorsOffset)
// A freshly allocated layout descriptor can be set on an existing map.
// We need to use release-store and acquire-load accessor pairs to ensure
@@ -54,6 +47,12 @@ SYNCHRONIZED_ACCESSORS_CHECKED(Map, layout_descriptor, LayoutDescriptor,
FLAG_unbox_double_fields)
WEAK_ACCESSORS(Map, raw_transitions, kTransitionsOrPrototypeInfoOffset)
+ACCESSORS_CHECKED2(Map, prototype, HeapObject, kPrototypeOffset, true,
+ value.IsNull() || value.IsJSReceiver())
+
+ACCESSORS_CHECKED(Map, prototype_info, Object,
+ kTransitionsOrPrototypeInfoOffset, this->is_prototype_map())
+
// |bit_field| fields.
// Concurrent access to |has_prototype_slot| and |has_non_instance_prototype|
// is explicitly whitelisted here. The former is never modified after the map
@@ -74,37 +73,35 @@ BIT_FIELD_ACCESSORS(Map, relaxed_bit_field, has_prototype_slot,
Map::HasPrototypeSlotBit)
// |bit_field2| fields.
-BIT_FIELD_ACCESSORS(Map, bit_field2, is_extensible, Map::IsExtensibleBit)
-BIT_FIELD_ACCESSORS(Map, bit_field2, is_prototype_map, Map::IsPrototypeMapBit)
-BIT_FIELD_ACCESSORS(Map, bit_field2, has_hidden_prototype,
- Map::HasHiddenPrototypeBit)
+BIT_FIELD_ACCESSORS(Map, bit_field2, new_target_is_base,
+ Map::NewTargetIsBaseBit)
+BIT_FIELD_ACCESSORS(Map, bit_field2, is_immutable_proto,
+ Map::IsImmutablePrototypeBit)
// |bit_field3| fields.
BIT_FIELD_ACCESSORS(Map, bit_field3, owns_descriptors, Map::OwnsDescriptorsBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, is_deprecated, Map::IsDeprecatedBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, is_in_retained_map_list,
Map::IsInRetainedMapListBit)
+BIT_FIELD_ACCESSORS(Map, bit_field3, is_prototype_map, Map::IsPrototypeMapBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, is_migration_target,
Map::IsMigrationTargetBit)
-BIT_FIELD_ACCESSORS(Map, bit_field3, is_immutable_proto,
- Map::IsImmutablePrototypeBit)
-BIT_FIELD_ACCESSORS(Map, bit_field3, new_target_is_base,
- Map::NewTargetIsBaseBit)
+BIT_FIELD_ACCESSORS(Map, bit_field3, is_extensible, Map::IsExtensibleBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, may_have_interesting_symbols,
Map::MayHaveInterestingSymbolsBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, construction_counter,
Map::ConstructionCounterBits)
-InterceptorInfo Map::GetNamedInterceptor() {
+DEF_GETTER(Map, GetNamedInterceptor, InterceptorInfo) {
DCHECK(has_named_interceptor());
- FunctionTemplateInfo info = GetFunctionTemplateInfo();
- return InterceptorInfo::cast(info.GetNamedPropertyHandler());
+ FunctionTemplateInfo info = GetFunctionTemplateInfo(isolate);
+ return InterceptorInfo::cast(info.GetNamedPropertyHandler(isolate));
}
-InterceptorInfo Map::GetIndexedInterceptor() {
+DEF_GETTER(Map, GetIndexedInterceptor, InterceptorInfo) {
DCHECK(has_indexed_interceptor());
- FunctionTemplateInfo info = GetFunctionTemplateInfo();
- return InterceptorInfo::cast(info.GetIndexedPropertyHandler());
+ FunctionTemplateInfo info = GetFunctionTemplateInfo(isolate);
+ return InterceptorInfo::cast(info.GetIndexedPropertyHandler(isolate));
}
bool Map::IsMostGeneralFieldType(Representation representation,
@@ -113,7 +110,8 @@ bool Map::IsMostGeneralFieldType(Representation representation,
}
bool Map::CanHaveFastTransitionableElementsKind(InstanceType instance_type) {
- return instance_type == JS_ARRAY_TYPE || instance_type == JS_VALUE_TYPE ||
+ return instance_type == JS_ARRAY_TYPE ||
+ instance_type == JS_PRIMITIVE_WRAPPER_TYPE ||
instance_type == JS_ARGUMENTS_TYPE;
}
@@ -136,10 +134,25 @@ void Map::GeneralizeIfCanHaveTransitionableFastElementsKind(
}
}
+Handle<Map> Map::Normalize(Isolate* isolate, Handle<Map> fast_map,
+ PropertyNormalizationMode mode, const char* reason) {
+ return Normalize(isolate, fast_map, fast_map->elements_kind(), mode, reason);
+}
+
+bool Map::EquivalentToForNormalization(const Map other,
+ PropertyNormalizationMode mode) const {
+ return EquivalentToForNormalization(other, elements_kind(), mode);
+}
+
bool Map::IsUnboxedDoubleField(FieldIndex index) const {
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return IsUnboxedDoubleField(isolate, index);
+}
+
+bool Map::IsUnboxedDoubleField(Isolate* isolate, FieldIndex index) const {
if (!FLAG_unbox_double_fields) return false;
if (!index.is_inobject()) return false;
- return !layout_descriptor().IsTagged(index.property_index());
+ return !layout_descriptor(isolate).IsTagged(index.property_index());
}
bool Map::TooManyFastProperties(StoreOrigin store_origin) const {
@@ -160,8 +173,8 @@ bool Map::TooManyFastProperties(StoreOrigin store_origin) const {
}
}
-PropertyDetails Map::GetLastDescriptorDetails() const {
- return instance_descriptors().GetDetails(LastAdded());
+PropertyDetails Map::GetLastDescriptorDetails(Isolate* isolate) const {
+ return instance_descriptors(isolate).GetDetails(LastAdded());
}
int Map::LastAdded() const {
@@ -375,7 +388,7 @@ void Map::CopyUnusedPropertyFields(Map map) {
void Map::CopyUnusedPropertyFieldsAdjustedForInstanceSize(Map map) {
int value = map.used_or_unused_instance_size_in_words();
- if (value >= JSValue::kFieldsAdded) {
+ if (value >= JSPrimitiveWrapper::kFieldsAdded) {
// Unused in-object fields. Adjust the offset from the object’s start
// so it matches the distance to the object’s end.
value += instance_size_in_words() - map.instance_size_in_words();
@@ -570,22 +583,13 @@ bool Map::IsPrimitiveMap() const {
return instance_type() <= LAST_PRIMITIVE_TYPE;
}
-HeapObject Map::prototype() const {
- return HeapObject::cast(READ_FIELD(*this, kPrototypeOffset));
-}
-
-void Map::set_prototype(HeapObject value, WriteBarrierMode mode) {
- DCHECK(value.IsNull() || value.IsJSReceiver());
- WRITE_FIELD(*this, kPrototypeOffset, value);
- CONDITIONAL_WRITE_BARRIER(*this, kPrototypeOffset, value, mode);
-}
-
LayoutDescriptor Map::layout_descriptor_gc_safe() const {
DCHECK(FLAG_unbox_double_fields);
// The loaded value can be dereferenced on background thread to load the
// bitmap. We need acquire load in order to ensure that the bitmap
// initializing stores are also visible to the background thread.
- Object layout_desc = ACQUIRE_READ_FIELD(*this, kLayoutDescriptorOffset);
+ Object layout_desc =
+ TaggedField<Object, kLayoutDescriptorOffset>::Acquire_Load(*this);
return LayoutDescriptor::cast_gc_safe(layout_desc);
}
@@ -593,7 +597,8 @@ bool Map::HasFastPointerLayout() const {
DCHECK(FLAG_unbox_double_fields);
// The loaded value is used for SMI check only and is not dereferenced,
// so relaxed load is safe.
- Object layout_desc = RELAXED_READ_FIELD(*this, kLayoutDescriptorOffset);
+ Object layout_desc =
+ TaggedField<Object, kLayoutDescriptorOffset>::Relaxed_Load(*this);
return LayoutDescriptor::IsFastPointerLayout(layout_desc);
}
@@ -686,36 +691,17 @@ void Map::AppendDescriptor(Isolate* isolate, Descriptor* desc) {
#endif
}
-HeapObject Map::GetBackPointer() const {
- Object object = constructor_or_backpointer();
- if (object.IsMap()) {
+DEF_GETTER(Map, GetBackPointer, HeapObject) {
+ Object object = constructor_or_backpointer(isolate);
+ if (object.IsMap(isolate)) {
return Map::cast(object);
}
- return GetReadOnlyRoots().undefined_value();
+ // Can't use ReadOnlyRoots(isolate) as this isolate could be produced by
+ // i::GetIsolateForPtrCompr(HeapObject).
+ return GetReadOnlyRoots(isolate).undefined_value();
}
-Map Map::ElementsTransitionMap() {
- DisallowHeapAllocation no_gc;
- // TODO(delphick): While it's safe to pass nullptr for Isolate* here as
- // SearchSpecial doesn't need it, this is really ugly. Perhaps factor out a
- // base class for methods not requiring an Isolate?
- return TransitionsAccessor(nullptr, *this, &no_gc)
- .SearchSpecial(GetReadOnlyRoots().elements_transition_symbol());
-}
-
-Object Map::prototype_info() const {
- DCHECK(is_prototype_map());
- return READ_FIELD(*this, Map::kTransitionsOrPrototypeInfoOffset);
-}
-
-void Map::set_prototype_info(Object value, WriteBarrierMode mode) {
- CHECK(is_prototype_map());
- WRITE_FIELD(*this, Map::kTransitionsOrPrototypeInfoOffset, value);
- CONDITIONAL_WRITE_BARRIER(*this, Map::kTransitionsOrPrototypeInfoOffset,
- value, mode);
-}
-
-void Map::SetBackPointer(Object value, WriteBarrierMode mode) {
+void Map::SetBackPointer(HeapObject value, WriteBarrierMode mode) {
CHECK_GE(instance_type(), FIRST_JS_RECEIVER_TYPE);
CHECK(value.IsMap());
CHECK(GetBackPointer().IsUndefined());
@@ -724,6 +710,13 @@ void Map::SetBackPointer(Object value, WriteBarrierMode mode) {
set_constructor_or_backpointer(value, mode);
}
+// static
+Map Map::ElementsTransitionMap(Isolate* isolate) {
+ DisallowHeapAllocation no_gc;
+ return TransitionsAccessor(isolate, *this, &no_gc)
+ .SearchSpecial(ReadOnlyRoots(isolate).elements_transition_symbol());
+}
+
ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
ACCESSORS(Map, prototype_validity_cell, Object, kPrototypeValidityCellOffset)
ACCESSORS(Map, constructor_or_backpointer, Object,
@@ -736,23 +729,24 @@ bool Map::IsPrototypeValidityCellValid() const {
return value == Smi::FromInt(Map::kPrototypeChainValid);
}
-Object Map::GetConstructor() const {
- Object maybe_constructor = constructor_or_backpointer();
+DEF_GETTER(Map, GetConstructor, Object) {
+ Object maybe_constructor = constructor_or_backpointer(isolate);
// Follow any back pointers.
- while (maybe_constructor.IsMap()) {
+ while (maybe_constructor.IsMap(isolate)) {
maybe_constructor =
- Map::cast(maybe_constructor).constructor_or_backpointer();
+ Map::cast(maybe_constructor).constructor_or_backpointer(isolate);
}
return maybe_constructor;
}
-FunctionTemplateInfo Map::GetFunctionTemplateInfo() const {
- Object constructor = GetConstructor();
- if (constructor.IsJSFunction()) {
- DCHECK(JSFunction::cast(constructor).shared().IsApiFunction());
- return JSFunction::cast(constructor).shared().get_api_func_data();
+DEF_GETTER(Map, GetFunctionTemplateInfo, FunctionTemplateInfo) {
+ Object constructor = GetConstructor(isolate);
+ if (constructor.IsJSFunction(isolate)) {
+ // TODO(ishell): IsApiFunction(isolate) and get_api_func_data(isolate)
+ DCHECK(JSFunction::cast(constructor).shared(isolate).IsApiFunction());
+ return JSFunction::cast(constructor).shared(isolate).get_api_func_data();
}
- DCHECK(constructor.IsFunctionTemplateInfo());
+ DCHECK(constructor.IsFunctionTemplateInfo(isolate));
return FunctionTemplateInfo::cast(constructor);
}
@@ -805,8 +799,8 @@ int NormalizedMapCache::GetIndex(Handle<Map> map) {
return map->Hash() % NormalizedMapCache::kEntries;
}
-bool HeapObject::IsNormalizedMapCache() const {
- if (!IsWeakFixedArray()) return false;
+DEF_GETTER(HeapObject, IsNormalizedMapCache, bool) {
+ if (!IsWeakFixedArray(isolate)) return false;
if (WeakFixedArray::cast(*this).length() != NormalizedMapCache::kEntries) {
return false;
}
diff --git a/deps/v8/src/objects/map-updater.cc b/deps/v8/src/objects/map-updater.cc
index 855fdabdf3..d21f0e1a12 100644
--- a/deps/v8/src/objects/map-updater.cc
+++ b/deps/v8/src/objects/map-updater.cc
@@ -201,10 +201,9 @@ void MapUpdater::GeneralizeField(Handle<Map> map, int modify_index,
*old_descriptors_ == integrity_source_map_->instance_descriptors());
}
-MapUpdater::State MapUpdater::CopyGeneralizeAllFields(const char* reason) {
- result_map_ = Map::CopyGeneralizeAllFields(
- isolate_, old_map_, new_elements_kind_, modified_descriptor_, new_kind_,
- new_attributes_, reason);
+MapUpdater::State MapUpdater::Normalize(const char* reason) {
+ result_map_ = Map::Normalize(isolate_, old_map_, new_elements_kind_,
+ CLEAR_INOBJECT_PROPERTIES, reason);
state_ = kEnd;
return state_; // Done.
}
@@ -310,14 +309,14 @@ MapUpdater::State MapUpdater::FindRootMap() {
}
if (!old_map_->EquivalentToForTransition(*root_map_)) {
- return CopyGeneralizeAllFields("GenAll_NotEquivalent");
+ return Normalize("Normalize_NotEquivalent");
} else if (old_map_->is_extensible() != root_map_->is_extensible()) {
DCHECK(!old_map_->is_extensible());
DCHECK(root_map_->is_extensible());
// We have an integrity level transition in the tree, let us make a note
// of that transition to be able to replay it later.
if (!TrySaveIntegrityLevelTransitions()) {
- return CopyGeneralizeAllFields("GenAll_PrivateSymbolsOnNonExtensible");
+ return Normalize("Normalize_PrivateSymbolsOnNonExtensible");
}
// We want to build transitions to the original element kind (before
@@ -335,7 +334,7 @@ MapUpdater::State MapUpdater::FindRootMap() {
to_kind != SLOW_SLOPPY_ARGUMENTS_ELEMENTS &&
!(IsTransitionableFastElementsKind(from_kind) &&
IsMoreGeneralElementsKindTransition(from_kind, to_kind))) {
- return CopyGeneralizeAllFields("GenAll_InvalidElementsTransition");
+ return Normalize("Normalize_InvalidElementsTransition");
}
int root_nof = root_map_->NumberOfOwnDescriptors();
@@ -344,13 +343,13 @@ MapUpdater::State MapUpdater::FindRootMap() {
old_descriptors_->GetDetails(modified_descriptor_);
if (old_details.kind() != new_kind_ ||
old_details.attributes() != new_attributes_) {
- return CopyGeneralizeAllFields("GenAll_RootModification1");
+ return Normalize("Normalize_RootModification1");
}
if (old_details.location() != kField) {
- return CopyGeneralizeAllFields("GenAll_RootModification2");
+ return Normalize("Normalize_RootModification2");
}
if (!new_representation_.fits_into(old_details.representation())) {
- return CopyGeneralizeAllFields("GenAll_RootModification4");
+ return Normalize("Normalize_RootModification4");
}
DCHECK_EQ(kData, old_details.kind());
@@ -394,7 +393,7 @@ MapUpdater::State MapUpdater::FindTargetMap() {
!EqualImmutableValues(GetValue(i),
tmp_descriptors->GetStrongValue(i))) {
// TODO(ishell): mutable accessors are not implemented yet.
- return CopyGeneralizeAllFields("GenAll_Incompatible");
+ return Normalize("Normalize_Incompatible");
}
if (!IsGeneralizableTo(old_details.location(), tmp_details.location())) {
break;
@@ -484,7 +483,7 @@ MapUpdater::State MapUpdater::FindTargetMap() {
if (old_details.kind() == kAccessor &&
!EqualImmutableValues(GetValue(i),
tmp_descriptors->GetStrongValue(i))) {
- return CopyGeneralizeAllFields("GenAll_Incompatible");
+ return Normalize("Normalize_Incompatible");
}
DCHECK(!tmp_map->is_deprecated());
target_map_ = tmp_map;
@@ -723,7 +722,7 @@ MapUpdater::State MapUpdater::ConstructNewMap() {
// contains entry for given descriptor. This means that the transition
// could be inserted regardless of whether transitions array is full or not.
if (maybe_transition.is_null() && !transitions.CanHaveMoreTransitions()) {
- return CopyGeneralizeAllFields("GenAll_CantHaveMoreTransitions");
+ return Normalize("Normalize_CantHaveMoreTransitions");
}
old_map_->NotifyLeafMapLayoutChange(isolate_);
@@ -787,7 +786,7 @@ MapUpdater::State MapUpdater::ConstructNewMapWithIntegrityLevelTransition() {
TransitionsAccessor transitions(isolate_, target_map_);
if (!transitions.CanHaveMoreTransitions()) {
- return CopyGeneralizeAllFields("GenAll_CantHaveMoreTransitions");
+ return Normalize("Normalize_CantHaveMoreTransitions");
}
result_map_ = Map::CopyForPreventExtensions(
diff --git a/deps/v8/src/objects/map-updater.h b/deps/v8/src/objects/map-updater.h
index 3ba86eacbc..6ee373cbdf 100644
--- a/deps/v8/src/objects/map-updater.h
+++ b/deps/v8/src/objects/map-updater.h
@@ -123,9 +123,8 @@ class MapUpdater {
State ConstructNewMapWithIntegrityLevelTransition();
// When a requested reconfiguration can not be done the result is a copy
- // of |old_map_| where every field has |Tagged| representation and |Any|
- // field type. This map is disconnected from the transition tree.
- State CopyGeneralizeAllFields(const char* reason);
+ // of |old_map_| in dictionary mode.
+ State Normalize(const char* reason);
// Returns name of a |descriptor| property.
inline Name GetKey(int descriptor) const;
diff --git a/deps/v8/src/objects/map.cc b/deps/v8/src/objects/map.cc
index 43d8c305c5..7b4f1abd05 100644
--- a/deps/v8/src/objects/map.cc
+++ b/deps/v8/src/objects/map.cc
@@ -85,6 +85,21 @@ void Map::PrintReconfiguration(Isolate* isolate, FILE* file, int modify_index,
os << "]\n";
}
+Map Map::GetStructMap(Isolate* isolate, InstanceType type) {
+ Map map;
+ switch (type) {
+#define MAKE_CASE(TYPE, Name, name) \
+ case TYPE: \
+ map = ReadOnlyRoots(isolate).name##_map(); \
+ break;
+ STRUCT_LIST(MAKE_CASE)
+#undef MAKE_CASE
+ default:
+ UNREACHABLE();
+ }
+ return map;
+}
+
VisitorId Map::GetVisitorId(Map map) {
STATIC_ASSERT(kVisitorIdCount <= 256);
@@ -262,7 +277,7 @@ VisitorId Map::GetVisitorId(Map map) {
case JS_ASYNC_FUNCTION_OBJECT_TYPE:
case JS_ASYNC_GENERATOR_OBJECT_TYPE:
case JS_MODULE_NAMESPACE_TYPE:
- case JS_VALUE_TYPE:
+ case JS_PRIMITIVE_WRAPPER_TYPE:
case JS_DATE_TYPE:
case JS_ARRAY_ITERATOR_TYPE:
case JS_ARRAY_TYPE:
@@ -337,12 +352,20 @@ VisitorId Map::GetVisitorId(Map map) {
if (instance_type == WASM_CAPI_FUNCTION_DATA_TYPE) {
return kVisitWasmCapiFunctionData;
}
+ if (instance_type == WASM_INDIRECT_FUNCTION_TABLE_TYPE) {
+ return kVisitWasmIndirectFunctionTable;
+ }
return kVisitStruct;
case LOAD_HANDLER_TYPE:
case STORE_HANDLER_TYPE:
return kVisitDataHandler;
+ case SOURCE_TEXT_MODULE_TYPE:
+ return kVisitSourceTextModule;
+ case SYNTHETIC_MODULE_TYPE:
+ return kVisitSyntheticModule;
+
default:
UNREACHABLE();
}
@@ -458,7 +481,7 @@ MaybeHandle<Map> Map::CopyWithConstant(Isolate* isolate, Handle<Map> map,
return MaybeHandle<Map>();
}
- Representation representation = constant->OptimalRepresentation();
+ Representation representation = constant->OptimalRepresentation(isolate);
Handle<FieldType> type = constant->OptimalType(isolate, representation);
return CopyWithField(isolate, map, name, type, attributes,
PropertyConstness::kConst, representation, flag);
@@ -570,61 +593,6 @@ bool Map::HasOutOfObjectProperties() const {
return GetInObjectProperties() < NumberOfFields();
}
-Handle<Map> Map::CopyGeneralizeAllFields(Isolate* isolate, Handle<Map> map,
- ElementsKind elements_kind,
- int modify_index, PropertyKind kind,
- PropertyAttributes attributes,
- const char* reason) {
- Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
- int number_of_own_descriptors = map->NumberOfOwnDescriptors();
- Handle<DescriptorArray> descriptors = DescriptorArray::CopyUpTo(
- isolate, old_descriptors, number_of_own_descriptors);
- descriptors->GeneralizeAllFields();
-
- Handle<LayoutDescriptor> new_layout_descriptor(
- LayoutDescriptor::FastPointerLayout(), isolate);
- Handle<Map> new_map = CopyReplaceDescriptors(
- isolate, map, descriptors, new_layout_descriptor, OMIT_TRANSITION,
- MaybeHandle<Name>(), reason, SPECIAL_TRANSITION);
-
- // Unless the instance is being migrated, ensure that modify_index is a field.
- if (modify_index >= 0) {
- PropertyDetails details = descriptors->GetDetails(modify_index);
- if (details.constness() != PropertyConstness::kMutable ||
- details.location() != kField || details.attributes() != attributes) {
- int field_index = details.location() == kField
- ? details.field_index()
- : new_map->NumberOfFields();
- Descriptor d = Descriptor::DataField(
- isolate, handle(descriptors->GetKey(modify_index), isolate),
- field_index, attributes, Representation::Tagged());
- descriptors->Replace(modify_index, &d);
- if (details.location() != kField) {
- new_map->AccountAddedPropertyField();
- }
- } else {
- DCHECK(details.attributes() == attributes);
- }
-
- if (FLAG_trace_generalization) {
- MaybeHandle<FieldType> field_type = FieldType::None(isolate);
- if (details.location() == kField) {
- field_type = handle(
- map->instance_descriptors().GetFieldType(modify_index), isolate);
- }
- map->PrintGeneralization(
- isolate, stdout, reason, modify_index,
- new_map->NumberOfOwnDescriptors(), new_map->NumberOfOwnDescriptors(),
- details.location() == kDescriptor, details.representation(),
- Representation::Tagged(), details.constness(), details.constness(),
- field_type, MaybeHandle<Object>(), FieldType::Any(isolate),
- MaybeHandle<Object>());
- }
- }
- new_map->set_elements_kind(elements_kind);
- return new_map;
-}
-
void Map::DeprecateTransitionTree(Isolate* isolate) {
if (is_deprecated()) return;
DisallowHeapAllocation no_gc;
@@ -648,7 +616,8 @@ void Map::DeprecateTransitionTree(Isolate* isolate) {
void Map::ReplaceDescriptors(Isolate* isolate, DescriptorArray new_descriptors,
LayoutDescriptor new_layout_descriptor) {
// Don't overwrite the empty descriptor array or initial map's descriptors.
- if (NumberOfOwnDescriptors() == 0 || GetBackPointer().IsUndefined(isolate)) {
+ if (NumberOfOwnDescriptors() == 0 ||
+ GetBackPointer(isolate).IsUndefined(isolate)) {
return;
}
@@ -659,8 +628,8 @@ void Map::ReplaceDescriptors(Isolate* isolate, DescriptorArray new_descriptors,
Map current = *this;
MarkingBarrierForDescriptorArray(isolate->heap(), current, to_replace,
to_replace.number_of_descriptors());
- while (current.instance_descriptors() == to_replace) {
- Object next = current.GetBackPointer();
+ while (current.instance_descriptors(isolate) == to_replace) {
+ Object next = current.GetBackPointer(isolate);
if (next.IsUndefined(isolate)) break; // Stop overwriting at initial map.
current.SetEnumLength(kInvalidEnumCacheSentinel);
current.UpdateDescriptors(isolate, new_descriptors, new_layout_descriptor,
@@ -673,7 +642,7 @@ void Map::ReplaceDescriptors(Isolate* isolate, DescriptorArray new_descriptors,
Map Map::FindRootMap(Isolate* isolate) const {
Map result = *this;
while (true) {
- Object back = result.GetBackPointer();
+ Object back = result.GetBackPointer(isolate);
if (back.IsUndefined(isolate)) {
// Initial map always owns descriptors and doesn't have unused entries
// in the descriptor array.
@@ -688,10 +657,11 @@ Map Map::FindRootMap(Isolate* isolate) const {
Map Map::FindFieldOwner(Isolate* isolate, int descriptor) const {
DisallowHeapAllocation no_allocation;
- DCHECK_EQ(kField, instance_descriptors().GetDetails(descriptor).location());
+ DCHECK_EQ(kField,
+ instance_descriptors(isolate).GetDetails(descriptor).location());
Map result = *this;
while (true) {
- Object back = result.GetBackPointer();
+ Object back = result.GetBackPointer(isolate);
if (back.IsUndefined(isolate)) break;
const Map parent = Map::cast(back);
if (parent.NumberOfOwnDescriptors() <= descriptor) break;
@@ -927,7 +897,7 @@ IntegrityLevelTransitionInfo DetectIntegrityLevelTransitions(
// Figure out the most restrictive integrity level transition (it should
// be the last one in the transition tree).
DCHECK(!map.is_extensible());
- Map previous = Map::cast(map.GetBackPointer());
+ Map previous = Map::cast(map.GetBackPointer(isolate));
TransitionsAccessor last_transitions(isolate, previous, no_allocation);
if (!last_transitions.HasIntegrityLevelTransitionTo(
map, &(info.integrity_level_symbol), &(info.integrity_level))) {
@@ -945,7 +915,7 @@ IntegrityLevelTransitionInfo DetectIntegrityLevelTransitions(
// transitions. If we encounter any non-integrity level transition interleaved
// with integrity level transitions, just bail out.
while (!source_map.is_extensible()) {
- previous = Map::cast(source_map.GetBackPointer());
+ previous = Map::cast(source_map.GetBackPointer(isolate));
TransitionsAccessor transitions(isolate, previous, no_allocation);
if (!transitions.HasIntegrityLevelTransitionTo(source_map)) {
return info;
@@ -1234,9 +1204,9 @@ Map Map::FindElementsKindTransitionedMap(Isolate* isolate,
// Starting from the next existing elements kind transition try to
// replay the property transitions that does not involve instance rewriting
// (ElementsTransitionAndStoreStub does not support that).
- for (root_map = root_map.ElementsTransitionMap();
+ for (root_map = root_map.ElementsTransitionMap(isolate);
!root_map.is_null() && root_map.has_fast_elements();
- root_map = root_map.ElementsTransitionMap()) {
+ root_map = root_map.ElementsTransitionMap(isolate)) {
// If root_map's elements kind doesn't match any of the elements kind in
// the candidates there is no need to do any additional work.
if (!HasElementsKind(candidates, root_map.elements_kind())) continue;
@@ -1263,7 +1233,7 @@ static Map FindClosestElementsTransition(Isolate* isolate, Map map,
ElementsKind kind = map.elements_kind();
while (kind != to_kind) {
- Map next_map = current_map.ElementsTransitionMap();
+ Map next_map = current_map.ElementsTransitionMap(isolate);
if (next_map.is_null()) return current_map;
kind = next_map.elements_kind();
current_map = next_map;
@@ -1401,25 +1371,23 @@ int Map::NumberOfEnumerableProperties() const {
}
int Map::NextFreePropertyIndex() const {
- int free_index = 0;
int number_of_own_descriptors = NumberOfOwnDescriptors();
DescriptorArray descs = instance_descriptors();
- for (int i = 0; i < number_of_own_descriptors; i++) {
+ // Search properties backwards to find the last field.
+ for (int i = number_of_own_descriptors - 1; i >= 0; --i) {
PropertyDetails details = descs.GetDetails(i);
if (details.location() == kField) {
- int candidate = details.field_index() + details.field_width_in_words();
- if (candidate > free_index) free_index = candidate;
+ return details.field_index() + details.field_width_in_words();
}
}
- return free_index;
+ return 0;
}
bool Map::OnlyHasSimpleProperties() const {
// Wrapped string elements aren't explicitly stored in the elements backing
// store, but are loaded indirectly from the underlying string.
return !IsStringWrapperElementsKind(elements_kind()) &&
- !IsSpecialReceiverMap() && !has_hidden_prototype() &&
- !is_dictionary_map();
+ !IsSpecialReceiverMap() && !is_dictionary_map();
}
bool Map::DictionaryElementsInPrototypeChainOnly(Isolate* isolate) {
@@ -1478,6 +1446,7 @@ Handle<Map> Map::RawCopy(Isolate* isolate, Handle<Map> map, int instance_size,
}
Handle<Map> Map::Normalize(Isolate* isolate, Handle<Map> fast_map,
+ ElementsKind new_elements_kind,
PropertyNormalizationMode mode, const char* reason) {
DCHECK(!fast_map->is_dictionary_map());
@@ -1489,7 +1458,8 @@ Handle<Map> Map::Normalize(Isolate* isolate, Handle<Map> fast_map,
if (use_cache) cache = Handle<NormalizedMapCache>::cast(maybe_cache);
Handle<Map> new_map;
- if (use_cache && cache->Get(fast_map, mode).ToHandle(&new_map)) {
+ if (use_cache &&
+ cache->Get(fast_map, new_elements_kind, mode).ToHandle(&new_map)) {
#ifdef VERIFY_HEAP
if (FLAG_verify_heap) new_map->DictionaryMapVerify(isolate);
#endif
@@ -1499,6 +1469,7 @@ Handle<Map> Map::Normalize(Isolate* isolate, Handle<Map> fast_map,
// except for the code cache, which can contain some ICs which can be
// applied to the shared map, dependent code and weak cell cache.
Handle<Map> fresh = Map::CopyNormalized(isolate, fast_map, mode);
+ fresh->set_elements_kind(new_elements_kind);
STATIC_ASSERT(Map::kPrototypeValidityCellOffset ==
Map::kDependentCodeOffset + kTaggedSize);
@@ -1508,8 +1479,12 @@ Handle<Map> Map::Normalize(Isolate* isolate, Handle<Map> fast_map,
// The IsInRetainedMapListBit might be different if the {new_map}
// that we got from the {cache} was already embedded into optimized
// code somewhere.
- DCHECK_EQ(fresh->bit_field3() & ~IsInRetainedMapListBit::kMask,
- new_map->bit_field3() & ~IsInRetainedMapListBit::kMask);
+ // The IsMigrationTargetBit might be different if the {new_map} from
+ // {cache} has already been marked as a migration target.
+ constexpr int ignored_bit_field3_bits =
+ IsInRetainedMapListBit::kMask | IsMigrationTargetBit::kMask;
+ DCHECK_EQ(fresh->bit_field3() & ~ignored_bit_field3_bits,
+ new_map->bit_field3() & ~ignored_bit_field3_bits);
int offset = Map::kBitField3Offset + kInt32Size;
DCHECK_EQ(0, memcmp(reinterpret_cast<void*>(fresh->address() + offset),
reinterpret_cast<void*>(new_map->address() + offset),
@@ -1530,13 +1505,14 @@ Handle<Map> Map::Normalize(Isolate* isolate, Handle<Map> fast_map,
#endif
} else {
new_map = Map::CopyNormalized(isolate, fast_map, mode);
+ new_map->set_elements_kind(new_elements_kind);
if (use_cache) {
cache->Set(fast_map, new_map);
isolate->counters()->maps_normalized()->Increment();
}
- if (FLAG_trace_maps) {
- LOG(isolate, MapEvent("Normalize", *fast_map, *new_map, reason));
- }
+ }
+ if (FLAG_trace_maps) {
+ LOG(isolate, MapEvent("Normalize", *fast_map, *new_map, reason));
}
fast_map->NotifyLeafMapLayoutChange(isolate);
return new_map;
@@ -1870,7 +1846,7 @@ Handle<Map> Map::CopyAsElementsKind(Isolate* isolate, Handle<Map> map,
DCHECK_EQ(map->FindRootMap(isolate).NumberOfOwnDescriptors(),
map->NumberOfOwnDescriptors());
- maybe_elements_transition_map = map->ElementsTransitionMap();
+ maybe_elements_transition_map = map->ElementsTransitionMap(isolate);
DCHECK(
maybe_elements_transition_map.is_null() ||
(maybe_elements_transition_map.elements_kind() == DICTIONARY_ELEMENTS &&
@@ -2093,7 +2069,7 @@ Handle<Map> UpdateDescriptorForValue(Isolate* isolate, Handle<Map> map,
PropertyAttributes attributes =
map->instance_descriptors().GetDetails(descriptor).attributes();
- Representation representation = value->OptimalRepresentation();
+ Representation representation = value->OptimalRepresentation(isolate);
Handle<FieldType> type = value->OptimalType(isolate, representation);
MapUpdater mu(isolate, map);
@@ -2108,11 +2084,11 @@ Handle<Map> Map::PrepareForDataProperty(Isolate* isolate, Handle<Map> map,
int descriptor,
PropertyConstness constness,
Handle<Object> value) {
+ // Update to the newest map before storing the property.
+ map = Update(isolate, map);
// Dictionaries can store any property value.
DCHECK(!map->is_dictionary_map());
- // Update to the newest map before storing the property.
- return UpdateDescriptorForValue(isolate, Update(isolate, map), descriptor,
- constness, value);
+ return UpdateDescriptorForValue(isolate, map, descriptor, constness, value);
}
Handle<Map> Map::TransitionToDataProperty(Isolate* isolate, Handle<Map> map,
@@ -2152,7 +2128,7 @@ Handle<Map> Map::TransitionToDataProperty(Isolate* isolate, Handle<Map> map,
isolate->bootstrapper()->IsActive() ? OMIT_TRANSITION : INSERT_TRANSITION;
MaybeHandle<Map> maybe_map;
if (!map->TooManyFastProperties(store_origin)) {
- Representation representation = value->OptimalRepresentation();
+ Representation representation = value->OptimalRepresentation(isolate);
Handle<FieldType> type = value->OptimalType(isolate, representation);
maybe_map = Map::CopyWithField(isolate, map, name, type, attributes,
constness, representation, flag);
@@ -2204,16 +2180,16 @@ Handle<Map> Map::TransitionToDataProperty(Isolate* isolate, Handle<Map> map,
Handle<Map> Map::ReconfigureExistingProperty(Isolate* isolate, Handle<Map> map,
int descriptor, PropertyKind kind,
- PropertyAttributes attributes) {
+ PropertyAttributes attributes,
+ PropertyConstness constness) {
// Dictionaries have to be reconfigured in-place.
DCHECK(!map->is_dictionary_map());
if (!map->GetBackPointer().IsMap()) {
// There is no benefit from reconstructing transition tree for maps without
- // back pointers.
- return CopyGeneralizeAllFields(isolate, map, map->elements_kind(),
- descriptor, kind, attributes,
- "GenAll_AttributesMismatchProtoMap");
+ // back pointers, normalize and try to hit the map cache instead.
+ return Map::Normalize(isolate, map, CLEAR_INOBJECT_PROPERTIES,
+ "Normalize_AttributesMismatchProtoMap");
}
if (FLAG_trace_generalization) {
@@ -2223,7 +2199,7 @@ Handle<Map> Map::ReconfigureExistingProperty(Isolate* isolate, Handle<Map> map,
MapUpdater mu(isolate, map);
DCHECK_EQ(kData, kind); // Only kData case is supported so far.
Handle<Map> new_map = mu.ReconfigureToDataField(
- descriptor, attributes, PropertyConstness::kConst, Representation::None(),
+ descriptor, attributes, constness, Representation::None(),
FieldType::None(isolate));
return new_map;
}
@@ -2243,12 +2219,12 @@ Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map,
DCHECK(!getter->IsNull(isolate) || !setter->IsNull(isolate));
DCHECK(name->IsUniqueName());
- // Dictionary maps can always have additional data properties.
- if (map->is_dictionary_map()) return map;
-
// Migrate to the newest map before transitioning to the new property.
map = Update(isolate, map);
+ // Dictionary maps can always have additional data properties.
+ if (map->is_dictionary_map()) return map;
+
PropertyNormalizationMode mode = map->is_prototype_map()
? KEEP_INOBJECT_PROPERTIES
: CLEAR_INOBJECT_PROPERTIES;
@@ -2433,8 +2409,7 @@ bool CheckEquivalent(const Map first, const Map second) {
first.instance_type() == second.instance_type() &&
first.bit_field() == second.bit_field() &&
first.is_extensible() == second.is_extensible() &&
- first.new_target_is_base() == second.new_target_is_base() &&
- first.has_hidden_prototype() == second.has_hidden_prototype();
+ first.new_target_is_base() == second.new_target_is_base();
}
} // namespace
@@ -2442,7 +2417,6 @@ bool CheckEquivalent(const Map first, const Map second) {
bool Map::EquivalentToForTransition(const Map other) const {
CHECK_EQ(GetConstructor(), other.GetConstructor());
CHECK_EQ(instance_type(), other.instance_type());
- CHECK_EQ(has_hidden_prototype(), other.has_hidden_prototype());
if (bit_field() != other.bit_field()) return false;
if (new_target_is_base() != other.new_target_is_base()) return false;
@@ -2477,10 +2451,16 @@ bool Map::EquivalentToForElementsKindTransition(const Map other) const {
}
bool Map::EquivalentToForNormalization(const Map other,
+ ElementsKind elements_kind,
PropertyNormalizationMode mode) const {
int properties =
mode == CLEAR_INOBJECT_PROPERTIES ? 0 : other.GetInObjectProperties();
- return CheckEquivalent(*this, other) && bit_field2() == other.bit_field2() &&
+ // Make sure the elements_kind bits are in bit_field2.
+ DCHECK_EQ(this->elements_kind(), Map::ElementsKindBits::decode(bit_field2()));
+ int adjusted_other_bit_field2 =
+ Map::ElementsKindBits::update(other.bit_field2(), elements_kind);
+ return CheckEquivalent(*this, other) &&
+ bit_field2() == adjusted_other_bit_field2 &&
GetInObjectProperties() == properties &&
JSObject::GetEmbedderFieldCount(*this) ==
JSObject::GetEmbedderFieldCount(other);
@@ -2639,7 +2619,6 @@ void Map::SetPrototype(Isolate* isolate, Handle<Map> map,
} else {
DCHECK(prototype->IsNull(isolate) || prototype->IsJSProxy());
}
- map->set_has_hidden_prototype(prototype->IsJSGlobalObject());
WriteBarrierMode wb_mode =
prototype->IsNull(isolate) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
@@ -2672,6 +2651,7 @@ Handle<NormalizedMapCache> NormalizedMapCache::New(Isolate* isolate) {
}
MaybeHandle<Map> NormalizedMapCache::Get(Handle<Map> fast_map,
+ ElementsKind elements_kind,
PropertyNormalizationMode mode) {
DisallowHeapAllocation no_gc;
MaybeObject value = WeakFixedArray::Get(GetIndex(fast_map));
@@ -2681,7 +2661,8 @@ MaybeHandle<Map> NormalizedMapCache::Get(Handle<Map> fast_map,
}
Map normalized_map = Map::cast(heap_object);
- if (!normalized_map.EquivalentToForNormalization(*fast_map, mode)) {
+ if (!normalized_map.EquivalentToForNormalization(*fast_map, elements_kind,
+ mode)) {
return MaybeHandle<Map>();
}
return handle(normalized_map, GetIsolate());
diff --git a/deps/v8/src/objects/map.h b/deps/v8/src/objects/map.h
index 814f8ed3be..c9da19b3e3 100644
--- a/deps/v8/src/objects/map.h
+++ b/deps/v8/src/objects/map.h
@@ -65,13 +65,16 @@ enum InstanceType : uint16_t;
V(SmallOrderedHashMap) \
V(SmallOrderedHashSet) \
V(SmallOrderedNameDictionary) \
+ V(SourceTextModule) \
V(Struct) \
V(Symbol) \
+ V(SyntheticModule) \
V(ThinString) \
V(TransitionArray) \
V(UncompiledDataWithoutPreparseData) \
V(UncompiledDataWithPreparseData) \
V(WasmCapiFunctionData) \
+ V(WasmIndirectFunctionTable) \
V(WasmInstanceObject) \
V(WeakArray) \
V(WeakCell)
@@ -138,22 +141,22 @@ using MapHandles = std::vector<Handle<Map>>;
// | | - has_prototype_slot (bit 7) |
// +----------+---------------------------------------------+
// | Byte | [bit_field2] |
-// | | - is_extensible (bit 0) |
-// | | - is_prototype_map (bit 1) |
-// | | - has_hidden_prototype (bit 2) |
+// | | - new_target_is_base (bit 0) |
+// | | - is_immutable_proto (bit 1) |
+// | | - unused bit (bit 2) |
// | | - elements_kind (bits 3..7) |
// +----+----------+---------------------------------------------+
// | Int | [bit_field3] |
// | | - enum_length (bit 0..9) |
// | | - number_of_own_descriptors (bit 10..19) |
-// | | - is_dictionary_map (bit 20) |
-// | | - owns_descriptors (bit 21) |
-// | | - is_in_retained_map_list (bit 22) |
-// | | - is_deprecated (bit 23) |
-// | | - is_unstable (bit 24) |
-// | | - is_migration_target (bit 25) |
-// | | - is_immutable_proto (bit 26) |
-// | | - new_target_is_base (bit 27) |
+// | | - is_prototype_map (bit 20) |
+// | | - is_dictionary_map (bit 21) |
+// | | - owns_descriptors (bit 22) |
+// | | - is_in_retained_map_list (bit 23) |
+// | | - is_deprecated (bit 24) |
+// | | - is_unstable (bit 25) |
+// | | - is_migration_target (bit 26) |
+// | | - is_extensible (bit 28) |
// | | - may_have_interesting_symbols (bit 28) |
// | | - construction_counter (bit 29..31) |
// | | |
@@ -212,8 +215,8 @@ class Map : public HeapObject {
Handle<Map> map, Handle<Context> native_context);
// Retrieve interceptors.
- inline InterceptorInfo GetNamedInterceptor();
- inline InterceptorInfo GetIndexedInterceptor();
+ DECL_GETTER(GetNamedInterceptor, InterceptorInfo)
+ DECL_GETTER(GetIndexedInterceptor, InterceptorInfo)
// Instance type.
DECL_PRIMITIVE_ACCESSORS(instance_type, InstanceType)
@@ -265,10 +268,10 @@ class Map : public HeapObject {
DECL_PRIMITIVE_ACCESSORS(bit_field2, byte)
// Bit positions for |bit_field2|.
-#define MAP_BIT_FIELD2_FIELDS(V, _) \
- V(IsExtensibleBit, bool, 1, _) \
- V(IsPrototypeMapBit, bool, 1, _) \
- V(HasHiddenPrototypeBit, bool, 1, _) \
+#define MAP_BIT_FIELD2_FIELDS(V, _) \
+ V(NewTargetIsBaseBit, bool, 1, _) \
+ V(IsImmutablePrototypeBit, bool, 1, _) \
+ V(UnusedBit, bool, 1, _) \
V(ElementsKindBits, ElementsKind, 5, _)
DEFINE_BIT_FIELDS(MAP_BIT_FIELD2_FIELDS)
@@ -287,14 +290,14 @@ class Map : public HeapObject {
#define MAP_BIT_FIELD3_FIELDS(V, _) \
V(EnumLengthBits, int, kDescriptorIndexBitCount, _) \
V(NumberOfOwnDescriptorsBits, int, kDescriptorIndexBitCount, _) \
+ V(IsPrototypeMapBit, bool, 1, _) \
V(IsDictionaryMapBit, bool, 1, _) \
V(OwnsDescriptorsBit, bool, 1, _) \
V(IsInRetainedMapListBit, bool, 1, _) \
V(IsDeprecatedBit, bool, 1, _) \
V(IsUnstableBit, bool, 1, _) \
V(IsMigrationTargetBit, bool, 1, _) \
- V(IsImmutablePrototypeBit, bool, 1, _) \
- V(NewTargetIsBaseBit, bool, 1, _) \
+ V(IsExtensibleBit, bool, 1, _) \
V(MayHaveInterestingSymbolsBit, bool, 1, _) \
V(ConstructionCounterBits, int, 3, _)
@@ -378,9 +381,6 @@ class Map : public HeapObject {
DECL_BOOLEAN_ACCESSORS(has_prototype_slot)
- // Tells whether the instance with this map has a hidden prototype.
- DECL_BOOLEAN_ACCESSORS(has_hidden_prototype)
-
// Records and queries whether the instance has a named interceptor.
DECL_BOOLEAN_ACCESSORS(has_named_interceptor)
@@ -431,7 +431,7 @@ class Map : public HeapObject {
// map with DICTIONARY_ELEMENTS was found in the prototype chain.
bool DictionaryElementsInPrototypeChainOnly(Isolate* isolate);
- inline Map ElementsTransitionMap();
+ inline Map ElementsTransitionMap(Isolate* isolate);
inline FixedArrayBase GetInitialElements() const;
@@ -545,9 +545,14 @@ class Map : public HeapObject {
V8_EXPORT_PRIVATE static Handle<Map> Normalize(Isolate* isolate,
Handle<Map> map,
+ ElementsKind new_elements_kind,
PropertyNormalizationMode mode,
const char* reason);
+ inline static Handle<Map> Normalize(Isolate* isolate, Handle<Map> fast_map,
+ PropertyNormalizationMode mode,
+ const char* reason);
+
// Tells whether the map is used for JSObjects in dictionary mode (ie
// normalized objects, ie objects for which HasFastProperties returns false).
// A map can never be used for both dictionary mode and fast mode JSObjects.
@@ -573,19 +578,18 @@ class Map : public HeapObject {
// Returns null_value if there's neither a constructor function nor a
// FunctionTemplateInfo available.
DECL_ACCESSORS(constructor_or_backpointer, Object)
- inline Object GetConstructor() const;
- inline FunctionTemplateInfo GetFunctionTemplateInfo() const;
+ DECL_GETTER(GetConstructor, Object)
+ DECL_GETTER(GetFunctionTemplateInfo, FunctionTemplateInfo)
inline void SetConstructor(Object constructor,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
// [back pointer]: points back to the parent map from which a transition
// leads to this map. The field overlaps with the constructor (see above).
- inline HeapObject GetBackPointer() const;
- inline void SetBackPointer(Object value,
+ DECL_GETTER(GetBackPointer, HeapObject)
+ inline void SetBackPointer(HeapObject value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
// [instance descriptors]: describes the object.
- inline DescriptorArray instance_descriptors() const;
- inline DescriptorArray synchronized_instance_descriptors() const;
+ DECL_GETTER(instance_descriptors, DescriptorArray)
V8_EXPORT_PRIVATE void SetInstanceDescriptors(Isolate* isolate,
DescriptorArray descriptors,
int number_of_own_descriptors);
@@ -629,7 +633,7 @@ class Map : public HeapObject {
// chain state.
inline bool IsPrototypeValidityCellValid() const;
- inline PropertyDetails GetLastDescriptorDetails() const;
+ inline PropertyDetails GetLastDescriptorDetails(Isolate* isolate) const;
inline int LastAdded() const;
@@ -742,7 +746,7 @@ class Map : public HeapObject {
PropertyAttributes attributes);
V8_EXPORT_PRIVATE static Handle<Map> ReconfigureExistingProperty(
Isolate* isolate, Handle<Map> map, int descriptor, PropertyKind kind,
- PropertyAttributes attributes);
+ PropertyAttributes attributes, PropertyConstness constness);
inline void AppendDescriptor(Isolate* isolate, Descriptor* desc);
@@ -794,6 +798,8 @@ class Map : public HeapObject {
inline bool CanTransition() const;
+ static Map GetStructMap(Isolate* isolate, InstanceType type);
+
#define DECL_TESTER(Type, ...) inline bool Is##Type##Map() const;
INSTANCE_TYPE_CHECKERS(DECL_TESTER)
#undef DECL_TESTER
@@ -836,15 +842,19 @@ class Map : public HeapObject {
class BodyDescriptor;
- // Compares this map to another to see if they describe equivalent objects.
+ // Compares this map to another to see if they describe equivalent objects,
+ // up to the given |elements_kind|.
// If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
// it had exactly zero inobject properties.
// The "shared" flags of both this map and |other| are ignored.
- bool EquivalentToForNormalization(const Map other,
+ bool EquivalentToForNormalization(const Map other, ElementsKind elements_kind,
PropertyNormalizationMode mode) const;
+ inline bool EquivalentToForNormalization(
+ const Map other, PropertyNormalizationMode mode) const;
// Returns true if given field is unboxed double.
inline bool IsUnboxedDoubleField(FieldIndex index) const;
+ inline bool IsUnboxedDoubleField(Isolate* isolate, FieldIndex index) const;
void PrintMapDetails(std::ostream& os);
@@ -932,14 +942,6 @@ class Map : public HeapObject {
static Handle<Map> CopyNormalized(Isolate* isolate, Handle<Map> map,
PropertyNormalizationMode mode);
- // TODO(ishell): Move to MapUpdater.
- static Handle<Map> CopyGeneralizeAllFields(Isolate* isolate, Handle<Map> map,
- ElementsKind elements_kind,
- int modify_index,
- PropertyKind kind,
- PropertyAttributes attributes,
- const char* reason);
-
void DeprecateTransitionTree(Isolate* isolate);
void ReplaceDescriptors(Isolate* isolate, DescriptorArray new_descriptors,
@@ -966,13 +968,13 @@ class Map : public HeapObject {
MaybeHandle<FieldType> new_field_type, MaybeHandle<Object> new_value);
// Use the high-level instance_descriptors/SetInstanceDescriptors instead.
- inline void set_synchronized_instance_descriptors(
- DescriptorArray array, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+ DECL_ACCESSORS(synchronized_instance_descriptors, DescriptorArray)
static const int kFastPropertiesSoftLimit = 12;
static const int kMaxFastProperties = 128;
friend class MapUpdater;
+ friend class ConcurrentMarkingVisitor;
OBJECT_CONSTRUCTORS(Map, HeapObject);
};
@@ -986,6 +988,7 @@ class NormalizedMapCache : public WeakFixedArray {
static Handle<NormalizedMapCache> New(Isolate* isolate);
V8_WARN_UNUSED_RESULT MaybeHandle<Map> Get(Handle<Map> fast_map,
+ ElementsKind elements_kind,
PropertyNormalizationMode mode);
void Set(Handle<Map> fast_map, Handle<Map> normalized_map);
@@ -993,7 +996,7 @@ class NormalizedMapCache : public WeakFixedArray {
DECL_VERIFIER(NormalizedMapCache)
private:
- friend bool HeapObject::IsNormalizedMapCache() const;
+ friend bool HeapObject::IsNormalizedMapCache(Isolate* isolate) const;
static const int kEntries = 64;
diff --git a/deps/v8/src/objects/maybe-object.h b/deps/v8/src/objects/maybe-object.h
index a1645c0604..304cf90d28 100644
--- a/deps/v8/src/objects/maybe-object.h
+++ b/deps/v8/src/objects/maybe-object.h
@@ -30,6 +30,10 @@ class MaybeObject : public TaggedImpl<HeapObjectReferenceType::WEAK, Address> {
#ifdef VERIFY_HEAP
static void VerifyMaybeObjectPointer(Isolate* isolate, MaybeObject p);
#endif
+
+ private:
+ template <typename TFieldType, int kFieldOffset>
+ friend class TaggedField;
};
// A HeapObjectReference is either a strong reference to a HeapObject, a weak
diff --git a/deps/v8/src/objects/module-inl.h b/deps/v8/src/objects/module-inl.h
index a3bc31b63a..1ab9b9fb04 100644
--- a/deps/v8/src/objects/module-inl.h
+++ b/deps/v8/src/objects/module-inl.h
@@ -6,9 +6,12 @@
#define V8_OBJECTS_MODULE_INL_H_
#include "src/objects/module.h"
+#include "src/objects/source-text-module.h"
+#include "src/objects/synthetic-module.h"
#include "src/objects/objects-inl.h" // Needed for write barriers
#include "src/objects/scope-info.h"
+#include "src/objects/string-inl.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -16,74 +19,86 @@
namespace v8 {
namespace internal {
-OBJECT_CONSTRUCTORS_IMPL(Module, Struct)
-OBJECT_CONSTRUCTORS_IMPL(ModuleInfoEntry, Struct)
+OBJECT_CONSTRUCTORS_IMPL(Module, HeapObject)
+OBJECT_CONSTRUCTORS_IMPL(SourceTextModule, Module)
+OBJECT_CONSTRUCTORS_IMPL(SourceTextModuleInfoEntry, Struct)
+OBJECT_CONSTRUCTORS_IMPL(SyntheticModule, Module)
OBJECT_CONSTRUCTORS_IMPL(JSModuleNamespace, JSObject)
NEVER_READ_ONLY_SPACE_IMPL(Module)
+NEVER_READ_ONLY_SPACE_IMPL(SourceTextModule)
+NEVER_READ_ONLY_SPACE_IMPL(SyntheticModule)
CAST_ACCESSOR(Module)
-ACCESSORS(Module, code, Object, kCodeOffset)
+CAST_ACCESSOR(SourceTextModule)
+CAST_ACCESSOR(SyntheticModule)
ACCESSORS(Module, exports, ObjectHashTable, kExportsOffset)
-ACCESSORS(Module, regular_exports, FixedArray, kRegularExportsOffset)
-ACCESSORS(Module, regular_imports, FixedArray, kRegularImportsOffset)
ACCESSORS(Module, module_namespace, HeapObject, kModuleNamespaceOffset)
-ACCESSORS(Module, requested_modules, FixedArray, kRequestedModulesOffset)
-ACCESSORS(Module, script, Script, kScriptOffset)
ACCESSORS(Module, exception, Object, kExceptionOffset)
-ACCESSORS(Module, import_meta, Object, kImportMetaOffset)
SMI_ACCESSORS(Module, status, kStatusOffset)
-SMI_ACCESSORS(Module, dfs_index, kDfsIndexOffset)
-SMI_ACCESSORS(Module, dfs_ancestor_index, kDfsAncestorIndexOffset)
SMI_ACCESSORS(Module, hash, kHashOffset)
-ModuleInfo Module::info() const {
+ACCESSORS(SourceTextModule, code, Object, kCodeOffset)
+ACCESSORS(SourceTextModule, regular_exports, FixedArray, kRegularExportsOffset)
+ACCESSORS(SourceTextModule, regular_imports, FixedArray, kRegularImportsOffset)
+ACCESSORS(SourceTextModule, requested_modules, FixedArray,
+ kRequestedModulesOffset)
+ACCESSORS(SourceTextModule, script, Script, kScriptOffset)
+ACCESSORS(SourceTextModule, import_meta, Object, kImportMetaOffset)
+SMI_ACCESSORS(SourceTextModule, dfs_index, kDfsIndexOffset)
+SMI_ACCESSORS(SourceTextModule, dfs_ancestor_index, kDfsAncestorIndexOffset)
+
+ACCESSORS(SyntheticModule, name, String, kNameOffset)
+ACCESSORS(SyntheticModule, export_names, FixedArray, kExportNamesOffset)
+ACCESSORS(SyntheticModule, evaluation_steps, Foreign, kEvaluationStepsOffset)
+
+SourceTextModuleInfo SourceTextModule::info() const {
return (status() >= kEvaluating)
- ? ModuleInfo::cast(code())
+ ? SourceTextModuleInfo::cast(code())
: GetSharedFunctionInfo().scope_info().ModuleDescriptorInfo();
}
CAST_ACCESSOR(JSModuleNamespace)
ACCESSORS(JSModuleNamespace, module, Module, kModuleOffset)
-CAST_ACCESSOR(ModuleInfoEntry)
-ACCESSORS(ModuleInfoEntry, export_name, Object, kExportNameOffset)
-ACCESSORS(ModuleInfoEntry, local_name, Object, kLocalNameOffset)
-ACCESSORS(ModuleInfoEntry, import_name, Object, kImportNameOffset)
-SMI_ACCESSORS(ModuleInfoEntry, module_request, kModuleRequestOffset)
-SMI_ACCESSORS(ModuleInfoEntry, cell_index, kCellIndexOffset)
-SMI_ACCESSORS(ModuleInfoEntry, beg_pos, kBegPosOffset)
-SMI_ACCESSORS(ModuleInfoEntry, end_pos, kEndPosOffset)
+CAST_ACCESSOR(SourceTextModuleInfoEntry)
+ACCESSORS(SourceTextModuleInfoEntry, export_name, Object, kExportNameOffset)
+ACCESSORS(SourceTextModuleInfoEntry, local_name, Object, kLocalNameOffset)
+ACCESSORS(SourceTextModuleInfoEntry, import_name, Object, kImportNameOffset)
+SMI_ACCESSORS(SourceTextModuleInfoEntry, module_request, kModuleRequestOffset)
+SMI_ACCESSORS(SourceTextModuleInfoEntry, cell_index, kCellIndexOffset)
+SMI_ACCESSORS(SourceTextModuleInfoEntry, beg_pos, kBegPosOffset)
+SMI_ACCESSORS(SourceTextModuleInfoEntry, end_pos, kEndPosOffset)
-OBJECT_CONSTRUCTORS_IMPL(ModuleInfo, FixedArray)
-CAST_ACCESSOR(ModuleInfo)
+OBJECT_CONSTRUCTORS_IMPL(SourceTextModuleInfo, FixedArray)
+CAST_ACCESSOR(SourceTextModuleInfo)
-FixedArray ModuleInfo::module_requests() const {
+FixedArray SourceTextModuleInfo::module_requests() const {
return FixedArray::cast(get(kModuleRequestsIndex));
}
-FixedArray ModuleInfo::special_exports() const {
+FixedArray SourceTextModuleInfo::special_exports() const {
return FixedArray::cast(get(kSpecialExportsIndex));
}
-FixedArray ModuleInfo::regular_exports() const {
+FixedArray SourceTextModuleInfo::regular_exports() const {
return FixedArray::cast(get(kRegularExportsIndex));
}
-FixedArray ModuleInfo::regular_imports() const {
+FixedArray SourceTextModuleInfo::regular_imports() const {
return FixedArray::cast(get(kRegularImportsIndex));
}
-FixedArray ModuleInfo::namespace_imports() const {
+FixedArray SourceTextModuleInfo::namespace_imports() const {
return FixedArray::cast(get(kNamespaceImportsIndex));
}
-FixedArray ModuleInfo::module_request_positions() const {
+FixedArray SourceTextModuleInfo::module_request_positions() const {
return FixedArray::cast(get(kModuleRequestPositionsIndex));
}
#ifdef DEBUG
-bool ModuleInfo::Equals(ModuleInfo other) const {
+bool SourceTextModuleInfo::Equals(SourceTextModuleInfo other) const {
return regular_exports() == other.regular_exports() &&
regular_imports() == other.regular_imports() &&
special_exports() == other.special_exports() &&
@@ -93,6 +108,30 @@ bool ModuleInfo::Equals(ModuleInfo other) const {
}
#endif
+struct ModuleHandleHash {
+ V8_INLINE size_t operator()(Handle<Module> module) const {
+ return module->hash();
+ }
+};
+
+struct ModuleHandleEqual {
+ V8_INLINE bool operator()(Handle<Module> lhs, Handle<Module> rhs) const {
+ return *lhs == *rhs;
+ }
+};
+
+class UnorderedModuleSet
+ : public std::unordered_set<Handle<Module>, ModuleHandleHash,
+ ModuleHandleEqual,
+ ZoneAllocator<Handle<Module>>> {
+ public:
+ explicit UnorderedModuleSet(Zone* zone)
+ : std::unordered_set<Handle<Module>, ModuleHandleHash, ModuleHandleEqual,
+ ZoneAllocator<Handle<Module>>>(
+ 2 /* bucket count */, ModuleHandleHash(), ModuleHandleEqual(),
+ ZoneAllocator<Handle<Module>>(zone)) {}
+};
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/module.cc b/deps/v8/src/objects/module.cc
index ea40989df1..4e89050360 100644
--- a/deps/v8/src/objects/module.cc
+++ b/deps/v8/src/objects/module.cc
@@ -14,169 +14,25 @@
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-generator-inl.h"
#include "src/objects/module-inl.h"
-#include "src/utils/ostreams.h"
#include "src/objects/objects-inl.h"
+#include "src/utils/ostreams.h"
namespace v8 {
namespace internal {
-struct ModuleHandleHash {
- V8_INLINE size_t operator()(Handle<Module> module) const {
- return module->hash();
- }
-};
-
-struct ModuleHandleEqual {
- V8_INLINE bool operator()(Handle<Module> lhs, Handle<Module> rhs) const {
- return *lhs == *rhs;
- }
-};
-
-struct StringHandleHash {
- V8_INLINE size_t operator()(Handle<String> string) const {
- return string->Hash();
- }
-};
-
-struct StringHandleEqual {
- V8_INLINE bool operator()(Handle<String> lhs, Handle<String> rhs) const {
- return lhs->Equals(*rhs);
- }
-};
-
-class UnorderedStringSet
- : public std::unordered_set<Handle<String>, StringHandleHash,
- StringHandleEqual,
- ZoneAllocator<Handle<String>>> {
- public:
- explicit UnorderedStringSet(Zone* zone)
- : std::unordered_set<Handle<String>, StringHandleHash, StringHandleEqual,
- ZoneAllocator<Handle<String>>>(
- 2 /* bucket count */, StringHandleHash(), StringHandleEqual(),
- ZoneAllocator<Handle<String>>(zone)) {}
-};
-
-class UnorderedModuleSet
- : public std::unordered_set<Handle<Module>, ModuleHandleHash,
- ModuleHandleEqual,
- ZoneAllocator<Handle<Module>>> {
- public:
- explicit UnorderedModuleSet(Zone* zone)
- : std::unordered_set<Handle<Module>, ModuleHandleHash, ModuleHandleEqual,
- ZoneAllocator<Handle<Module>>>(
- 2 /* bucket count */, ModuleHandleHash(), ModuleHandleEqual(),
- ZoneAllocator<Handle<Module>>(zone)) {}
-};
-
-class UnorderedStringMap
- : public std::unordered_map<
- Handle<String>, Handle<Object>, StringHandleHash, StringHandleEqual,
- ZoneAllocator<std::pair<const Handle<String>, Handle<Object>>>> {
- public:
- explicit UnorderedStringMap(Zone* zone)
- : std::unordered_map<
- Handle<String>, Handle<Object>, StringHandleHash, StringHandleEqual,
- ZoneAllocator<std::pair<const Handle<String>, Handle<Object>>>>(
- 2 /* bucket count */, StringHandleHash(), StringHandleEqual(),
- ZoneAllocator<std::pair<const Handle<String>, Handle<Object>>>(
- zone)) {}
-};
-
-class Module::ResolveSet
- : public std::unordered_map<
- Handle<Module>, UnorderedStringSet*, ModuleHandleHash,
- ModuleHandleEqual,
- ZoneAllocator<std::pair<const Handle<Module>, UnorderedStringSet*>>> {
- public:
- explicit ResolveSet(Zone* zone)
- : std::unordered_map<Handle<Module>, UnorderedStringSet*,
- ModuleHandleHash, ModuleHandleEqual,
- ZoneAllocator<std::pair<const Handle<Module>,
- UnorderedStringSet*>>>(
- 2 /* bucket count */, ModuleHandleHash(), ModuleHandleEqual(),
- ZoneAllocator<std::pair<const Handle<Module>, UnorderedStringSet*>>(
- zone)),
- zone_(zone) {}
-
- Zone* zone() const { return zone_; }
-
- private:
- Zone* zone_;
-};
-
-int Module::ExportIndex(int cell_index) {
- DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
- ModuleDescriptor::kExport);
- return cell_index - 1;
-}
-
-int Module::ImportIndex(int cell_index) {
- DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
- ModuleDescriptor::kImport);
- return -cell_index - 1;
-}
-
-void Module::CreateIndirectExport(Isolate* isolate, Handle<Module> module,
- Handle<String> name,
- Handle<ModuleInfoEntry> entry) {
- Handle<ObjectHashTable> exports(module->exports(), isolate);
- DCHECK(exports->Lookup(name).IsTheHole(isolate));
- exports = ObjectHashTable::Put(exports, name, entry);
- module->set_exports(*exports);
-}
-
-void Module::CreateExport(Isolate* isolate, Handle<Module> module,
- int cell_index, Handle<FixedArray> names) {
- DCHECK_LT(0, names->length());
- Handle<Cell> cell =
- isolate->factory()->NewCell(isolate->factory()->undefined_value());
- module->regular_exports().set(ExportIndex(cell_index), *cell);
-
- Handle<ObjectHashTable> exports(module->exports(), isolate);
- for (int i = 0, n = names->length(); i < n; ++i) {
- Handle<String> name(String::cast(names->get(i)), isolate);
- DCHECK(exports->Lookup(name).IsTheHole(isolate));
- exports = ObjectHashTable::Put(exports, name, cell);
- }
- module->set_exports(*exports);
-}
-
-Cell Module::GetCell(int cell_index) {
- DisallowHeapAllocation no_gc;
- Object cell;
- switch (ModuleDescriptor::GetCellIndexKind(cell_index)) {
- case ModuleDescriptor::kImport:
- cell = regular_imports().get(ImportIndex(cell_index));
- break;
- case ModuleDescriptor::kExport:
- cell = regular_exports().get(ExportIndex(cell_index));
- break;
- case ModuleDescriptor::kInvalid:
- UNREACHABLE();
- }
- return Cell::cast(cell);
-}
-
-Handle<Object> Module::LoadVariable(Isolate* isolate, Handle<Module> module,
- int cell_index) {
- return handle(module->GetCell(cell_index).value(), isolate);
-}
-
-void Module::StoreVariable(Handle<Module> module, int cell_index,
- Handle<Object> value) {
- DisallowHeapAllocation no_gc;
- DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
- ModuleDescriptor::kExport);
- module->GetCell(cell_index).set_value(*value);
-}
-
#ifdef DEBUG
void Module::PrintStatusTransition(Status new_status) {
if (FLAG_trace_module_status) {
StdoutStream os;
os << "Changing module status from " << status() << " to " << new_status
<< " for ";
- script().GetNameOrSourceURL().Print(os);
+ if (this->IsSourceTextModule()) {
+ Handle<Script> script(SourceTextModule::cast(*this).script(),
+ GetIsolate());
+ script->GetNameOrSourceURL().Print(os);
+ } else {
+ SyntheticModule::cast(*this).name().Print(os);
+ }
#ifndef OBJECT_PRINT
os << "\n";
#endif // OBJECT_PRINT
@@ -194,70 +50,80 @@ void Module::SetStatus(Status new_status) {
set_status(new_status);
}
+void Module::RecordError(Isolate* isolate) {
+ DisallowHeapAllocation no_alloc;
+ DCHECK(exception().IsTheHole(isolate));
+ Object the_exception = isolate->pending_exception();
+ DCHECK(!the_exception.IsTheHole(isolate));
+
+ if (this->IsSourceTextModule()) {
+ Handle<SourceTextModule> self(SourceTextModule::cast(*this), GetIsolate());
+ self->set_code(self->info());
+ }
+#ifdef DEBUG
+ PrintStatusTransition(Module::kErrored);
+#endif // DEBUG
+ set_status(Module::kErrored);
+ set_exception(the_exception);
+}
+
void Module::ResetGraph(Isolate* isolate, Handle<Module> module) {
DCHECK_NE(module->status(), kInstantiating);
DCHECK_NE(module->status(), kEvaluating);
if (module->status() != kPreInstantiating) return;
- Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
+
+ Handle<FixedArray> requested_modules =
+ module->IsSourceTextModule()
+ ? Handle<FixedArray>(
+ Handle<SourceTextModule>::cast(module)->requested_modules(),
+ isolate)
+ : Handle<FixedArray>();
Reset(isolate, module);
- for (int i = 0; i < requested_modules->length(); ++i) {
- Handle<Object> descendant(requested_modules->get(i), isolate);
- if (descendant->IsModule()) {
- ResetGraph(isolate, Handle<Module>::cast(descendant));
- } else {
- DCHECK(descendant->IsUndefined(isolate));
+ if (module->IsSourceTextModule()) {
+ for (int i = 0; i < requested_modules->length(); ++i) {
+ Handle<Object> descendant(requested_modules->get(i), isolate);
+ if (descendant->IsModule()) {
+ ResetGraph(isolate, Handle<Module>::cast(descendant));
+ } else {
+ DCHECK(descendant->IsUndefined(isolate));
+ }
}
+ } else {
+ DCHECK(module->IsSyntheticModule());
+ // Nothing else to do here.
}
}
void Module::Reset(Isolate* isolate, Handle<Module> module) {
- Factory* factory = isolate->factory();
-
DCHECK(module->status() == kPreInstantiating ||
module->status() == kInstantiating);
DCHECK(module->exception().IsTheHole(isolate));
- DCHECK(module->import_meta().IsTheHole(isolate));
// The namespace object cannot exist, because it would have been created
// by RunInitializationCode, which is called only after this module's SCC
// succeeds instantiation.
DCHECK(!module->module_namespace().IsJSModuleNamespace());
- Handle<ObjectHashTable> exports =
- ObjectHashTable::New(isolate, module->info().RegularExportCount());
- Handle<FixedArray> regular_exports =
- factory->NewFixedArray(module->regular_exports().length());
- Handle<FixedArray> regular_imports =
- factory->NewFixedArray(module->regular_imports().length());
- Handle<FixedArray> requested_modules =
- factory->NewFixedArray(module->requested_modules().length());
-
- if (module->status() == kInstantiating) {
- module->set_code(JSFunction::cast(module->code()).shared());
- }
#ifdef DEBUG
module->PrintStatusTransition(kUninstantiated);
#endif // DEBUG
- module->set_status(kUninstantiated);
- module->set_exports(*exports);
- module->set_regular_exports(*regular_exports);
- module->set_regular_imports(*regular_imports);
- module->set_requested_modules(*requested_modules);
- module->set_dfs_index(-1);
- module->set_dfs_ancestor_index(-1);
-}
-void Module::RecordError(Isolate* isolate) {
- DisallowHeapAllocation no_alloc;
- DCHECK(exception().IsTheHole(isolate));
- Object the_exception = isolate->pending_exception();
- DCHECK(!the_exception.IsTheHole(isolate));
+ int export_count;
- set_code(info());
-#ifdef DEBUG
- PrintStatusTransition(Module::kErrored);
-#endif // DEBUG
- set_status(Module::kErrored);
- set_exception(the_exception);
+ if (module->IsSourceTextModule()) {
+ Handle<SourceTextModule> source_text_module =
+ Handle<SourceTextModule>::cast(module);
+ export_count = source_text_module->regular_exports().length();
+ SourceTextModule::Reset(isolate, source_text_module);
+ } else {
+ export_count =
+ Handle<SyntheticModule>::cast(module)->export_names().length();
+ // Nothing to do here.
+ }
+
+ Handle<ObjectHashTable> exports = ObjectHashTable::New(isolate, export_count);
+
+ module->set_exports(*exports);
+ module->set_status(kUninstantiated);
}
Object Module::GetException() {
@@ -267,46 +133,6 @@ Object Module::GetException() {
return exception();
}
-SharedFunctionInfo Module::GetSharedFunctionInfo() const {
- DisallowHeapAllocation no_alloc;
- DCHECK_NE(status(), Module::kEvaluating);
- DCHECK_NE(status(), Module::kEvaluated);
- switch (status()) {
- case kUninstantiated:
- case kPreInstantiating:
- DCHECK(code().IsSharedFunctionInfo());
- return SharedFunctionInfo::cast(code());
- case kInstantiating:
- DCHECK(code().IsJSFunction());
- return JSFunction::cast(code()).shared();
- case kInstantiated:
- DCHECK(code().IsJSGeneratorObject());
- return JSGeneratorObject::cast(code()).function().shared();
- case kEvaluating:
- case kEvaluated:
- case kErrored:
- UNREACHABLE();
- }
-
- UNREACHABLE();
-}
-
-MaybeHandle<Cell> Module::ResolveImport(Isolate* isolate, Handle<Module> module,
- Handle<String> name, int module_request,
- MessageLocation loc, bool must_resolve,
- Module::ResolveSet* resolve_set) {
- Handle<Module> requested_module(
- Module::cast(module->requested_modules().get(module_request)), isolate);
- Handle<String> specifier(
- String::cast(module->info().module_requests().get(module_request)),
- isolate);
- MaybeHandle<Cell> result =
- Module::ResolveExport(isolate, requested_module, specifier, name, loc,
- must_resolve, resolve_set);
- DCHECK_IMPLIES(isolate->has_pending_exception(), result.is_null());
- return result;
-}
-
MaybeHandle<Cell> Module::ResolveExport(Isolate* isolate, Handle<Module> module,
Handle<String> module_specifier,
Handle<String> export_name,
@@ -314,121 +140,16 @@ MaybeHandle<Cell> Module::ResolveExport(Isolate* isolate, Handle<Module> module,
Module::ResolveSet* resolve_set) {
DCHECK_GE(module->status(), kPreInstantiating);
DCHECK_NE(module->status(), kEvaluating);
- Handle<Object> object(module->exports().Lookup(export_name), isolate);
- if (object->IsCell()) {
- // Already resolved (e.g. because it's a local export).
- return Handle<Cell>::cast(object);
- }
- // Check for cycle before recursing.
- {
- // Attempt insertion with a null string set.
- auto result = resolve_set->insert({module, nullptr});
- UnorderedStringSet*& name_set = result.first->second;
- if (result.second) {
- // |module| wasn't in the map previously, so allocate a new name set.
- Zone* zone = resolve_set->zone();
- name_set =
- new (zone->New(sizeof(UnorderedStringSet))) UnorderedStringSet(zone);
- } else if (name_set->count(export_name)) {
- // Cycle detected.
- if (must_resolve) {
- return isolate->Throw<Cell>(
- isolate->factory()->NewSyntaxError(
- MessageTemplate::kCyclicModuleDependency, export_name,
- module_specifier),
- &loc);
- }
- return MaybeHandle<Cell>();
- }
- name_set->insert(export_name);
+ if (module->IsSourceTextModule()) {
+ return SourceTextModule::ResolveExport(
+ isolate, Handle<SourceTextModule>::cast(module), module_specifier,
+ export_name, loc, must_resolve, resolve_set);
+ } else {
+ return SyntheticModule::ResolveExport(
+ isolate, Handle<SyntheticModule>::cast(module), module_specifier,
+ export_name, loc, must_resolve);
}
-
- if (object->IsModuleInfoEntry()) {
- // Not yet resolved indirect export.
- Handle<ModuleInfoEntry> entry = Handle<ModuleInfoEntry>::cast(object);
- Handle<String> import_name(String::cast(entry->import_name()), isolate);
- Handle<Script> script(module->script(), isolate);
- MessageLocation new_loc(script, entry->beg_pos(), entry->end_pos());
-
- Handle<Cell> cell;
- if (!ResolveImport(isolate, module, import_name, entry->module_request(),
- new_loc, true, resolve_set)
- .ToHandle(&cell)) {
- DCHECK(isolate->has_pending_exception());
- return MaybeHandle<Cell>();
- }
-
- // The export table may have changed but the entry in question should be
- // unchanged.
- Handle<ObjectHashTable> exports(module->exports(), isolate);
- DCHECK(exports->Lookup(export_name).IsModuleInfoEntry());
-
- exports = ObjectHashTable::Put(exports, export_name, cell);
- module->set_exports(*exports);
- return cell;
- }
-
- DCHECK(object->IsTheHole(isolate));
- return Module::ResolveExportUsingStarExports(isolate, module,
- module_specifier, export_name,
- loc, must_resolve, resolve_set);
-}
-
-MaybeHandle<Cell> Module::ResolveExportUsingStarExports(
- Isolate* isolate, Handle<Module> module, Handle<String> module_specifier,
- Handle<String> export_name, MessageLocation loc, bool must_resolve,
- Module::ResolveSet* resolve_set) {
- if (!export_name->Equals(ReadOnlyRoots(isolate).default_string())) {
- // Go through all star exports looking for the given name. If multiple star
- // exports provide the name, make sure they all map it to the same cell.
- Handle<Cell> unique_cell;
- Handle<FixedArray> special_exports(module->info().special_exports(),
- isolate);
- for (int i = 0, n = special_exports->length(); i < n; ++i) {
- i::Handle<i::ModuleInfoEntry> entry(
- i::ModuleInfoEntry::cast(special_exports->get(i)), isolate);
- if (!entry->export_name().IsUndefined(isolate)) {
- continue; // Indirect export.
- }
-
- Handle<Script> script(module->script(), isolate);
- MessageLocation new_loc(script, entry->beg_pos(), entry->end_pos());
-
- Handle<Cell> cell;
- if (ResolveImport(isolate, module, export_name, entry->module_request(),
- new_loc, false, resolve_set)
- .ToHandle(&cell)) {
- if (unique_cell.is_null()) unique_cell = cell;
- if (*unique_cell != *cell) {
- return isolate->Throw<Cell>(isolate->factory()->NewSyntaxError(
- MessageTemplate::kAmbiguousExport,
- module_specifier, export_name),
- &loc);
- }
- } else if (isolate->has_pending_exception()) {
- return MaybeHandle<Cell>();
- }
- }
-
- if (!unique_cell.is_null()) {
- // Found a unique star export for this name.
- Handle<ObjectHashTable> exports(module->exports(), isolate);
- DCHECK(exports->Lookup(export_name).IsTheHole(isolate));
- exports = ObjectHashTable::Put(exports, export_name, unique_cell);
- module->set_exports(*exports);
- return unique_cell;
- }
- }
-
- // Unresolvable.
- if (must_resolve) {
- return isolate->Throw<Cell>(
- isolate->factory()->NewSyntaxError(MessageTemplate::kUnresolvableExport,
- module_specifier, export_name),
- &loc);
- }
- return MaybeHandle<Cell>();
}
bool Module::Instantiate(Isolate* isolate, Handle<Module> module,
@@ -438,7 +159,14 @@ bool Module::Instantiate(Isolate* isolate, Handle<Module> module,
if (FLAG_trace_module_status) {
StdoutStream os;
os << "Instantiating module ";
- module->script().GetNameOrSourceURL().Print(os);
+ if (module->IsSourceTextModule()) {
+ Handle<SourceTextModule>::cast(module)
+ ->script()
+ .GetNameOrSourceURL()
+ .Print(os);
+ } else {
+ Handle<SyntheticModule>::cast(module)->name().Print(os);
+ }
#ifndef OBJECT_PRINT
os << "\n";
#endif // OBJECT_PRINT
@@ -450,7 +178,7 @@ bool Module::Instantiate(Isolate* isolate, Handle<Module> module,
return false;
}
Zone zone(isolate->allocator(), ZONE_NAME);
- ZoneForwardList<Handle<Module>> stack(&zone);
+ ZoneForwardList<Handle<SourceTextModule>> stack(&zone);
unsigned dfs_index = 0;
if (!FinishInstantiate(isolate, module, &stack, &dfs_index, &zone)) {
for (auto& descendant : stack) {
@@ -474,188 +202,31 @@ bool Module::PrepareInstantiate(Isolate* isolate, Handle<Module> module,
module->SetStatus(kPreInstantiating);
STACK_CHECK(isolate, false);
- // Obtain requested modules.
- Handle<ModuleInfo> module_info(module->info(), isolate);
- Handle<FixedArray> module_requests(module_info->module_requests(), isolate);
- Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
- for (int i = 0, length = module_requests->length(); i < length; ++i) {
- Handle<String> specifier(String::cast(module_requests->get(i)), isolate);
- v8::Local<v8::Module> api_requested_module;
- if (!callback(context, v8::Utils::ToLocal(specifier),
- v8::Utils::ToLocal(module))
- .ToLocal(&api_requested_module)) {
- isolate->PromoteScheduledException();
- return false;
- }
- Handle<Module> requested_module = Utils::OpenHandle(*api_requested_module);
- requested_modules->set(i, *requested_module);
- }
-
- // Recurse.
- for (int i = 0, length = requested_modules->length(); i < length; ++i) {
- Handle<Module> requested_module(Module::cast(requested_modules->get(i)),
- isolate);
- if (!PrepareInstantiate(isolate, requested_module, context, callback)) {
- return false;
- }
- }
-
- // Set up local exports.
- // TODO(neis): Create regular_exports array here instead of in factory method?
- for (int i = 0, n = module_info->RegularExportCount(); i < n; ++i) {
- int cell_index = module_info->RegularExportCellIndex(i);
- Handle<FixedArray> export_names(module_info->RegularExportExportNames(i),
- isolate);
- CreateExport(isolate, module, cell_index, export_names);
- }
-
- // Partially set up indirect exports.
- // For each indirect export, we create the appropriate slot in the export
- // table and store its ModuleInfoEntry there. When we later find the correct
- // Cell in the module that actually provides the value, we replace the
- // ModuleInfoEntry by that Cell (see ResolveExport).
- Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
- for (int i = 0, n = special_exports->length(); i < n; ++i) {
- Handle<ModuleInfoEntry> entry(
- ModuleInfoEntry::cast(special_exports->get(i)), isolate);
- Handle<Object> export_name(entry->export_name(), isolate);
- if (export_name->IsUndefined(isolate)) continue; // Star export.
- CreateIndirectExport(isolate, module, Handle<String>::cast(export_name),
- entry);
- }
-
- DCHECK_EQ(module->status(), kPreInstantiating);
- return true;
-}
-
-bool Module::RunInitializationCode(Isolate* isolate, Handle<Module> module) {
- DCHECK_EQ(module->status(), kInstantiating);
- Handle<JSFunction> function(JSFunction::cast(module->code()), isolate);
- DCHECK_EQ(MODULE_SCOPE, function->shared().scope_info().scope_type());
- Handle<Object> receiver = isolate->factory()->undefined_value();
- Handle<Object> argv[] = {module};
- MaybeHandle<Object> maybe_generator =
- Execution::Call(isolate, function, receiver, arraysize(argv), argv);
- Handle<Object> generator;
- if (!maybe_generator.ToHandle(&generator)) {
- DCHECK(isolate->has_pending_exception());
- return false;
- }
- DCHECK_EQ(*function, Handle<JSGeneratorObject>::cast(generator)->function());
- module->set_code(*generator);
- return true;
-}
-
-bool Module::MaybeTransitionComponent(Isolate* isolate, Handle<Module> module,
- ZoneForwardList<Handle<Module>>* stack,
- Status new_status) {
- DCHECK(new_status == kInstantiated || new_status == kEvaluated);
- SLOW_DCHECK(
- // {module} is on the {stack}.
- std::count_if(stack->begin(), stack->end(),
- [&](Handle<Module> m) { return *m == *module; }) == 1);
- DCHECK_LE(module->dfs_ancestor_index(), module->dfs_index());
- if (module->dfs_ancestor_index() == module->dfs_index()) {
- // This is the root of its strongly connected component.
- Handle<Module> ancestor;
- do {
- ancestor = stack->front();
- stack->pop_front();
- DCHECK_EQ(ancestor->status(),
- new_status == kInstantiated ? kInstantiating : kEvaluating);
- if (new_status == kInstantiated) {
- if (!RunInitializationCode(isolate, ancestor)) return false;
- }
- ancestor->SetStatus(new_status);
- } while (*ancestor != *module);
+ if (module->IsSourceTextModule()) {
+ return SourceTextModule::PrepareInstantiate(
+ isolate, Handle<SourceTextModule>::cast(module), context, callback);
+ } else {
+ return SyntheticModule::PrepareInstantiate(
+ isolate, Handle<SyntheticModule>::cast(module), context, callback);
}
- return true;
}
bool Module::FinishInstantiate(Isolate* isolate, Handle<Module> module,
- ZoneForwardList<Handle<Module>>* stack,
+ ZoneForwardList<Handle<SourceTextModule>>* stack,
unsigned* dfs_index, Zone* zone) {
DCHECK_NE(module->status(), kEvaluating);
if (module->status() >= kInstantiating) return true;
DCHECK_EQ(module->status(), kPreInstantiating);
STACK_CHECK(isolate, false);
- // Instantiate SharedFunctionInfo and mark module as instantiating for
- // the recursion.
- Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(module->code()),
- isolate);
- Handle<JSFunction> function =
- isolate->factory()->NewFunctionFromSharedFunctionInfo(
- shared, isolate->native_context());
- module->set_code(*function);
- module->SetStatus(kInstantiating);
- module->set_dfs_index(*dfs_index);
- module->set_dfs_ancestor_index(*dfs_index);
- stack->push_front(module);
- (*dfs_index)++;
-
- // Recurse.
- Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
- for (int i = 0, length = requested_modules->length(); i < length; ++i) {
- Handle<Module> requested_module(Module::cast(requested_modules->get(i)),
- isolate);
- if (!FinishInstantiate(isolate, requested_module, stack, dfs_index, zone)) {
- return false;
- }
-
- DCHECK_NE(requested_module->status(), kEvaluating);
- DCHECK_GE(requested_module->status(), kInstantiating);
- SLOW_DCHECK(
- // {requested_module} is instantiating iff it's on the {stack}.
- (requested_module->status() == kInstantiating) ==
- std::count_if(stack->begin(), stack->end(), [&](Handle<Module> m) {
- return *m == *requested_module;
- }));
-
- if (requested_module->status() == kInstantiating) {
- module->set_dfs_ancestor_index(
- std::min(module->dfs_ancestor_index(),
- requested_module->dfs_ancestor_index()));
- }
+ if (module->IsSourceTextModule()) {
+ return SourceTextModule::FinishInstantiate(
+ isolate, Handle<SourceTextModule>::cast(module), stack, dfs_index,
+ zone);
+ } else {
+ return SyntheticModule::FinishInstantiate(
+ isolate, Handle<SyntheticModule>::cast(module));
}
-
- Handle<Script> script(module->script(), isolate);
- Handle<ModuleInfo> module_info(module->info(), isolate);
-
- // Resolve imports.
- Handle<FixedArray> regular_imports(module_info->regular_imports(), isolate);
- for (int i = 0, n = regular_imports->length(); i < n; ++i) {
- Handle<ModuleInfoEntry> entry(
- ModuleInfoEntry::cast(regular_imports->get(i)), isolate);
- Handle<String> name(String::cast(entry->import_name()), isolate);
- MessageLocation loc(script, entry->beg_pos(), entry->end_pos());
- ResolveSet resolve_set(zone);
- Handle<Cell> cell;
- if (!ResolveImport(isolate, module, name, entry->module_request(), loc,
- true, &resolve_set)
- .ToHandle(&cell)) {
- return false;
- }
- module->regular_imports().set(ImportIndex(entry->cell_index()), *cell);
- }
-
- // Resolve indirect exports.
- Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
- for (int i = 0, n = special_exports->length(); i < n; ++i) {
- Handle<ModuleInfoEntry> entry(
- ModuleInfoEntry::cast(special_exports->get(i)), isolate);
- Handle<Object> name(entry->export_name(), isolate);
- if (name->IsUndefined(isolate)) continue; // Star export.
- MessageLocation loc(script, entry->beg_pos(), entry->end_pos());
- ResolveSet resolve_set(zone);
- if (ResolveExport(isolate, module, Handle<String>(),
- Handle<String>::cast(name), loc, true, &resolve_set)
- .is_null()) {
- return false;
- }
- }
-
- return MaybeTransitionComponent(isolate, module, stack, kInstantiated);
}
MaybeHandle<Object> Module::Evaluate(Isolate* isolate, Handle<Module> module) {
@@ -663,7 +234,14 @@ MaybeHandle<Object> Module::Evaluate(Isolate* isolate, Handle<Module> module) {
if (FLAG_trace_module_status) {
StdoutStream os;
os << "Evaluating module ";
- module->script().GetNameOrSourceURL().Print(os);
+ if (module->IsSourceTextModule()) {
+ Handle<SourceTextModule>::cast(module)
+ ->script()
+ .GetNameOrSourceURL()
+ .Print(os);
+ } else {
+ Handle<SyntheticModule>::cast(module)->name().Print(os);
+ }
#ifndef OBJECT_PRINT
os << "\n";
#endif // OBJECT_PRINT
@@ -677,7 +255,7 @@ MaybeHandle<Object> Module::Evaluate(Isolate* isolate, Handle<Module> module) {
DCHECK_GE(module->status(), kInstantiated);
Zone zone(isolate->allocator(), ZONE_NAME);
- ZoneForwardList<Handle<Module>> stack(&zone);
+ ZoneForwardList<Handle<SourceTextModule>> stack(&zone);
unsigned dfs_index = 0;
Handle<Object> result;
if (!Evaluate(isolate, module, &stack, &dfs_index).ToHandle(&result)) {
@@ -693,9 +271,9 @@ MaybeHandle<Object> Module::Evaluate(Isolate* isolate, Handle<Module> module) {
return result;
}
-MaybeHandle<Object> Module::Evaluate(Isolate* isolate, Handle<Module> module,
- ZoneForwardList<Handle<Module>>* stack,
- unsigned* dfs_index) {
+MaybeHandle<Object> Module::Evaluate(
+ Isolate* isolate, Handle<Module> module,
+ ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index) {
if (module->status() == kErrored) {
isolate->Throw(module->GetException());
return MaybeHandle<Object>();
@@ -706,134 +284,13 @@ MaybeHandle<Object> Module::Evaluate(Isolate* isolate, Handle<Module> module,
DCHECK_EQ(module->status(), kInstantiated);
STACK_CHECK(isolate, MaybeHandle<Object>());
- Handle<JSGeneratorObject> generator(JSGeneratorObject::cast(module->code()),
- isolate);
- module->set_code(
- generator->function().shared().scope_info().ModuleDescriptorInfo());
- module->SetStatus(kEvaluating);
- module->set_dfs_index(*dfs_index);
- module->set_dfs_ancestor_index(*dfs_index);
- stack->push_front(module);
- (*dfs_index)++;
-
- // Recursion.
- Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
- for (int i = 0, length = requested_modules->length(); i < length; ++i) {
- Handle<Module> requested_module(Module::cast(requested_modules->get(i)),
- isolate);
- RETURN_ON_EXCEPTION(
- isolate, Evaluate(isolate, requested_module, stack, dfs_index), Object);
-
- DCHECK_GE(requested_module->status(), kEvaluating);
- DCHECK_NE(requested_module->status(), kErrored);
- SLOW_DCHECK(
- // {requested_module} is evaluating iff it's on the {stack}.
- (requested_module->status() == kEvaluating) ==
- std::count_if(stack->begin(), stack->end(), [&](Handle<Module> m) {
- return *m == *requested_module;
- }));
-
- if (requested_module->status() == kEvaluating) {
- module->set_dfs_ancestor_index(
- std::min(module->dfs_ancestor_index(),
- requested_module->dfs_ancestor_index()));
- }
+ if (module->IsSourceTextModule()) {
+ return SourceTextModule::Evaluate(
+ isolate, Handle<SourceTextModule>::cast(module), stack, dfs_index);
+ } else {
+ return SyntheticModule::Evaluate(isolate,
+ Handle<SyntheticModule>::cast(module));
}
-
- // Evaluation of module body.
- Handle<JSFunction> resume(
- isolate->native_context()->generator_next_internal(), isolate);
- Handle<Object> result;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, result, Execution::Call(isolate, resume, generator, 0, nullptr),
- Object);
- DCHECK(JSIteratorResult::cast(*result).done().BooleanValue(isolate));
-
- CHECK(MaybeTransitionComponent(isolate, module, stack, kEvaluated));
- return handle(JSIteratorResult::cast(*result).value(), isolate);
-}
-
-namespace {
-
-void FetchStarExports(Isolate* isolate, Handle<Module> module, Zone* zone,
- UnorderedModuleSet* visited) {
- DCHECK_GE(module->status(), Module::kInstantiating);
-
- if (module->module_namespace().IsJSModuleNamespace()) return; // Shortcut.
-
- bool cycle = !visited->insert(module).second;
- if (cycle) return;
- Handle<ObjectHashTable> exports(module->exports(), isolate);
- UnorderedStringMap more_exports(zone);
-
- // TODO(neis): Only allocate more_exports if there are star exports.
- // Maybe split special_exports into indirect_exports and star_exports.
-
- ReadOnlyRoots roots(isolate);
- Handle<FixedArray> special_exports(module->info().special_exports(), isolate);
- for (int i = 0, n = special_exports->length(); i < n; ++i) {
- Handle<ModuleInfoEntry> entry(
- ModuleInfoEntry::cast(special_exports->get(i)), isolate);
- if (!entry->export_name().IsUndefined(roots)) {
- continue; // Indirect export.
- }
-
- Handle<Module> requested_module(
- Module::cast(module->requested_modules().get(entry->module_request())),
- isolate);
-
- // Recurse.
- FetchStarExports(isolate, requested_module, zone, visited);
-
- // Collect all of [requested_module]'s exports that must be added to
- // [module]'s exports (i.e. to [exports]). We record these in
- // [more_exports]. Ambiguities (conflicting exports) are marked by mapping
- // the name to undefined instead of a Cell.
- Handle<ObjectHashTable> requested_exports(requested_module->exports(),
- isolate);
- for (int i = 0, n = requested_exports->Capacity(); i < n; ++i) {
- Object key;
- if (!requested_exports->ToKey(roots, i, &key)) continue;
- Handle<String> name(String::cast(key), isolate);
-
- if (name->Equals(roots.default_string())) continue;
- if (!exports->Lookup(name).IsTheHole(roots)) continue;
-
- Handle<Cell> cell(Cell::cast(requested_exports->ValueAt(i)), isolate);
- auto insert_result = more_exports.insert(std::make_pair(name, cell));
- if (!insert_result.second) {
- auto it = insert_result.first;
- if (*it->second == *cell || it->second->IsUndefined(roots)) {
- // We already recorded this mapping before, or the name is already
- // known to be ambiguous. In either case, there's nothing to do.
- } else {
- DCHECK(it->second->IsCell());
- // Different star exports provide different cells for this name, hence
- // mark the name as ambiguous.
- it->second = roots.undefined_value_handle();
- }
- }
- }
- }
-
- // Copy [more_exports] into [exports].
- for (const auto& elem : more_exports) {
- if (elem.second->IsUndefined(isolate)) continue; // Ambiguous export.
- DCHECK(!elem.first->Equals(ReadOnlyRoots(isolate).default_string()));
- DCHECK(elem.second->IsCell());
- exports = ObjectHashTable::Put(exports, elem.first, elem.second);
- }
- module->set_exports(*exports);
-}
-
-} // anonymous namespace
-
-Handle<JSModuleNamespace> Module::GetModuleNamespace(Isolate* isolate,
- Handle<Module> module,
- int module_request) {
- Handle<Module> requested_module(
- Module::cast(module->requested_modules().get(module_request)), isolate);
- return Module::GetModuleNamespace(isolate, requested_module);
}
Handle<JSModuleNamespace> Module::GetModuleNamespace(Isolate* isolate,
@@ -848,7 +305,12 @@ Handle<JSModuleNamespace> Module::GetModuleNamespace(Isolate* isolate,
// Collect the export names.
Zone zone(isolate->allocator(), ZONE_NAME);
UnorderedModuleSet visited(&zone);
- FetchStarExports(isolate, module, &zone, &visited);
+
+ if (module->IsSourceTextModule()) {
+ SourceTextModule::FetchStarExports(
+ isolate, Handle<SourceTextModule>::cast(module), &zone, &visited);
+ }
+
Handle<ObjectHashTable> exports(module->exports(), isolate);
ZoneVector<Handle<String>> names(&zone);
names.reserve(exports->NumberOfElements());
@@ -874,7 +336,7 @@ Handle<JSModuleNamespace> Module::GetModuleNamespace(Isolate* isolate,
// Create the properties in the namespace object. Transition the object
// to dictionary mode so that property addition is faster.
PropertyAttributes attr = DONT_DELETE;
- JSObject::NormalizeProperties(ns, CLEAR_INOBJECT_PROPERTIES,
+ JSObject::NormalizeProperties(isolate, ns, CLEAR_INOBJECT_PROPERTIES,
static_cast<int>(names.size()),
"JSModuleNamespace");
for (const auto& name : names) {
diff --git a/deps/v8/src/objects/module.h b/deps/v8/src/objects/module.h
index a1672dce7e..b776ddb0be 100644
--- a/deps/v8/src/objects/module.h
+++ b/deps/v8/src/objects/module.h
@@ -9,6 +9,7 @@
#include "src/objects/js-objects.h"
#include "src/objects/objects.h"
#include "src/objects/struct.h"
+#include "torque-generated/field-offsets-tq.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -20,35 +21,23 @@ template <typename T>
class Handle;
class Isolate;
class JSModuleNamespace;
-class ModuleDescriptor;
-class ModuleInfo;
-class ModuleInfoEntry;
+class SourceTextModuleDescriptor;
+class SourceTextModuleInfo;
+class SourceTextModuleInfoEntry;
class String;
class Zone;
-// The runtime representation of an ECMAScript module.
-class Module : public Struct {
+// Module is the base class for ECMAScript module types, roughly corresponding
+// to Abstract Module Record.
+// https://tc39.github.io/ecma262/#sec-abstract-module-records
+class Module : public HeapObject {
public:
NEVER_READ_ONLY_SPACE
DECL_CAST(Module)
DECL_VERIFIER(Module)
DECL_PRINTER(Module)
- // The code representing this module, or an abstraction thereof.
- // This is either a SharedFunctionInfo, a JSFunction, a JSGeneratorObject, or
- // a ModuleInfo, depending on the state (status) the module is in. See
- // Module::ModuleVerify() for the precise invariant.
- DECL_ACCESSORS(code, Object)
-
- // Arrays of cells corresponding to regular exports and regular imports.
- // A cell's position in the array is determined by the cell index of the
- // associated module entry (which coincides with the variable index of the
- // associated variable).
- DECL_ACCESSORS(regular_exports, FixedArray)
- DECL_ACCESSORS(regular_imports, FixedArray)
-
// The complete export table, mapping an export name to its cell.
- // TODO(neis): We may want to remove the regular exports from the table.
DECL_ACCESSORS(exports, ObjectHashTable)
// Hash for this object (a random non-zero Smi).
@@ -67,31 +56,12 @@ class Module : public Struct {
kErrored
};
- // The exception in the case {status} is kErrored.
- Object GetException();
-
- // The shared function info in case {status} is not kEvaluating, kEvaluated or
- // kErrored.
- SharedFunctionInfo GetSharedFunctionInfo() const;
-
// The namespace object (or undefined).
DECL_ACCESSORS(module_namespace, HeapObject)
- // Modules imported or re-exported by this module.
- // Corresponds 1-to-1 to the module specifier strings in
- // ModuleInfo::module_requests.
- DECL_ACCESSORS(requested_modules, FixedArray)
-
- // [script]: Script from which the module originates.
- DECL_ACCESSORS(script, Script)
-
- // The value of import.meta inside of this module.
- // Lazily initialized on first access. It's the hole before first access and
- // a JSObject afterwards.
- DECL_ACCESSORS(import_meta, Object)
-
- // Get the ModuleInfo associated with the code.
- inline ModuleInfo info() const;
+ // The exception in the case {status} is kErrored.
+ Object GetException();
+ DECL_ACCESSORS(exception, Object)
// Implementation of spec operation ModuleDeclarationInstantiation.
// Returns false if an exception occurred during instantiation, true
@@ -105,63 +75,20 @@ class Module : public Struct {
static V8_WARN_UNUSED_RESULT MaybeHandle<Object> Evaluate(
Isolate* isolate, Handle<Module> module);
- Cell GetCell(int cell_index);
- static Handle<Object> LoadVariable(Isolate* isolate, Handle<Module> module,
- int cell_index);
- static void StoreVariable(Handle<Module> module, int cell_index,
- Handle<Object> value);
-
- static int ImportIndex(int cell_index);
- static int ExportIndex(int cell_index);
-
- // Get the namespace object for [module_request] of [module]. If it doesn't
- // exist yet, it is created.
- static Handle<JSModuleNamespace> GetModuleNamespace(Isolate* isolate,
- Handle<Module> module,
- int module_request);
-
// Get the namespace object for [module]. If it doesn't exist yet, it is
// created.
static Handle<JSModuleNamespace> GetModuleNamespace(Isolate* isolate,
Handle<Module> module);
// Layout description.
-#define MODULE_FIELDS(V) \
- V(kCodeOffset, kTaggedSize) \
- V(kExportsOffset, kTaggedSize) \
- V(kRegularExportsOffset, kTaggedSize) \
- V(kRegularImportsOffset, kTaggedSize) \
- V(kHashOffset, kTaggedSize) \
- V(kModuleNamespaceOffset, kTaggedSize) \
- V(kRequestedModulesOffset, kTaggedSize) \
- V(kStatusOffset, kTaggedSize) \
- V(kDfsIndexOffset, kTaggedSize) \
- V(kDfsAncestorIndexOffset, kTaggedSize) \
- V(kExceptionOffset, kTaggedSize) \
- V(kScriptOffset, kTaggedSize) \
- V(kImportMetaOffset, kTaggedSize) \
- /* Total size. */ \
- V(kSize, 0)
-
- DEFINE_FIELD_OFFSET_CONSTANTS(Struct::kHeaderSize, MODULE_FIELDS)
-#undef MODULE_FIELDS
-
- private:
- friend class Factory;
-
- DECL_ACCESSORS(exception, Object)
-
- // TODO(neis): Don't store those in the module object?
- DECL_INT_ACCESSORS(dfs_index)
- DECL_INT_ACCESSORS(dfs_ancestor_index)
+ DEFINE_FIELD_OFFSET_CONSTANTS(Struct::kHeaderSize,
+ TORQUE_GENERATED_MODULE_FIELDS)
- // Helpers for Instantiate and Evaluate.
+ using BodyDescriptor =
+ FixedBodyDescriptor<kExportsOffset, kHeaderSize, kHeaderSize>;
- static void CreateExport(Isolate* isolate, Handle<Module> module,
- int cell_index, Handle<FixedArray> names);
- static void CreateIndirectExport(Isolate* isolate, Handle<Module> module,
- Handle<String> name,
- Handle<ModuleInfoEntry> entry);
+ protected:
+ friend class Factory;
// The [must_resolve] argument indicates whether or not an exception should be
// thrown in case the module does not provide an export named [name]
@@ -176,32 +103,18 @@ class Module : public Struct {
Isolate* isolate, Handle<Module> module, Handle<String> module_specifier,
Handle<String> export_name, MessageLocation loc, bool must_resolve,
ResolveSet* resolve_set);
- static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveImport(
- Isolate* isolate, Handle<Module> module, Handle<String> name,
- int module_request, MessageLocation loc, bool must_resolve,
- ResolveSet* resolve_set);
-
- static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveExportUsingStarExports(
- Isolate* isolate, Handle<Module> module, Handle<String> module_specifier,
- Handle<String> export_name, MessageLocation loc, bool must_resolve,
- ResolveSet* resolve_set);
static V8_WARN_UNUSED_RESULT bool PrepareInstantiate(
Isolate* isolate, Handle<Module> module, v8::Local<v8::Context> context,
v8::Module::ResolveCallback callback);
static V8_WARN_UNUSED_RESULT bool FinishInstantiate(
Isolate* isolate, Handle<Module> module,
- ZoneForwardList<Handle<Module>>* stack, unsigned* dfs_index, Zone* zone);
- static V8_WARN_UNUSED_RESULT bool RunInitializationCode(
- Isolate* isolate, Handle<Module> module);
+ ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index,
+ Zone* zone);
static V8_WARN_UNUSED_RESULT MaybeHandle<Object> Evaluate(
Isolate* isolate, Handle<Module> module,
- ZoneForwardList<Handle<Module>>* stack, unsigned* dfs_index);
-
- static V8_WARN_UNUSED_RESULT bool MaybeTransitionComponent(
- Isolate* isolate, Handle<Module> module,
- ZoneForwardList<Handle<Module>>* stack, Status new_status);
+ ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index);
// Set module's status back to kUninstantiated and reset other internal state.
// This is used when instantiation fails.
@@ -217,7 +130,7 @@ class Module : public Struct {
void PrintStatusTransition(Status new_status);
#endif // DEBUG
- OBJECT_CONSTRUCTORS(Module, Struct);
+ OBJECT_CONSTRUCTORS(Module, HeapObject);
};
// When importing a module namespace (import * as foo from "bar"), a
@@ -250,93 +163,16 @@ class JSModuleNamespace : public JSObject {
kInObjectFieldCount,
};
-// Layout description.
-#define JS_MODULE_NAMESPACE_FIELDS(V) \
- V(kModuleOffset, kTaggedSize) \
- /* Header size. */ \
- V(kHeaderSize, 0) \
- V(kInObjectFieldsOffset, kTaggedSize* kInObjectFieldCount) \
- /* Total size. */ \
- V(kSize, 0)
-
+ // Layout description.
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
- JS_MODULE_NAMESPACE_FIELDS)
-#undef JS_MODULE_NAMESPACE_FIELDS
-
- OBJECT_CONSTRUCTORS(JSModuleNamespace, JSObject);
-};
-
-// ModuleInfo is to ModuleDescriptor what ScopeInfo is to Scope.
-class ModuleInfo : public FixedArray {
- public:
- DECL_CAST(ModuleInfo)
-
- static Handle<ModuleInfo> New(Isolate* isolate, Zone* zone,
- ModuleDescriptor* descr);
-
- inline FixedArray module_requests() const;
- inline FixedArray special_exports() const;
- inline FixedArray regular_exports() const;
- inline FixedArray regular_imports() const;
- inline FixedArray namespace_imports() const;
- inline FixedArray module_request_positions() const;
-
- // Accessors for [regular_exports].
- int RegularExportCount() const;
- String RegularExportLocalName(int i) const;
- int RegularExportCellIndex(int i) const;
- FixedArray RegularExportExportNames(int i) const;
+ TORQUE_GENERATED_JSMODULE_NAMESPACE_FIELDS)
-#ifdef DEBUG
- inline bool Equals(ModuleInfo other) const;
-#endif
+ // We need to include in-object fields
+ // TODO(v8:8944): improve handling of in-object fields
+ static constexpr int kSize =
+ kHeaderSize + (kTaggedSize * kInObjectFieldCount);
- private:
- friend class Factory;
- friend class ModuleDescriptor;
- enum {
- kModuleRequestsIndex,
- kSpecialExportsIndex,
- kRegularExportsIndex,
- kNamespaceImportsIndex,
- kRegularImportsIndex,
- kModuleRequestPositionsIndex,
- kLength
- };
- enum {
- kRegularExportLocalNameOffset,
- kRegularExportCellIndexOffset,
- kRegularExportExportNamesOffset,
- kRegularExportLength
- };
- OBJECT_CONSTRUCTORS(ModuleInfo, FixedArray);
-};
-
-class ModuleInfoEntry : public Struct {
- public:
- DECL_CAST(ModuleInfoEntry)
- DECL_PRINTER(ModuleInfoEntry)
- DECL_VERIFIER(ModuleInfoEntry)
-
- DECL_ACCESSORS(export_name, Object)
- DECL_ACCESSORS(local_name, Object)
- DECL_ACCESSORS(import_name, Object)
- DECL_INT_ACCESSORS(module_request)
- DECL_INT_ACCESSORS(cell_index)
- DECL_INT_ACCESSORS(beg_pos)
- DECL_INT_ACCESSORS(end_pos)
-
- static Handle<ModuleInfoEntry> New(Isolate* isolate,
- Handle<Object> export_name,
- Handle<Object> local_name,
- Handle<Object> import_name,
- int module_request, int cell_index,
- int beg_pos, int end_pos);
-
- DEFINE_FIELD_OFFSET_CONSTANTS(Struct::kHeaderSize,
- TORQUE_GENERATED_MODULE_INFO_ENTRY_FIELDS)
-
- OBJECT_CONSTRUCTORS(ModuleInfoEntry, Struct);
+ OBJECT_CONSTRUCTORS(JSModuleNamespace, JSObject);
};
} // namespace internal
diff --git a/deps/v8/src/objects/name-inl.h b/deps/v8/src/objects/name-inl.h
index b3e04bbd50..8aded12fb5 100644
--- a/deps/v8/src/objects/name-inl.h
+++ b/deps/v8/src/objects/name-inl.h
@@ -16,14 +16,9 @@
namespace v8 {
namespace internal {
-OBJECT_CONSTRUCTORS_IMPL(Name, HeapObject)
-OBJECT_CONSTRUCTORS_IMPL(Symbol, Name)
+TQ_OBJECT_CONSTRUCTORS_IMPL(Name)
+TQ_OBJECT_CONSTRUCTORS_IMPL(Symbol)
-CAST_ACCESSOR(Name)
-CAST_ACCESSOR(Symbol)
-
-ACCESSORS(Symbol, name, Object, kNameOffset)
-INT_ACCESSORS(Symbol, flags, kFlagsOffset)
BIT_FIELD_ACCESSORS(Symbol, flags, is_private, Symbol::IsPrivateBit)
BIT_FIELD_ACCESSORS(Symbol, flags, is_well_known_symbol,
Symbol::IsWellKnownSymbolBit)
@@ -44,20 +39,14 @@ void Symbol::set_is_private_name() {
set_flags(Symbol::IsPrivateNameBit::update(flags(), true));
}
-bool Name::IsUniqueName() const {
- uint32_t type = map().instance_type();
+DEF_GETTER(Name, IsUniqueName, bool) {
+ uint32_t type = map(isolate).instance_type();
bool result = (type & (kIsNotStringMask | kIsNotInternalizedMask)) !=
(kStringTag | kNotInternalizedTag);
SLOW_DCHECK(result == HeapObject::IsUniqueName());
return result;
}
-uint32_t Name::hash_field() { return ReadField<uint32_t>(kHashFieldOffset); }
-
-void Name::set_hash_field(uint32_t value) {
- WriteField<uint32_t>(kHashFieldOffset, value);
-}
-
bool Name::Equals(Name other) {
if (other == *this) return true;
if ((this->IsInternalizedString() && other.IsInternalizedString()) ||
@@ -91,17 +80,17 @@ uint32_t Name::Hash() {
return String::cast(*this).ComputeAndSetHash();
}
-bool Name::IsInterestingSymbol() const {
- return IsSymbol() && Symbol::cast(*this).is_interesting_symbol();
+DEF_GETTER(Name, IsInterestingSymbol, bool) {
+ return IsSymbol(isolate) && Symbol::cast(*this).is_interesting_symbol();
}
-bool Name::IsPrivate() {
- return this->IsSymbol() && Symbol::cast(*this).is_private();
+DEF_GETTER(Name, IsPrivate, bool) {
+ return this->IsSymbol(isolate) && Symbol::cast(*this).is_private();
}
-bool Name::IsPrivateName() {
+DEF_GETTER(Name, IsPrivateName, bool) {
bool is_private_name =
- this->IsSymbol() && Symbol::cast(*this).is_private_name();
+ this->IsSymbol(isolate) && Symbol::cast(*this).is_private_name();
DCHECK_IMPLIES(is_private_name, IsPrivate());
return is_private_name;
}
diff --git a/deps/v8/src/objects/name.h b/deps/v8/src/objects/name.h
index 8b2a8f0a01..b13aa30fb0 100644
--- a/deps/v8/src/objects/name.h
+++ b/deps/v8/src/objects/name.h
@@ -7,7 +7,7 @@
#include "src/objects/heap-object.h"
#include "src/objects/objects.h"
-#include "torque-generated/field-offsets-tq.h"
+#include "torque-generated/class-definitions-tq.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -17,12 +17,8 @@ namespace internal {
// The Name abstract class captures anything that can be used as a property
// name, i.e., strings and symbols. All names store a hash value.
-class Name : public HeapObject {
+class Name : public TorqueGeneratedName<Name, HeapObject> {
public:
- // Get and set the hash field of the name.
- inline uint32_t hash_field();
- inline void set_hash_field(uint32_t value);
-
// Tells whether the hash code has been computed.
inline bool HasHashCode();
@@ -43,15 +39,19 @@ class Name : public HeapObject {
// symbol properties are added, so we can optimize lookups on objects
// that don't have the flag.
inline bool IsInterestingSymbol() const;
+ inline bool IsInterestingSymbol(Isolate* isolate) const;
// If the name is private, it can only name own properties.
- inline bool IsPrivate();
+ inline bool IsPrivate() const;
+ inline bool IsPrivate(Isolate* isolate) const;
// If the name is a private name, it should behave like a private
// symbol but also throw on property access miss.
- inline bool IsPrivateName();
+ inline bool IsPrivateName() const;
+ inline bool IsPrivateName(Isolate* isolate) const;
inline bool IsUniqueName() const;
+ inline bool IsUniqueName(Isolate* isolate) const;
static inline bool ContainsCachedArrayIndex(uint32_t hash);
@@ -62,15 +62,10 @@ class Name : public HeapObject {
V8_WARN_UNUSED_RESULT static MaybeHandle<String> ToFunctionName(
Isolate* isolate, Handle<Name> name, Handle<String> prefix);
- DECL_CAST(Name)
-
DECL_PRINTER(Name)
void NameShortPrint();
int NameShortPrint(Vector<char> str);
- DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
- TORQUE_GENERATED_NAME_FIELDS)
-
// Mask constant for checking if a name has a computed hash code
// and if it is a string that is an array index. The least significant bit
// indicates whether a hash code has been computed. If the hash code has
@@ -131,17 +126,12 @@ class Name : public HeapObject {
protected:
static inline bool IsHashFieldComputed(uint32_t field);
- OBJECT_CONSTRUCTORS(Name, HeapObject);
+ TQ_OBJECT_CONSTRUCTORS(Name)
};
// ES6 symbols.
-class Symbol : public Name {
+class Symbol : public TorqueGeneratedSymbol<Symbol, Name> {
public:
- // [name]: The print name of a symbol, or undefined if none.
- DECL_ACCESSORS(name, Object)
-
- DECL_INT_ACCESSORS(flags)
-
// [is_private]: Whether this is a private symbol. Private symbols can only
// be used to designate own properties of objects.
DECL_BOOLEAN_ACCESSORS(is_private)
@@ -169,15 +159,10 @@ class Symbol : public Name {
inline bool is_private_name() const;
inline void set_is_private_name();
- DECL_CAST(Symbol)
-
// Dispatched behavior.
DECL_PRINTER(Symbol)
DECL_VERIFIER(Symbol)
- DEFINE_FIELD_OFFSET_CONSTANTS(Name::kHeaderSize,
- TORQUE_GENERATED_SYMBOL_FIELDS)
-
// Flags layout.
#define FLAGS_BIT_FIELDS(V, _) \
V(IsPrivateBit, bool, 1, _) \
@@ -199,7 +184,7 @@ class Symbol : public Name {
// TODO(cbruni): remove once the new maptracer is in place.
friend class Name; // For PrivateSymbolToName.
- OBJECT_CONSTRUCTORS(Symbol, Name);
+ TQ_OBJECT_CONSTRUCTORS(Symbol)
};
} // namespace internal
diff --git a/deps/v8/src/objects/object-list-macros.h b/deps/v8/src/objects/object-list-macros.h
index 78452de502..c15b212eec 100644
--- a/deps/v8/src/objects/object-list-macros.h
+++ b/deps/v8/src/objects/object-list-macros.h
@@ -27,6 +27,7 @@ class FunctionLiteral;
class FunctionTemplateInfo;
class JSAsyncGeneratorObject;
class JSGlobalProxy;
+class SourceTextModule;
class JSPromise;
class JSProxy;
class JSProxyRevocableResult;
@@ -35,7 +36,7 @@ class LayoutDescriptor;
class LookupIterator;
class FieldType;
class Module;
-class ModuleInfoEntry;
+class SourceTextModuleInfoEntry;
class MutableHeapNumber;
class ObjectHashTable;
class ObjectTemplateInfo;
@@ -53,6 +54,7 @@ class ScriptContextTable;
class SharedFunctionInfo;
class StringStream;
class Symbol;
+class SyntheticModule;
class FeedbackCell;
class FeedbackMetadata;
class FeedbackVector;
@@ -134,10 +136,13 @@ class ZoneForwardList;
V(JSAsyncGeneratorObject) \
V(JSBoundFunction) \
V(JSCollection) \
+ V(JSCollectionIterator) \
V(JSContextExtensionObject) \
V(JSDataView) \
V(JSDate) \
V(JSError) \
+ V(JSFinalizationGroup) \
+ V(JSFinalizationGroupCleanupIterator) \
V(JSFunction) \
V(JSGeneratorObject) \
V(JSGlobalObject) \
@@ -147,6 +152,7 @@ class ZoneForwardList;
V(JSMessageObject) \
V(JSModuleNamespace) \
V(JSObject) \
+ V(JSPrimitiveWrapper) \
V(JSPromise) \
V(JSProxy) \
V(JSReceiver) \
@@ -158,18 +164,15 @@ class ZoneForwardList;
V(JSSloppyArgumentsObject) \
V(JSStringIterator) \
V(JSTypedArray) \
- V(JSValue) \
- V(JSWeakRef) \
V(JSWeakCollection) \
- V(JSFinalizationGroup) \
- V(JSFinalizationGroupCleanupIterator) \
+ V(JSWeakRef) \
V(JSWeakMap) \
V(JSWeakSet) \
V(LoadHandler) \
V(Map) \
V(MapCache) \
+ V(Module) \
V(Microtask) \
- V(ModuleInfo) \
V(MutableHeapNumber) \
V(Name) \
V(NameDictionary) \
@@ -202,6 +205,8 @@ class ZoneForwardList;
V(SmallOrderedHashMap) \
V(SmallOrderedHashSet) \
V(SmallOrderedNameDictionary) \
+ V(SourceTextModule) \
+ V(SourceTextModuleInfo) \
V(StoreHandler) \
V(String) \
V(StringSet) \
@@ -210,6 +215,7 @@ class ZoneForwardList;
V(Struct) \
V(Symbol) \
V(SymbolWrapper) \
+ V(SyntheticModule) \
V(TemplateInfo) \
V(TemplateList) \
V(ThinString) \
@@ -248,9 +254,17 @@ class ZoneForwardList;
#define HEAP_OBJECT_TEMPLATE_TYPE_LIST(V) V(HashTable)
+// Logical sub-types of heap objects that don't correspond to a C++ class but
+// represent some specialization in terms of additional constraints.
+#define HEAP_OBJECT_SPECIALIZED_TYPE_LIST(V) \
+ V(CallableApiObject) \
+ V(CallableJSProxy) \
+ V(NonNullForeign)
+
#define HEAP_OBJECT_TYPE_LIST(V) \
HEAP_OBJECT_ORDINARY_TYPE_LIST(V) \
- HEAP_OBJECT_TEMPLATE_TYPE_LIST(V)
+ HEAP_OBJECT_TEMPLATE_TYPE_LIST(V) \
+ HEAP_OBJECT_SPECIALIZED_TYPE_LIST(V)
#define ODDBALL_LIST(V) \
V(Undefined, undefined_value) \
diff --git a/deps/v8/src/objects/object-macros-undef.h b/deps/v8/src/objects/object-macros-undef.h
index c8ebf57ce7..b96c03c00f 100644
--- a/deps/v8/src/objects/object-macros-undef.h
+++ b/deps/v8/src/objects/object-macros-undef.h
@@ -11,12 +11,16 @@
#undef NEVER_READ_ONLY_SPACE
#undef NEVER_READ_ONLY_SPACE_IMPL
#undef DECL_PRIMITIVE_ACCESSORS
+#undef DECL_SYNCHRONIZED_PRIMITIVE_ACCESSORS
#undef DECL_BOOLEAN_ACCESSORS
#undef DECL_INT_ACCESSORS
+#undef DECL_SYNCHRONIZED_INT_ACCESSORS
#undef DECL_INT32_ACCESSORS
#undef DECL_UINT16_ACCESSORS
#undef DECL_INT16_ACCESSORS
#undef DECL_UINT8_ACCESSORS
+#undef DECL_GETTER
+#undef DEF_GETTER
#undef DECL_ACCESSORS
#undef DECL_CAST
#undef CAST_ACCESSOR
@@ -45,13 +49,10 @@
#undef TYPE_CHECKER
#undef RELAXED_INT16_ACCESSORS
#undef FIELD_ADDR
-#undef READ_FIELD
-#undef READ_WEAK_FIELD
#undef ACQUIRE_READ_FIELD
#undef RELAXED_READ_FIELD
#undef RELAXED_READ_WEAK_FIELD
#undef WRITE_FIELD
-#undef WRITE_WEAK_FIELD
#undef RELEASE_WRITE_FIELD
#undef RELAXED_WRITE_FIELD
#undef RELAXED_WRITE_WEAK_FIELD
diff --git a/deps/v8/src/objects/object-macros.h b/deps/v8/src/objects/object-macros.h
index 1f499d4fba..8f9e51ca9e 100644
--- a/deps/v8/src/objects/object-macros.h
+++ b/deps/v8/src/objects/object-macros.h
@@ -14,15 +14,18 @@
// for fields that can be written to and read from multiple threads at the same
// time. See comments in src/base/atomicops.h for the memory ordering sematics.
-#include "src/common/v8memory.h"
+#include "src/base/memory.h"
// Since this changes visibility, it should always be last in a class
// definition.
-#define OBJECT_CONSTRUCTORS(Type, ...) \
- public: \
- constexpr Type() : __VA_ARGS__() {} \
- \
- protected: \
+#define OBJECT_CONSTRUCTORS(Type, ...) \
+ public: \
+ constexpr Type() : __VA_ARGS__() {} \
+ \
+ protected: \
+ template <typename TFieldType, int kFieldOffset> \
+ friend class TaggedField; \
+ \
explicit inline Type(Address ptr)
#define OBJECT_CONSTRUCTORS_IMPL(Type, Super) \
@@ -34,22 +37,27 @@
// TODO(leszeks): Add checks in the factory that we never allocate these
// objects in RO space.
-#define NEVER_READ_ONLY_SPACE_IMPL(Type) \
- Heap* Type::GetHeap() const { \
- return NeverReadOnlySpaceObject::GetHeap(*this); \
- } \
- Isolate* Type::GetIsolate() const { \
- return NeverReadOnlySpaceObject::GetIsolate(*this); \
+#define NEVER_READ_ONLY_SPACE_IMPL(Type) \
+ Heap* Type::GetHeap() const { return GetHeapFromWritableObject(*this); } \
+ Isolate* Type::GetIsolate() const { \
+ return GetIsolateFromWritableObject(*this); \
}
#define DECL_PRIMITIVE_ACCESSORS(name, type) \
inline type name() const; \
inline void set_##name(type value);
+#define DECL_SYNCHRONIZED_PRIMITIVE_ACCESSORS(name, type) \
+ inline type synchronized_##name() const; \
+ inline void synchronized_set_##name(type value);
+
#define DECL_BOOLEAN_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, bool)
#define DECL_INT_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, int)
+#define DECL_SYNCHRONIZED_INT_ACCESSORS(name) \
+ DECL_SYNCHRONIZED_PRIMITIVE_ACCESSORS(name, int)
+
#define DECL_INT32_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, int32_t)
#define DECL_UINT16_ACCESSORS(name) \
@@ -64,8 +72,22 @@
inline uint8_t name() const; \
inline void set_##name(int value);
+// TODO(ishell): eventually isolate-less getters should not be used anymore.
+// For full pointer-mode the C++ compiler should optimize away unused isolate
+// parameter.
+#define DECL_GETTER(name, type) \
+ inline type name() const; \
+ inline type name(Isolate* isolate) const;
+
+#define DEF_GETTER(holder, name, type) \
+ type holder::name() const { \
+ Isolate* isolate = GetIsolateForPtrCompr(*this); \
+ return holder::name(isolate); \
+ } \
+ type holder::name(Isolate* isolate) const
+
#define DECL_ACCESSORS(name, type) \
- inline type name() const; \
+ DECL_GETTER(name, type) \
inline void set_##name(type value, \
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
@@ -112,14 +134,14 @@
#define ACCESSORS_CHECKED2(holder, name, type, offset, get_condition, \
set_condition) \
- type holder::name() const { \
- type value = type::cast(READ_FIELD(*this, offset)); \
+ DEF_GETTER(holder, name, type) { \
+ type value = TaggedField<type, offset>::load(isolate, *this); \
DCHECK(get_condition); \
return value; \
} \
void holder::set_##name(type value, WriteBarrierMode mode) { \
DCHECK(set_condition); \
- WRITE_FIELD(*this, offset, value); \
+ TaggedField<type, offset>::store(*this, value); \
CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode); \
}
@@ -129,17 +151,17 @@
#define ACCESSORS(holder, name, type, offset) \
ACCESSORS_CHECKED(holder, name, type, offset, true)
-#define SYNCHRONIZED_ACCESSORS_CHECKED2(holder, name, type, offset, \
- get_condition, set_condition) \
- type holder::name() const { \
- type value = type::cast(ACQUIRE_READ_FIELD(*this, offset)); \
- DCHECK(get_condition); \
- return value; \
- } \
- void holder::set_##name(type value, WriteBarrierMode mode) { \
- DCHECK(set_condition); \
- RELEASE_WRITE_FIELD(*this, offset, value); \
- CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode); \
+#define SYNCHRONIZED_ACCESSORS_CHECKED2(holder, name, type, offset, \
+ get_condition, set_condition) \
+ DEF_GETTER(holder, name, type) { \
+ type value = TaggedField<type, offset>::Acquire_Load(isolate, *this); \
+ DCHECK(get_condition); \
+ return value; \
+ } \
+ void holder::set_##name(type value, WriteBarrierMode mode) { \
+ DCHECK(set_condition); \
+ TaggedField<type, offset>::Release_Store(*this, value); \
+ CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode); \
}
#define SYNCHRONIZED_ACCESSORS_CHECKED(holder, name, type, offset, condition) \
@@ -151,14 +173,15 @@
#define WEAK_ACCESSORS_CHECKED2(holder, name, offset, get_condition, \
set_condition) \
- MaybeObject holder::name() const { \
- MaybeObject value = READ_WEAK_FIELD(*this, offset); \
+ DEF_GETTER(holder, name, MaybeObject) { \
+ MaybeObject value = \
+ TaggedField<MaybeObject, offset>::load(isolate, *this); \
DCHECK(get_condition); \
return value; \
} \
void holder::set_##name(MaybeObject value, WriteBarrierMode mode) { \
DCHECK(set_condition); \
- WRITE_WEAK_FIELD(*this, offset, value); \
+ TaggedField<MaybeObject, offset>::store(*this, value); \
CONDITIONAL_WEAK_WRITE_BARRIER(*this, offset, value, mode); \
}
@@ -169,36 +192,44 @@
WEAK_ACCESSORS_CHECKED(holder, name, offset, true)
// Getter that returns a Smi as an int and writes an int as a Smi.
-#define SMI_ACCESSORS_CHECKED(holder, name, offset, condition) \
- int holder::name() const { \
- DCHECK(condition); \
- Object value = READ_FIELD(*this, offset); \
- return Smi::ToInt(value); \
- } \
- void holder::set_##name(int value) { \
- DCHECK(condition); \
- WRITE_FIELD(*this, offset, Smi::FromInt(value)); \
+#define SMI_ACCESSORS_CHECKED(holder, name, offset, condition) \
+ int holder::name() const { \
+ DCHECK(condition); \
+ Smi value = TaggedField<Smi, offset>::load(*this); \
+ return value.value(); \
+ } \
+ void holder::set_##name(int value) { \
+ DCHECK(condition); \
+ TaggedField<Smi, offset>::store(*this, Smi::FromInt(value)); \
}
#define SMI_ACCESSORS(holder, name, offset) \
SMI_ACCESSORS_CHECKED(holder, name, offset, true)
-#define SYNCHRONIZED_SMI_ACCESSORS(holder, name, offset) \
- int holder::synchronized_##name() const { \
- Object value = ACQUIRE_READ_FIELD(*this, offset); \
- return Smi::ToInt(value); \
- } \
- void holder::synchronized_set_##name(int value) { \
- RELEASE_WRITE_FIELD(*this, offset, Smi::FromInt(value)); \
+#define SYNCHRONIZED_SMI_ACCESSORS(holder, name, offset) \
+ int holder::synchronized_##name() const { \
+ Smi value = TaggedField<Smi, offset>::Acquire_Load(*this); \
+ return value.value(); \
+ } \
+ void holder::synchronized_set_##name(int value) { \
+ TaggedField<Smi, offset>::Release_Store(*this, Smi::FromInt(value)); \
+ }
+
+#define RELAXED_SMI_ACCESSORS(holder, name, offset) \
+ int holder::relaxed_read_##name() const { \
+ Smi value = TaggedField<Smi, offset>::Relaxed_Load(*this); \
+ return value.value(); \
+ } \
+ void holder::relaxed_write_##name(int value) { \
+ TaggedField<Smi, offset>::Relaxed_Store(*this, Smi::FromInt(value)); \
}
-#define RELAXED_SMI_ACCESSORS(holder, name, offset) \
- int holder::relaxed_read_##name() const { \
- Object value = RELAXED_READ_FIELD(*this, offset); \
- return Smi::ToInt(value); \
- } \
- void holder::relaxed_write_##name(int value) { \
- RELAXED_WRITE_FIELD(*this, offset, Smi::FromInt(value)); \
+#define TQ_SMI_ACCESSORS(holder, name) \
+ int holder::name() const { \
+ return TorqueGenerated##holder<holder, Super>::name().value(); \
+ } \
+ void holder::set_##name(int value) { \
+ TorqueGenerated##holder<holder, Super>::set_##name(Smi::FromInt(value)); \
}
#define BOOL_GETTER(holder, field, name, offset) \
@@ -223,9 +254,9 @@
return instance_type == forinstancetype; \
}
-#define TYPE_CHECKER(type, ...) \
- bool HeapObject::Is##type() const { \
- return InstanceTypeChecker::Is##type(map().instance_type()); \
+#define TYPE_CHECKER(type, ...) \
+ DEF_GETTER(HeapObject, Is##type, bool) { \
+ return InstanceTypeChecker::Is##type(map(isolate).instance_type()); \
}
#define RELAXED_INT16_ACCESSORS(holder, name, offset) \
@@ -238,39 +269,26 @@
#define FIELD_ADDR(p, offset) ((p).ptr() + offset - kHeapObjectTag)
-#define READ_FIELD(p, offset) (*ObjectSlot(FIELD_ADDR(p, offset)))
-
-#define READ_WEAK_FIELD(p, offset) (*MaybeObjectSlot(FIELD_ADDR(p, offset)))
-
#define ACQUIRE_READ_FIELD(p, offset) \
- ObjectSlot(FIELD_ADDR(p, offset)).Acquire_Load()
+ TaggedField<Object>::Acquire_Load(p, offset)
#define RELAXED_READ_FIELD(p, offset) \
- ObjectSlot(FIELD_ADDR(p, offset)).Relaxed_Load()
+ TaggedField<Object>::Relaxed_Load(p, offset)
#define RELAXED_READ_WEAK_FIELD(p, offset) \
- MaybeObjectSlot(FIELD_ADDR(p, offset)).Relaxed_Load()
+ TaggedField<MaybeObject>::Relaxed_Load(p, offset)
-#ifdef V8_CONCURRENT_MARKING
-#define WRITE_FIELD(p, offset, value) \
- ObjectSlot(FIELD_ADDR(p, offset)).Relaxed_Store(value)
-#define WRITE_WEAK_FIELD(p, offset, value) \
- MaybeObjectSlot(FIELD_ADDR(p, offset)).Relaxed_Store(value)
-#else
#define WRITE_FIELD(p, offset, value) \
- ObjectSlot(FIELD_ADDR(p, offset)).store(value)
-#define WRITE_WEAK_FIELD(p, offset, value) \
- MaybeObjectSlot(FIELD_ADDR(p, offset)).store(value)
-#endif
+ TaggedField<Object>::store(p, offset, value)
#define RELEASE_WRITE_FIELD(p, offset, value) \
- ObjectSlot(FIELD_ADDR(p, offset)).Release_Store(value)
+ TaggedField<Object>::Release_Store(p, offset, value)
#define RELAXED_WRITE_FIELD(p, offset, value) \
- ObjectSlot(FIELD_ADDR(p, offset)).Relaxed_Store(value)
+ TaggedField<Object>::Relaxed_Store(p, offset, value)
#define RELAXED_WRITE_WEAK_FIELD(p, offset, value) \
- MaybeObjectSlot(FIELD_ADDR(p, offset)).Relaxed_Store(value)
+ TaggedField<MaybeObject>::Relaxed_Store(p, offset, value)
#define WRITE_BARRIER(object, offset, value) \
do { \
@@ -412,12 +430,15 @@
set(IndexForEntry(i) + k##name##Offset, value); \
}
-#define TQ_OBJECT_CONSTRUCTORS(Type) \
- public: \
- constexpr Type() = default; \
- \
- protected: \
- inline explicit Type(Address ptr); \
+#define TQ_OBJECT_CONSTRUCTORS(Type) \
+ public: \
+ constexpr Type() = default; \
+ \
+ protected: \
+ template <typename TFieldType, int kFieldOffset> \
+ friend class TaggedField; \
+ \
+ inline explicit Type(Address ptr); \
friend class TorqueGenerated##Type<Type, Super>;
#define TQ_OBJECT_CONSTRUCTORS_IMPL(Type) \
diff --git a/deps/v8/src/objects/objects-body-descriptors-inl.h b/deps/v8/src/objects/objects-body-descriptors-inl.h
index 8626165647..51e380695e 100644
--- a/deps/v8/src/objects/objects-body-descriptors-inl.h
+++ b/deps/v8/src/objects/objects-body-descriptors-inl.h
@@ -19,6 +19,8 @@
#include "src/objects/js-weak-refs.h"
#include "src/objects/oddball.h"
#include "src/objects/ordered-hash-table.h"
+#include "src/objects/source-text-module.h"
+#include "src/objects/synthetic-module.h"
#include "src/objects/transitions.h"
#include "src/wasm/wasm-objects-inl.h"
@@ -918,7 +920,7 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
case JS_GENERATOR_OBJECT_TYPE:
case JS_ASYNC_FUNCTION_OBJECT_TYPE:
case JS_ASYNC_GENERATOR_OBJECT_TYPE:
- case JS_VALUE_TYPE:
+ case JS_PRIMITIVE_WRAPPER_TYPE:
case JS_DATE_TYPE:
case JS_ARRAY_TYPE:
case JS_ARRAY_ITERATOR_TYPE:
@@ -1043,6 +1045,9 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
} else if (type == WASM_CAPI_FUNCTION_DATA_TYPE) {
return Op::template apply<WasmCapiFunctionData::BodyDescriptor>(p1, p2,
p3, p4);
+ } else if (type == WASM_INDIRECT_FUNCTION_TABLE_TYPE) {
+ return Op::template apply<WasmIndirectFunctionTable::BodyDescriptor>(
+ p1, p2, p3, p4);
} else {
return Op::template apply<StructBodyDescriptor>(p1, p2, p3, p4);
}
@@ -1051,6 +1056,12 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
case LOAD_HANDLER_TYPE:
case STORE_HANDLER_TYPE:
return Op::template apply<DataHandler::BodyDescriptor>(p1, p2, p3, p4);
+ case SOURCE_TEXT_MODULE_TYPE:
+ return Op::template apply<SourceTextModule::BodyDescriptor>(p1, p2, p3,
+ p4);
+ case SYNTHETIC_MODULE_TYPE:
+ return Op::template apply<SyntheticModule::BodyDescriptor>(p1, p2, p3,
+ p4);
default:
PrintF("Unknown type: %d\n", type);
UNREACHABLE();
diff --git a/deps/v8/src/objects/objects-definitions.h b/deps/v8/src/objects/objects-definitions.h
index 90824c68ef..b4c8591e5c 100644
--- a/deps/v8/src/objects/objects-definitions.h
+++ b/deps/v8/src/objects/objects-definitions.h
@@ -7,6 +7,8 @@
#include "src/init/heap-symbols.h"
+#include "torque-generated/instance-types-tq.h"
+
namespace v8 {
namespace internal {
@@ -31,7 +33,7 @@ namespace internal {
// HeapObject::Size, HeapObject::IterateBody, the typeof operator, and
// Object::IsString.
//
-// NOTE: Everything following JS_VALUE_TYPE is considered a
+// NOTE: Everything following JS_PRIMITIVE_WRAPPER_TYPE is considered a
// JSObject for GC purposes. The first four entries here have typeof
// 'object', whereas JS_FUNCTION_TYPE has typeof 'function'.
//
@@ -80,6 +82,7 @@ namespace internal {
V(ACCESSOR_PAIR_TYPE) \
V(ALIASED_ARGUMENTS_ENTRY_TYPE) \
V(ALLOCATION_MEMENTO_TYPE) \
+ V(ARRAY_BOILERPLATE_DESCRIPTION_TYPE) \
V(ASM_WASM_DATA_TYPE) \
V(ASYNC_GENERATOR_REQUEST_TYPE) \
V(CLASS_POSITIONS_TYPE) \
@@ -89,24 +92,23 @@ namespace internal {
V(FUNCTION_TEMPLATE_RARE_DATA_TYPE) \
V(INTERCEPTOR_INFO_TYPE) \
V(INTERPRETER_DATA_TYPE) \
- V(MODULE_INFO_ENTRY_TYPE) \
- V(MODULE_TYPE) \
V(OBJECT_TEMPLATE_INFO_TYPE) \
V(PROMISE_CAPABILITY_TYPE) \
V(PROMISE_REACTION_TYPE) \
V(PROTOTYPE_INFO_TYPE) \
V(SCRIPT_TYPE) \
V(SOURCE_POSITION_TABLE_WITH_FRAME_CACHE_TYPE) \
+ V(SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE) \
V(STACK_FRAME_INFO_TYPE) \
V(STACK_TRACE_FRAME_TYPE) \
V(TEMPLATE_OBJECT_DESCRIPTION_TYPE) \
V(TUPLE2_TYPE) \
V(TUPLE3_TYPE) \
- V(ARRAY_BOILERPLATE_DESCRIPTION_TYPE) \
V(WASM_CAPI_FUNCTION_DATA_TYPE) \
V(WASM_DEBUG_INFO_TYPE) \
V(WASM_EXCEPTION_TAG_TYPE) \
V(WASM_EXPORTED_FUNCTION_DATA_TYPE) \
+ V(WASM_INDIRECT_FUNCTION_TABLE_TYPE) \
V(WASM_JS_FUNCTION_DATA_TYPE) \
\
V(CALLABLE_TASK_TYPE) \
@@ -116,6 +118,11 @@ namespace internal {
V(PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE) \
V(FINALIZATION_GROUP_CLEANUP_JOB_TASK_TYPE) \
\
+ TORQUE_DEFINED_INSTANCE_TYPES(V) \
+ \
+ V(SOURCE_TEXT_MODULE_TYPE) \
+ V(SYNTHETIC_MODULE_TYPE) \
+ \
V(ALLOCATION_SITE_TYPE) \
V(EMBEDDER_DATA_ARRAY_TYPE) \
\
@@ -174,7 +181,7 @@ namespace internal {
V(JS_GLOBAL_PROXY_TYPE) \
V(JS_MODULE_NAMESPACE_TYPE) \
V(JS_SPECIAL_API_OBJECT_TYPE) \
- V(JS_VALUE_TYPE) \
+ V(JS_PRIMITIVE_WRAPPER_TYPE) \
V(JS_API_OBJECT_TYPE) \
V(JS_OBJECT_TYPE) \
\
@@ -296,6 +303,8 @@ namespace internal {
V(_, ALIASED_ARGUMENTS_ENTRY_TYPE, AliasedArgumentsEntry, \
aliased_arguments_entry) \
V(_, ALLOCATION_MEMENTO_TYPE, AllocationMemento, allocation_memento) \
+ V(_, ARRAY_BOILERPLATE_DESCRIPTION_TYPE, ArrayBoilerplateDescription, \
+ array_boilerplate_description) \
V(_, ASM_WASM_DATA_TYPE, AsmWasmData, asm_wasm_data) \
V(_, ASYNC_GENERATOR_REQUEST_TYPE, AsyncGeneratorRequest, \
async_generator_request) \
@@ -308,8 +317,6 @@ namespace internal {
function_template_rare_data) \
V(_, INTERCEPTOR_INFO_TYPE, InterceptorInfo, interceptor_info) \
V(_, INTERPRETER_DATA_TYPE, InterpreterData, interpreter_data) \
- V(_, MODULE_INFO_ENTRY_TYPE, ModuleInfoEntry, module_info_entry) \
- V(_, MODULE_TYPE, Module, module) \
V(_, OBJECT_TEMPLATE_INFO_TYPE, ObjectTemplateInfo, object_template_info) \
V(_, PROMISE_CAPABILITY_TYPE, PromiseCapability, promise_capability) \
V(_, PROMISE_REACTION_TYPE, PromiseReaction, promise_reaction) \
@@ -317,20 +324,22 @@ namespace internal {
V(_, SCRIPT_TYPE, Script, script) \
V(_, SOURCE_POSITION_TABLE_WITH_FRAME_CACHE_TYPE, \
SourcePositionTableWithFrameCache, source_position_table_with_frame_cache) \
+ V(_, SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE, SourceTextModuleInfoEntry, \
+ module_info_entry) \
V(_, STACK_FRAME_INFO_TYPE, StackFrameInfo, stack_frame_info) \
V(_, STACK_TRACE_FRAME_TYPE, StackTraceFrame, stack_trace_frame) \
V(_, TEMPLATE_OBJECT_DESCRIPTION_TYPE, TemplateObjectDescription, \
template_object_description) \
V(_, TUPLE2_TYPE, Tuple2, tuple2) \
V(_, TUPLE3_TYPE, Tuple3, tuple3) \
- V(_, ARRAY_BOILERPLATE_DESCRIPTION_TYPE, ArrayBoilerplateDescription, \
- array_boilerplate_description) \
V(_, WASM_CAPI_FUNCTION_DATA_TYPE, WasmCapiFunctionData, \
wasm_capi_function_data) \
V(_, WASM_DEBUG_INFO_TYPE, WasmDebugInfo, wasm_debug_info) \
V(_, WASM_EXCEPTION_TAG_TYPE, WasmExceptionTag, wasm_exception_tag) \
V(_, WASM_EXPORTED_FUNCTION_DATA_TYPE, WasmExportedFunctionData, \
wasm_exported_function_data) \
+ V(_, WASM_INDIRECT_FUNCTION_TABLE_TYPE, WasmIndirectFunctionTable, \
+ wasm_indirect_function_table) \
V(_, WASM_JS_FUNCTION_DATA_TYPE, WasmJSFunctionData, wasm_js_function_data) \
V(_, CALLABLE_TASK_TYPE, CallableTask, callable_task) \
V(_, CALLBACK_TASK_TYPE, CallbackTask, callback_task) \
@@ -347,14 +356,18 @@ namespace internal {
#define STRUCT_LIST_ADAPTER(V, NAME, Name, name) V(NAME, Name, name)
// Produces (NAME, Name, name) entries.
-#define STRUCT_LIST(V) STRUCT_LIST_GENERATOR(STRUCT_LIST_ADAPTER, V)
+#define STRUCT_LIST(V) \
+ STRUCT_LIST_GENERATOR(STRUCT_LIST_ADAPTER, V) \
+ TORQUE_STRUCT_LIST_GENERATOR(STRUCT_LIST_ADAPTER, V)
// Adapts one STRUCT_LIST_GENERATOR entry to the STRUCT_MAPS_LIST entry
#define STRUCT_MAPS_LIST_ADAPTER(V, NAME, Name, name) \
V(Map, name##_map, Name##Map)
// Produces (Map, struct_name_map, StructNameMap) entries
-#define STRUCT_MAPS_LIST(V) STRUCT_LIST_GENERATOR(STRUCT_MAPS_LIST_ADAPTER, V)
+#define STRUCT_MAPS_LIST(V) \
+ STRUCT_LIST_GENERATOR(STRUCT_MAPS_LIST_ADAPTER, V) \
+ TORQUE_STRUCT_LIST_GENERATOR(STRUCT_MAPS_LIST_ADAPTER, V)
//
// The following macros define list of allocation size objects and list of
diff --git a/deps/v8/src/objects/objects-inl.h b/deps/v8/src/objects/objects-inl.h
index ce92d64f2f..b6748401c0 100644
--- a/deps/v8/src/objects/objects-inl.h
+++ b/deps/v8/src/objects/objects-inl.h
@@ -15,11 +15,12 @@
#include "src/objects/objects.h"
#include "src/base/bits.h"
+#include "src/base/memory.h"
#include "src/builtins/builtins.h"
-#include "src/common/v8memory.h"
#include "src/handles/handles-inl.h"
#include "src/heap/factory.h"
#include "src/heap/heap-write-barrier-inl.h"
+#include "src/heap/read-only-heap-inl.h"
#include "src/numbers/conversions.h"
#include "src/numbers/double.h"
#include "src/objects/bigint.h"
@@ -37,6 +38,7 @@
#include "src/objects/shared-function-info.h"
#include "src/objects/slots-inl.h"
#include "src/objects/smi-inl.h"
+#include "src/objects/tagged-field-inl.h"
#include "src/objects/tagged-impl-inl.h"
#include "src/objects/templates.h"
#include "src/sanitizer/tsan.h"
@@ -64,30 +66,37 @@ int PropertyDetails::field_width_in_words() const {
return representation().IsDouble() ? kDoubleSize / kTaggedSize : 1;
}
-bool HeapObject::IsSloppyArgumentsElements() const {
- return IsFixedArrayExact();
+DEF_GETTER(HeapObject, IsSloppyArgumentsElements, bool) {
+ return IsFixedArrayExact(isolate);
}
-bool HeapObject::IsJSSloppyArgumentsObject() const {
- return IsJSArgumentsObject();
+DEF_GETTER(HeapObject, IsJSSloppyArgumentsObject, bool) {
+ return IsJSArgumentsObject(isolate);
}
-bool HeapObject::IsJSGeneratorObject() const {
- return map().instance_type() == JS_GENERATOR_OBJECT_TYPE ||
- IsJSAsyncFunctionObject() || IsJSAsyncGeneratorObject();
+DEF_GETTER(HeapObject, IsJSGeneratorObject, bool) {
+ return map(isolate).instance_type() == JS_GENERATOR_OBJECT_TYPE ||
+ IsJSAsyncFunctionObject(isolate) || IsJSAsyncGeneratorObject(isolate);
}
-bool HeapObject::IsDataHandler() const {
- return IsLoadHandler() || IsStoreHandler();
+DEF_GETTER(HeapObject, IsDataHandler, bool) {
+ return IsLoadHandler(isolate) || IsStoreHandler(isolate);
}
-bool HeapObject::IsClassBoilerplate() const { return IsFixedArrayExact(); }
+DEF_GETTER(HeapObject, IsClassBoilerplate, bool) {
+ return IsFixedArrayExact(isolate);
+}
-#define IS_TYPE_FUNCTION_DEF(type_) \
- bool Object::Is##type_() const { \
- return IsHeapObject() && HeapObject::cast(*this).Is##type_(); \
+#define IS_TYPE_FUNCTION_DEF(type_) \
+ bool Object::Is##type_() const { \
+ return IsHeapObject() && HeapObject::cast(*this).Is##type_(); \
+ } \
+ bool Object::Is##type_(Isolate* isolate) const { \
+ return IsHeapObject() && HeapObject::cast(*this).Is##type_(isolate); \
}
HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DEF)
+IS_TYPE_FUNCTION_DEF(HashTableBase)
+IS_TYPE_FUNCTION_DEF(SmallOrderedHashTable)
#undef IS_TYPE_FUNCTION_DEF
#define IS_TYPE_FUNCTION_DEF(Type, Value) \
@@ -140,109 +149,166 @@ bool HeapObject::IsNullOrUndefined() const {
return IsNullOrUndefined(GetReadOnlyRoots());
}
-bool HeapObject::IsUniqueName() const {
- return IsInternalizedString() || IsSymbol();
+DEF_GETTER(HeapObject, IsUniqueName, bool) {
+ return IsInternalizedString(isolate) || IsSymbol(isolate);
}
-bool HeapObject::IsFunction() const {
+DEF_GETTER(HeapObject, IsFunction, bool) {
STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
- return map().instance_type() >= FIRST_FUNCTION_TYPE;
+ return map(isolate).instance_type() >= FIRST_FUNCTION_TYPE;
}
-bool HeapObject::IsCallable() const { return map().is_callable(); }
+DEF_GETTER(HeapObject, IsCallable, bool) { return map(isolate).is_callable(); }
-bool HeapObject::IsConstructor() const { return map().is_constructor(); }
+DEF_GETTER(HeapObject, IsCallableJSProxy, bool) {
+ return IsCallable(isolate) && IsJSProxy(isolate);
+}
-bool HeapObject::IsModuleInfo() const {
- return map() == GetReadOnlyRoots().module_info_map();
+DEF_GETTER(HeapObject, IsCallableApiObject, bool) {
+ InstanceType type = map(isolate).instance_type();
+ return IsCallable(isolate) &&
+ (type == JS_API_OBJECT_TYPE || type == JS_SPECIAL_API_OBJECT_TYPE);
}
-bool HeapObject::IsTemplateInfo() const {
- return IsObjectTemplateInfo() || IsFunctionTemplateInfo();
+DEF_GETTER(HeapObject, IsNonNullForeign, bool) {
+ return IsForeign(isolate) &&
+ Foreign::cast(*this).foreign_address() != kNullAddress;
}
-bool HeapObject::IsConsString() const {
- if (!IsString()) return false;
- return StringShape(String::cast(*this)).IsCons();
+DEF_GETTER(HeapObject, IsConstructor, bool) {
+ return map(isolate).is_constructor();
}
-bool HeapObject::IsThinString() const {
- if (!IsString()) return false;
- return StringShape(String::cast(*this)).IsThin();
+DEF_GETTER(HeapObject, IsSourceTextModuleInfo, bool) {
+ // Can't use ReadOnlyRoots(isolate) as this isolate could be produced by
+ // i::GetIsolateForPtrCompr(HeapObject).
+ return map(isolate) == GetReadOnlyRoots(isolate).module_info_map();
}
-bool HeapObject::IsSlicedString() const {
- if (!IsString()) return false;
- return StringShape(String::cast(*this)).IsSliced();
+DEF_GETTER(HeapObject, IsTemplateInfo, bool) {
+ return IsObjectTemplateInfo(isolate) || IsFunctionTemplateInfo(isolate);
}
-bool HeapObject::IsSeqString() const {
- if (!IsString()) return false;
- return StringShape(String::cast(*this)).IsSequential();
+DEF_GETTER(HeapObject, IsConsString, bool) {
+ if (!IsString(isolate)) return false;
+ return StringShape(String::cast(*this).map(isolate)).IsCons();
}
-bool HeapObject::IsSeqOneByteString() const {
- if (!IsString()) return false;
- return StringShape(String::cast(*this)).IsSequential() &&
- String::cast(*this).IsOneByteRepresentation();
+DEF_GETTER(HeapObject, IsThinString, bool) {
+ if (!IsString(isolate)) return false;
+ return StringShape(String::cast(*this).map(isolate)).IsThin();
}
-bool HeapObject::IsSeqTwoByteString() const {
- if (!IsString()) return false;
- return StringShape(String::cast(*this)).IsSequential() &&
- String::cast(*this).IsTwoByteRepresentation();
+DEF_GETTER(HeapObject, IsSlicedString, bool) {
+ if (!IsString(isolate)) return false;
+ return StringShape(String::cast(*this).map(isolate)).IsSliced();
}
-bool HeapObject::IsExternalString() const {
- if (!IsString()) return false;
- return StringShape(String::cast(*this)).IsExternal();
+DEF_GETTER(HeapObject, IsSeqString, bool) {
+ if (!IsString(isolate)) return false;
+ return StringShape(String::cast(*this).map(isolate)).IsSequential();
}
-bool HeapObject::IsExternalOneByteString() const {
- if (!IsString()) return false;
- return StringShape(String::cast(*this)).IsExternal() &&
- String::cast(*this).IsOneByteRepresentation();
+DEF_GETTER(HeapObject, IsSeqOneByteString, bool) {
+ if (!IsString(isolate)) return false;
+ return StringShape(String::cast(*this).map(isolate)).IsSequential() &&
+ String::cast(*this).IsOneByteRepresentation(isolate);
}
-bool HeapObject::IsExternalTwoByteString() const {
- if (!IsString()) return false;
- return StringShape(String::cast(*this)).IsExternal() &&
- String::cast(*this).IsTwoByteRepresentation();
+DEF_GETTER(HeapObject, IsSeqTwoByteString, bool) {
+ if (!IsString(isolate)) return false;
+ return StringShape(String::cast(*this).map(isolate)).IsSequential() &&
+ String::cast(*this).IsTwoByteRepresentation(isolate);
}
-bool Object::IsNumber() const { return IsSmi() || IsHeapNumber(); }
+DEF_GETTER(HeapObject, IsExternalString, bool) {
+ if (!IsString(isolate)) return false;
+ return StringShape(String::cast(*this).map(isolate)).IsExternal();
+}
-bool Object::IsNumeric() const { return IsNumber() || IsBigInt(); }
+DEF_GETTER(HeapObject, IsExternalOneByteString, bool) {
+ if (!IsString(isolate)) return false;
+ return StringShape(String::cast(*this).map(isolate)).IsExternal() &&
+ String::cast(*this).IsOneByteRepresentation(isolate);
+}
-bool HeapObject::IsFiller() const {
- InstanceType instance_type = map().instance_type();
+DEF_GETTER(HeapObject, IsExternalTwoByteString, bool) {
+ if (!IsString(isolate)) return false;
+ return StringShape(String::cast(*this).map(isolate)).IsExternal() &&
+ String::cast(*this).IsTwoByteRepresentation(isolate);
+}
+
+bool Object::IsNumber() const {
+ if (IsSmi()) return true;
+ HeapObject this_heap_object = HeapObject::cast(*this);
+ Isolate* isolate = GetIsolateForPtrCompr(this_heap_object);
+ return this_heap_object.IsHeapNumber(isolate);
+}
+
+bool Object::IsNumber(Isolate* isolate) const {
+ return IsSmi() || IsHeapNumber(isolate);
+}
+
+bool Object::IsNumeric() const {
+ if (IsSmi()) return true;
+ HeapObject this_heap_object = HeapObject::cast(*this);
+ Isolate* isolate = GetIsolateForPtrCompr(this_heap_object);
+ return this_heap_object.IsHeapNumber(isolate) ||
+ this_heap_object.IsBigInt(isolate);
+}
+
+bool Object::IsNumeric(Isolate* isolate) const {
+ return IsNumber(isolate) || IsBigInt(isolate);
+}
+
+DEF_GETTER(HeapObject, IsFiller, bool) {
+ InstanceType instance_type = map(isolate).instance_type();
return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
}
-bool HeapObject::IsJSWeakCollection() const {
- return IsJSWeakMap() || IsJSWeakSet();
+DEF_GETTER(HeapObject, IsJSWeakCollection, bool) {
+ return IsJSWeakMap(isolate) || IsJSWeakSet(isolate);
+}
+
+DEF_GETTER(HeapObject, IsJSCollection, bool) {
+ return IsJSMap(isolate) || IsJSSet(isolate);
}
-bool HeapObject::IsJSCollection() const { return IsJSMap() || IsJSSet(); }
+DEF_GETTER(HeapObject, IsPromiseReactionJobTask, bool) {
+ return IsPromiseFulfillReactionJobTask(isolate) ||
+ IsPromiseRejectReactionJobTask(isolate);
+}
-bool HeapObject::IsPromiseReactionJobTask() const {
- return IsPromiseFulfillReactionJobTask() || IsPromiseRejectReactionJobTask();
+DEF_GETTER(HeapObject, IsFrameArray, bool) {
+ return IsFixedArrayExact(isolate);
}
-bool HeapObject::IsFrameArray() const { return IsFixedArrayExact(); }
+DEF_GETTER(HeapObject, IsArrayList, bool) {
+ // Can't use ReadOnlyRoots(isolate) as this isolate could be produced by
+ // i::GetIsolateForPtrCompr(HeapObject).
+ ReadOnlyRoots roots = GetReadOnlyRoots(isolate);
+ return *this == roots.empty_fixed_array() ||
+ map(isolate) == roots.array_list_map();
+}
-bool HeapObject::IsArrayList() const {
- return map() == GetReadOnlyRoots().array_list_map() ||
- *this == GetReadOnlyRoots().empty_fixed_array();
+DEF_GETTER(HeapObject, IsRegExpMatchInfo, bool) {
+ return IsFixedArrayExact(isolate);
}
-bool HeapObject::IsRegExpMatchInfo() const { return IsFixedArrayExact(); }
+bool Object::IsLayoutDescriptor() const {
+ if (IsSmi()) return true;
+ HeapObject this_heap_object = HeapObject::cast(*this);
+ Isolate* isolate = GetIsolateForPtrCompr(this_heap_object);
+ return this_heap_object.IsByteArray(isolate);
+}
-bool Object::IsLayoutDescriptor() const { return IsSmi() || IsByteArray(); }
+bool Object::IsLayoutDescriptor(Isolate* isolate) const {
+ return IsSmi() || IsByteArray(isolate);
+}
-bool HeapObject::IsDeoptimizationData() const {
+DEF_GETTER(HeapObject, IsDeoptimizationData, bool) {
// Must be a fixed array.
- if (!IsFixedArrayExact()) return false;
+ if (!IsFixedArrayExact(isolate)) return false;
// There's no sure way to detect the difference between a fixed array and
// a deoptimization data array. Since this is used for asserts we can
@@ -255,79 +321,98 @@ bool HeapObject::IsDeoptimizationData() const {
return length >= 0 && length % DeoptimizationData::kDeoptEntrySize == 0;
}
-bool HeapObject::IsHandlerTable() const {
- if (!IsFixedArrayExact()) return false;
+DEF_GETTER(HeapObject, IsHandlerTable, bool) {
+ if (!IsFixedArrayExact(isolate)) return false;
// There's actually no way to see the difference between a fixed array and
// a handler table array.
return true;
}
-bool HeapObject::IsTemplateList() const {
- if (!IsFixedArrayExact()) return false;
+DEF_GETTER(HeapObject, IsTemplateList, bool) {
+ if (!IsFixedArrayExact(isolate)) return false;
// There's actually no way to see the difference between a fixed array and
// a template list.
if (FixedArray::cast(*this).length() < 1) return false;
return true;
}
-bool HeapObject::IsDependentCode() const {
- if (!IsWeakFixedArray()) return false;
+DEF_GETTER(HeapObject, IsDependentCode, bool) {
+ if (!IsWeakFixedArray(isolate)) return false;
// There's actually no way to see the difference between a weak fixed array
// and a dependent codes array.
return true;
}
-bool HeapObject::IsAbstractCode() const {
- return IsBytecodeArray() || IsCode();
+DEF_GETTER(HeapObject, IsAbstractCode, bool) {
+ return IsBytecodeArray(isolate) || IsCode(isolate);
}
-bool HeapObject::IsStringWrapper() const {
- return IsJSValue() && JSValue::cast(*this).value().IsString();
+DEF_GETTER(HeapObject, IsStringWrapper, bool) {
+ return IsJSPrimitiveWrapper(isolate) &&
+ JSPrimitiveWrapper::cast(*this).value().IsString(isolate);
}
-bool HeapObject::IsBooleanWrapper() const {
- return IsJSValue() && JSValue::cast(*this).value().IsBoolean();
+DEF_GETTER(HeapObject, IsBooleanWrapper, bool) {
+ return IsJSPrimitiveWrapper(isolate) &&
+ JSPrimitiveWrapper::cast(*this).value().IsBoolean(isolate);
}
-bool HeapObject::IsScriptWrapper() const {
- return IsJSValue() && JSValue::cast(*this).value().IsScript();
+DEF_GETTER(HeapObject, IsScriptWrapper, bool) {
+ return IsJSPrimitiveWrapper(isolate) &&
+ JSPrimitiveWrapper::cast(*this).value().IsScript(isolate);
}
-bool HeapObject::IsNumberWrapper() const {
- return IsJSValue() && JSValue::cast(*this).value().IsNumber();
+DEF_GETTER(HeapObject, IsNumberWrapper, bool) {
+ return IsJSPrimitiveWrapper(isolate) &&
+ JSPrimitiveWrapper::cast(*this).value().IsNumber(isolate);
}
-bool HeapObject::IsBigIntWrapper() const {
- return IsJSValue() && JSValue::cast(*this).value().IsBigInt();
+DEF_GETTER(HeapObject, IsBigIntWrapper, bool) {
+ return IsJSPrimitiveWrapper(isolate) &&
+ JSPrimitiveWrapper::cast(*this).value().IsBigInt(isolate);
}
-bool HeapObject::IsSymbolWrapper() const {
- return IsJSValue() && JSValue::cast(*this).value().IsSymbol();
+DEF_GETTER(HeapObject, IsSymbolWrapper, bool) {
+ return IsJSPrimitiveWrapper(isolate) &&
+ JSPrimitiveWrapper::cast(*this).value().IsSymbol(isolate);
}
-bool HeapObject::IsJSArrayBufferView() const {
- return IsJSDataView() || IsJSTypedArray();
+DEF_GETTER(HeapObject, IsJSArrayBufferView, bool) {
+ return IsJSDataView(isolate) || IsJSTypedArray(isolate);
}
-bool HeapObject::IsStringSet() const { return IsHashTable(); }
+DEF_GETTER(HeapObject, IsJSCollectionIterator, bool) {
+ return IsJSMapIterator(isolate) || IsJSSetIterator(isolate);
+}
-bool HeapObject::IsObjectHashSet() const { return IsHashTable(); }
+DEF_GETTER(HeapObject, IsStringSet, bool) { return IsHashTable(isolate); }
-bool HeapObject::IsCompilationCacheTable() const { return IsHashTable(); }
+DEF_GETTER(HeapObject, IsObjectHashSet, bool) { return IsHashTable(isolate); }
-bool HeapObject::IsMapCache() const { return IsHashTable(); }
+DEF_GETTER(HeapObject, IsCompilationCacheTable, bool) {
+ return IsHashTable(isolate);
+}
-bool HeapObject::IsObjectHashTable() const { return IsHashTable(); }
+DEF_GETTER(HeapObject, IsMapCache, bool) { return IsHashTable(isolate); }
-bool Object::IsHashTableBase() const { return IsHashTable(); }
+DEF_GETTER(HeapObject, IsObjectHashTable, bool) { return IsHashTable(isolate); }
-bool Object::IsSmallOrderedHashTable() const {
- return IsSmallOrderedHashSet() || IsSmallOrderedHashMap() ||
- IsSmallOrderedNameDictionary();
+DEF_GETTER(HeapObject, IsHashTableBase, bool) { return IsHashTable(isolate); }
+
+DEF_GETTER(HeapObject, IsSmallOrderedHashTable, bool) {
+ return IsSmallOrderedHashSet(isolate) || IsSmallOrderedHashMap(isolate) ||
+ IsSmallOrderedNameDictionary(isolate);
}
bool Object::IsPrimitive() const {
- return IsSmi() || HeapObject::cast(*this).map().IsPrimitiveMap();
+ if (IsSmi()) return true;
+ HeapObject this_heap_object = HeapObject::cast(*this);
+ Isolate* isolate = GetIsolateForPtrCompr(this_heap_object);
+ return this_heap_object.map(isolate).IsPrimitiveMap();
+}
+
+bool Object::IsPrimitive(Isolate* isolate) const {
+ return IsSmi() || HeapObject::cast(*this).map(isolate).IsPrimitiveMap();
}
// static
@@ -339,19 +424,21 @@ Maybe<bool> Object::IsArray(Handle<Object> object) {
return JSProxy::IsArray(Handle<JSProxy>::cast(object));
}
-bool HeapObject::IsUndetectable() const { return map().is_undetectable(); }
+DEF_GETTER(HeapObject, IsUndetectable, bool) {
+ return map(isolate).is_undetectable();
+}
-bool HeapObject::IsAccessCheckNeeded() const {
- if (IsJSGlobalProxy()) {
+DEF_GETTER(HeapObject, IsAccessCheckNeeded, bool) {
+ if (IsJSGlobalProxy(isolate)) {
const JSGlobalProxy proxy = JSGlobalProxy::cast(*this);
JSGlobalObject global = proxy.GetIsolate()->context().global_object();
return proxy.IsDetachedFrom(global);
}
- return map().is_access_check_needed();
+ return map(isolate).is_access_check_needed();
}
-bool HeapObject::IsStruct() const {
- switch (map().instance_type()) {
+DEF_GETTER(HeapObject, IsStruct, bool) {
+ switch (map(isolate).instance_type()) {
#define MAKE_STRUCT_CASE(TYPE, Name, name) \
case TYPE: \
return true;
@@ -374,10 +461,13 @@ bool HeapObject::IsStruct() const {
}
}
-#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
- bool Object::Is##Name() const { \
- return IsHeapObject() && HeapObject::cast(*this).Is##Name(); \
- } \
+#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
+ bool Object::Is##Name() const { \
+ return IsHeapObject() && HeapObject::cast(*this).Is##Name(); \
+ } \
+ bool Object::Is##Name(Isolate* isolate) const { \
+ return IsHeapObject() && HeapObject::cast(*this).Is##Name(isolate); \
+ } \
TYPE_CHECKER(Name)
STRUCT_LIST(MAKE_STRUCT_PREDICATE)
#undef MAKE_STRUCT_PREDICATE
@@ -441,25 +531,28 @@ bool Object::FilterKey(PropertyFilter filter) {
return false;
}
-Representation Object::OptimalRepresentation() {
+Representation Object::OptimalRepresentation(Isolate* isolate) const {
if (!FLAG_track_fields) return Representation::Tagged();
if (IsSmi()) {
return Representation::Smi();
- } else if (FLAG_track_double_fields && IsHeapNumber()) {
+ }
+ HeapObject heap_object = HeapObject::cast(*this);
+ if (FLAG_track_double_fields && heap_object.IsHeapNumber(isolate)) {
return Representation::Double();
- } else if (FLAG_track_computed_fields && IsUninitialized()) {
+ } else if (FLAG_track_computed_fields &&
+ heap_object.IsUninitialized(
+ heap_object.GetReadOnlyRoots(isolate))) {
return Representation::None();
} else if (FLAG_track_heap_object_fields) {
- DCHECK(IsHeapObject());
return Representation::HeapObject();
} else {
return Representation::Tagged();
}
}
-ElementsKind Object::OptimalElementsKind() {
+ElementsKind Object::OptimalElementsKind(Isolate* isolate) const {
if (IsSmi()) return PACKED_SMI_ELEMENTS;
- if (IsNumber()) return PACKED_DOUBLE_ELEMENTS;
+ if (IsNumber(isolate)) return PACKED_DOUBLE_ELEMENTS;
return PACKED_ELEMENTS;
}
@@ -618,18 +711,18 @@ HeapObject MapWord::ToForwardingAddress() {
#ifdef VERIFY_HEAP
void HeapObject::VerifyObjectField(Isolate* isolate, int offset) {
- VerifyPointer(isolate, READ_FIELD(*this, offset));
+ VerifyPointer(isolate, TaggedField<Object>::load(isolate, *this, offset));
STATIC_ASSERT(!COMPRESS_POINTERS_BOOL || kTaggedSize == kInt32Size);
}
void HeapObject::VerifyMaybeObjectField(Isolate* isolate, int offset) {
- MaybeObject::VerifyMaybeObjectPointer(isolate,
- READ_WEAK_FIELD(*this, offset));
+ MaybeObject::VerifyMaybeObjectPointer(
+ isolate, TaggedField<MaybeObject>::load(isolate, *this, offset));
STATIC_ASSERT(!COMPRESS_POINTERS_BOOL || kTaggedSize == kInt32Size);
}
void HeapObject::VerifySmiField(int offset) {
- CHECK(READ_FIELD(*this, offset).IsSmi());
+ CHECK(TaggedField<Object>::load(*this, offset).IsSmi());
STATIC_ASSERT(!COMPRESS_POINTERS_BOOL || kTaggedSize == kInt32Size);
}
@@ -639,7 +732,15 @@ ReadOnlyRoots HeapObject::GetReadOnlyRoots() const {
return ReadOnlyHeap::GetReadOnlyRoots(*this);
}
-Map HeapObject::map() const { return map_word().ToMap(); }
+ReadOnlyRoots HeapObject::GetReadOnlyRoots(Isolate* isolate) const {
+#ifdef V8_COMPRESS_POINTERS
+ return ReadOnlyRoots(isolate);
+#else
+ return GetReadOnlyRoots();
+#endif
+}
+
+DEF_GETTER(HeapObject, map, Map) { return map_word(isolate).ToMap(); }
void HeapObject::set_map(Map value) {
if (!value.is_null()) {
@@ -655,8 +756,8 @@ void HeapObject::set_map(Map value) {
}
}
-Map HeapObject::synchronized_map() const {
- return synchronized_map_word().ToMap();
+DEF_GETTER(HeapObject, synchronized_map, Map) {
+ return synchronized_map_word(isolate).ToMap();
}
void HeapObject::synchronized_set_map(Map value) {
@@ -693,24 +794,31 @@ void HeapObject::set_map_after_allocation(Map value, WriteBarrierMode mode) {
}
}
-MapWordSlot HeapObject::map_slot() const {
- return MapWordSlot(FIELD_ADDR(*this, kMapOffset));
+ObjectSlot HeapObject::map_slot() const {
+ return ObjectSlot(MapField::address(*this));
}
-MapWord HeapObject::map_word() const {
- return MapWord(map_slot().Relaxed_Load().ptr());
+DEF_GETTER(HeapObject, map_word, MapWord) {
+ return MapField::Relaxed_Load(isolate, *this);
}
void HeapObject::set_map_word(MapWord map_word) {
- map_slot().Relaxed_Store(Object(map_word.value_));
+ MapField::Relaxed_Store(*this, map_word);
}
-MapWord HeapObject::synchronized_map_word() const {
- return MapWord(map_slot().Acquire_Load().ptr());
+DEF_GETTER(HeapObject, synchronized_map_word, MapWord) {
+ return MapField::Acquire_Load(isolate, *this);
}
void HeapObject::synchronized_set_map_word(MapWord map_word) {
- map_slot().Release_Store(Object(map_word.value_));
+ MapField::Release_Store(*this, map_word);
+}
+
+bool HeapObject::synchronized_compare_and_swap_map_word(MapWord old_map_word,
+ MapWord new_map_word) {
+ Tagged_t result =
+ MapField::Release_CompareAndSwap(*this, old_map_word, new_map_word);
+ return result == static_cast<Tagged_t>(old_map_word.ptr());
}
int HeapObject::Size() const { return SizeFromMap(map()); }
diff --git a/deps/v8/src/objects/objects.cc b/deps/v8/src/objects/objects.cc
index 8cc22fa0e5..9963cba472 100644
--- a/deps/v8/src/objects/objects.cc
+++ b/deps/v8/src/objects/objects.cc
@@ -25,13 +25,13 @@
#include "src/builtins/builtins.h"
#include "src/codegen/compiler.h"
#include "src/common/globals.h"
+#include "src/common/message-template.h"
#include "src/date/date.h"
#include "src/debug/debug.h"
#include "src/execution/arguments.h"
#include "src/execution/execution.h"
#include "src/execution/frames-inl.h"
#include "src/execution/isolate-inl.h"
-#include "src/execution/message-template.h"
#include "src/execution/microtask-queue.h"
#include "src/heap/heap-inl.h"
#include "src/heap/read-only-heap.h"
@@ -104,7 +104,7 @@
#include "src/objects/template-objects-inl.h"
#include "src/objects/transitions-inl.h"
#include "src/parsing/preparse-data.h"
-#include "src/regexp/jsregexp.h"
+#include "src/regexp/regexp.h"
#include "src/strings/string-builder-inl.h"
#include "src/strings/string-search.h"
#include "src/strings/string-stream.h"
@@ -116,6 +116,9 @@
#include "src/wasm/wasm-objects.h"
#include "src/zone/zone.h"
+#include "torque-generated/class-definitions-tq-inl.h"
+#include "torque-generated/internal-class-definitions-tq-inl.h"
+
namespace v8 {
namespace internal {
@@ -209,8 +212,8 @@ Handle<Object> Object::WrapForRead(Isolate* isolate, Handle<Object> object,
DCHECK(object->FitsRepresentation(representation));
return object;
}
- return isolate->factory()->NewHeapNumber(
- MutableHeapNumber::cast(*object).value());
+ return isolate->factory()->NewHeapNumberFromBits(
+ MutableHeapNumber::cast(*object).value_as_bits());
}
MaybeHandle<JSReceiver> Object::ToObjectImpl(Isolate* isolate,
@@ -242,7 +245,7 @@ MaybeHandle<JSReceiver> Object::ToObjectImpl(Isolate* isolate,
isolate);
}
Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
- Handle<JSValue>::cast(result)->set_value(*object);
+ Handle<JSPrimitiveWrapper>::cast(result)->set_value(*object);
return result;
}
@@ -2387,9 +2390,9 @@ void DescriptorArray::GeneralizeAllFields() {
if (details.location() == kField) {
DCHECK_EQ(kData, details.kind());
details = details.CopyWithConstness(PropertyConstness::kMutable);
- SetValue(i, FieldType::Any());
+ SetValue(i, MaybeObject::FromObject(FieldType::Any()));
}
- set(ToDetailsIndex(i), MaybeObject::FromObject(details.AsSmi()));
+ SetDetails(i, details);
}
}
@@ -3043,27 +3046,34 @@ Maybe<bool> JSProxy::DeletePropertyOrElement(Handle<JSProxy> proxy,
}
// Enforce the invariant.
+ return JSProxy::CheckDeleteTrap(isolate, name, target);
+}
+
+Maybe<bool> JSProxy::CheckDeleteTrap(Isolate* isolate, Handle<Name> name,
+ Handle<JSReceiver> target) {
+ // 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
PropertyDescriptor target_desc;
- Maybe<bool> owned =
+ Maybe<bool> target_found =
JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
- MAYBE_RETURN(owned, Nothing<bool>());
- if (owned.FromJust()) {
+ MAYBE_RETURN(target_found, Nothing<bool>());
+ // 11. If targetDesc is undefined, return true.
+ if (target_found.FromJust()) {
+ // 12. If targetDesc.[[Configurable]] is false, throw a TypeError exception.
if (!target_desc.configurable()) {
- isolate->Throw(*factory->NewTypeError(
+ isolate->Throw(*isolate->factory()->NewTypeError(
MessageTemplate::kProxyDeletePropertyNonConfigurable, name));
return Nothing<bool>();
}
// 13. Let extensibleTarget be ? IsExtensible(target).
+ Maybe<bool> extensible_target = JSReceiver::IsExtensible(target);
+ MAYBE_RETURN(extensible_target, Nothing<bool>());
// 14. If extensibleTarget is false, throw a TypeError exception.
- Maybe<bool> extensible = JSReceiver::IsExtensible(target);
- MAYBE_RETURN(extensible, Nothing<bool>());
- if (!extensible.FromJust()) {
- isolate->Throw(*factory->NewTypeError(
+ if (!extensible_target.FromJust()) {
+ isolate->Throw(*isolate->factory()->NewTypeError(
MessageTemplate::kProxyDeletePropertyNonExtensible, name));
return Nothing<bool>();
}
}
-
return Just(true);
}
@@ -3269,7 +3279,11 @@ Maybe<bool> JSArray::ArraySetLength(Isolate* isolate, Handle<JSArray> a,
new_len_desc, should_throw);
}
// 13. If oldLenDesc.[[Writable]] is false, return false.
- if (!old_len_desc.writable()) {
+ if (!old_len_desc.writable() ||
+ // Also handle the {configurable: true} case since we later use
+ // JSArray::SetLength instead of OrdinaryDefineOwnProperty to change
+ // the length, and it doesn't have access to the descriptor anymore.
+ new_len_desc->configurable()) {
RETURN_FAILURE(isolate, GetShouldThrow(isolate, should_throw),
NewTypeError(MessageTemplate::kRedefineDisallowed,
isolate->factory()->length_string()));
@@ -4294,8 +4308,10 @@ bool DescriptorArray::IsEqualTo(DescriptorArray other) {
if (number_of_all_descriptors() != other.number_of_all_descriptors()) {
return false;
}
- for (int i = 0; i < number_of_all_descriptors(); ++i) {
- if (get(i) != other.get(i)) return false;
+ for (int i = 0; i < number_of_descriptors(); ++i) {
+ if (GetKey(i) != other.GetKey(i)) return false;
+ if (GetDetails(i).AsSmi() != other.GetDetails(i).AsSmi()) return false;
+ if (GetValue(i) != other.GetValue(i)) return false;
}
return true;
}
@@ -4500,7 +4516,8 @@ uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
return value;
}
-Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
+Handle<Object> CacheInitialJSArrayMaps(Isolate* isolate,
+ Handle<Context> native_context,
Handle<Map> initial_map) {
// Replace all of the cached initial array maps in the native context with
// the appropriate transitioned elements kind maps.
@@ -4512,13 +4529,12 @@ Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
i < kFastElementsKindCount; ++i) {
Handle<Map> new_map;
ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
- Map maybe_elements_transition = current_map->ElementsTransitionMap();
+ Map maybe_elements_transition = current_map->ElementsTransitionMap(isolate);
if (!maybe_elements_transition.is_null()) {
- new_map = handle(maybe_elements_transition, native_context->GetIsolate());
+ new_map = handle(maybe_elements_transition, isolate);
} else {
- new_map =
- Map::CopyAsElementsKind(native_context->GetIsolate(), current_map,
- next_kind, INSERT_TRANSITION);
+ new_map = Map::CopyAsElementsKind(isolate, current_map, next_kind,
+ INSERT_TRANSITION);
}
DCHECK_EQ(next_kind, new_map->elements_kind());
native_context->set(Context::ArrayMapIndex(next_kind), *new_map);
@@ -4855,22 +4871,12 @@ std::unique_ptr<v8::tracing::TracedValue> SharedFunctionInfo::ToTracedValue(
const char* SharedFunctionInfo::kTraceScope =
"v8::internal::SharedFunctionInfo";
-uint64_t SharedFunctionInfo::TraceID() const {
- // TODO(bmeurer): We use a combination of Script ID and function literal
- // ID (within the Script) to uniquely identify SharedFunctionInfos. This
- // can add significant overhead, and we should probably find a better way
- // to uniquely identify SharedFunctionInfos over time.
+uint64_t SharedFunctionInfo::TraceID(FunctionLiteral* literal) const {
+ int literal_id =
+ literal ? literal->function_literal_id() : function_literal_id();
Script script = Script::cast(this->script());
- WeakFixedArray script_functions = script.shared_function_infos();
- for (int i = 0; i < script_functions.length(); ++i) {
- HeapObject script_function;
- if (script_functions.Get(i).GetHeapObjectIfWeak(&script_function) &&
- script_function.address() == address()) {
- return (static_cast<uint64_t>(script.id() + 1) << 32) |
- (static_cast<uint64_t>(i));
- }
- }
- UNREACHABLE();
+ return (static_cast<uint64_t>(script.id() + 1) << 32) |
+ (static_cast<uint64_t>(literal_id));
}
std::unique_ptr<v8::tracing::TracedValue> SharedFunctionInfo::TraceIDRef()
@@ -4946,21 +4952,17 @@ WasmCapiFunctionData SharedFunctionInfo::wasm_capi_function_data() const {
SharedFunctionInfo::ScriptIterator::ScriptIterator(Isolate* isolate,
Script script)
- : ScriptIterator(isolate, handle(script.shared_function_infos(), isolate)) {
-}
+ : ScriptIterator(handle(script.shared_function_infos(), isolate)) {}
SharedFunctionInfo::ScriptIterator::ScriptIterator(
- Isolate* isolate, Handle<WeakFixedArray> shared_function_infos)
- : isolate_(isolate),
- shared_function_infos_(shared_function_infos),
- index_(0) {}
+ Handle<WeakFixedArray> shared_function_infos)
+ : shared_function_infos_(shared_function_infos), index_(0) {}
SharedFunctionInfo SharedFunctionInfo::ScriptIterator::Next() {
while (index_ < shared_function_infos_->length()) {
MaybeObject raw = shared_function_infos_->Get(index_++);
HeapObject heap_object;
- if (!raw->GetHeapObject(&heap_object) ||
- heap_object.IsUndefined(isolate_)) {
+ if (!raw->GetHeapObject(&heap_object) || heap_object.IsUndefined()) {
continue;
}
return SharedFunctionInfo::cast(heap_object);
@@ -4968,13 +4970,15 @@ SharedFunctionInfo SharedFunctionInfo::ScriptIterator::Next() {
return SharedFunctionInfo();
}
-void SharedFunctionInfo::ScriptIterator::Reset(Script script) {
- shared_function_infos_ = handle(script.shared_function_infos(), isolate_);
+void SharedFunctionInfo::ScriptIterator::Reset(Isolate* isolate,
+ Script script) {
+ shared_function_infos_ = handle(script.shared_function_infos(), isolate);
index_ = 0;
}
SharedFunctionInfo::GlobalIterator::GlobalIterator(Isolate* isolate)
- : script_iterator_(isolate),
+ : isolate_(isolate),
+ script_iterator_(isolate),
noscript_sfi_iterator_(isolate->heap()->noscript_shared_function_infos()),
sfi_iterator_(isolate, script_iterator_.Next()) {}
@@ -4986,7 +4990,7 @@ SharedFunctionInfo SharedFunctionInfo::GlobalIterator::Next() {
if (!next.is_null()) return SharedFunctionInfo::cast(next);
Script next_script = script_iterator_.Next();
if (next_script.is_null()) return SharedFunctionInfo();
- sfi_iterator_.Reset(next_script);
+ sfi_iterator_.Reset(isolate_, next_script);
}
}
@@ -5148,7 +5152,6 @@ void SharedFunctionInfo::DiscardCompiled(
handle(shared_info->inferred_name(), isolate);
int start_position = shared_info->StartPosition();
int end_position = shared_info->EndPosition();
- int function_literal_id = shared_info->FunctionLiteralId(isolate);
shared_info->DiscardCompiledMetadata(isolate);
@@ -5163,8 +5166,7 @@ void SharedFunctionInfo::DiscardCompiled(
// validity checks, since we're performing the unusual task of decompiling.
Handle<UncompiledData> data =
isolate->factory()->NewUncompiledDataWithoutPreparseData(
- inferred_name_val, start_position, end_position,
- function_literal_id);
+ inferred_name_val, start_position, end_position);
shared_info->set_function_data(*data);
}
}
@@ -5273,28 +5275,6 @@ bool SharedFunctionInfo::IsInlineable() {
int SharedFunctionInfo::SourceSize() { return EndPosition() - StartPosition(); }
-int SharedFunctionInfo::FindIndexInScript(Isolate* isolate) const {
- DisallowHeapAllocation no_gc;
-
- Object script_obj = script();
- if (!script_obj.IsScript()) return kFunctionLiteralIdInvalid;
-
- WeakFixedArray shared_info_list =
- Script::cast(script_obj).shared_function_infos();
- SharedFunctionInfo::ScriptIterator iterator(
- isolate,
- Handle<WeakFixedArray>(reinterpret_cast<Address*>(&shared_info_list)));
-
- for (SharedFunctionInfo shared = iterator.Next(); !shared.is_null();
- shared = iterator.Next()) {
- if (shared == *this) {
- return iterator.CurrentIndex();
- }
- }
-
- return kFunctionLiteralIdInvalid;
-}
-
// Output the source code without any allocation in the heap.
std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v) {
const SharedFunctionInfo s = v.value;
@@ -5365,6 +5345,7 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
shared_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
shared_info->set_language_mode(lit->language_mode());
shared_info->set_is_wrapped(lit->is_wrapped());
+ shared_info->set_function_literal_id(lit->function_literal_id());
// shared_info->set_kind(lit->kind());
// FunctionKind must have already been set.
DCHECK(lit->kind() == shared_info->kind());
@@ -5409,7 +5390,7 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
Handle<UncompiledData> data =
isolate->factory()->NewUncompiledDataWithPreparseData(
lit->inferred_name(), lit->start_position(), lit->end_position(),
- lit->function_literal_id(), preparse_data);
+ preparse_data);
shared_info->set_uncompiled_data(*data);
needs_position_info = false;
}
@@ -5418,8 +5399,7 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
if (needs_position_info) {
Handle<UncompiledData> data =
isolate->factory()->NewUncompiledDataWithoutPreparseData(
- lit->inferred_name(), lit->start_position(), lit->end_position(),
- lit->function_literal_id());
+ lit->inferred_name(), lit->start_position(), lit->end_position());
shared_info->set_uncompiled_data(*data);
}
}
@@ -5510,21 +5490,6 @@ int SharedFunctionInfo::EndPosition() const {
return kNoSourcePosition;
}
-int SharedFunctionInfo::FunctionLiteralId(Isolate* isolate) const {
- // Fast path for the common case when the SFI is uncompiled and so the
- // function literal id is already in the uncompiled data.
- if (HasUncompiledData() && uncompiled_data().has_function_literal_id()) {
- int id = uncompiled_data().function_literal_id();
- // Make sure the id is what we should have found with the slow path.
- DCHECK_EQ(id, FindIndexInScript(isolate));
- return id;
- }
-
- // Otherwise, search for the function in the SFI's script's function list,
- // and return its index in that list.
- return FindIndexInScript(isolate);
-}
-
void SharedFunctionInfo::SetPosition(int start_position, int end_position) {
Object maybe_scope_info = name_or_scope_info();
if (maybe_scope_info.IsScopeInfo()) {
@@ -5561,16 +5526,6 @@ void SharedFunctionInfo::EnsureSourcePositionsAvailable(
}
}
-bool BytecodeArray::IsBytecodeEqual(const BytecodeArray other) const {
- if (length() != other.length()) return false;
-
- for (int i = 0; i < length(); ++i) {
- if (get(i) != other.get(i)) return false;
- }
-
- return true;
-}
-
// static
void JSArray::Initialize(Handle<JSArray> array, int capacity, int length) {
DCHECK_GE(capacity, 0);
@@ -6128,42 +6083,14 @@ Handle<Object> JSPromise::TriggerPromiseReactions(Isolate* isolate,
namespace {
-constexpr JSRegExp::Flag kCharFlagValues[] = {
- JSRegExp::kGlobal, // g
- JSRegExp::kInvalid, // h
- JSRegExp::kIgnoreCase, // i
- JSRegExp::kInvalid, // j
- JSRegExp::kInvalid, // k
- JSRegExp::kInvalid, // l
- JSRegExp::kMultiline, // m
- JSRegExp::kInvalid, // n
- JSRegExp::kInvalid, // o
- JSRegExp::kInvalid, // p
- JSRegExp::kInvalid, // q
- JSRegExp::kInvalid, // r
- JSRegExp::kDotAll, // s
- JSRegExp::kInvalid, // t
- JSRegExp::kUnicode, // u
- JSRegExp::kInvalid, // v
- JSRegExp::kInvalid, // w
- JSRegExp::kInvalid, // x
- JSRegExp::kSticky, // y
-};
-
-constexpr JSRegExp::Flag CharToFlag(uc16 flag_char) {
- return (flag_char < 'g' || flag_char > 'y')
- ? JSRegExp::kInvalid
- : kCharFlagValues[flag_char - 'g'];
-}
-
JSRegExp::Flags RegExpFlagsFromString(Isolate* isolate, Handle<String> flags,
bool* success) {
- STATIC_ASSERT(CharToFlag('g') == JSRegExp::kGlobal);
- STATIC_ASSERT(CharToFlag('i') == JSRegExp::kIgnoreCase);
- STATIC_ASSERT(CharToFlag('m') == JSRegExp::kMultiline);
- STATIC_ASSERT(CharToFlag('s') == JSRegExp::kDotAll);
- STATIC_ASSERT(CharToFlag('u') == JSRegExp::kUnicode);
- STATIC_ASSERT(CharToFlag('y') == JSRegExp::kSticky);
+ STATIC_ASSERT(JSRegExp::FlagFromChar('g') == JSRegExp::kGlobal);
+ STATIC_ASSERT(JSRegExp::FlagFromChar('i') == JSRegExp::kIgnoreCase);
+ STATIC_ASSERT(JSRegExp::FlagFromChar('m') == JSRegExp::kMultiline);
+ STATIC_ASSERT(JSRegExp::FlagFromChar('s') == JSRegExp::kDotAll);
+ STATIC_ASSERT(JSRegExp::FlagFromChar('u') == JSRegExp::kUnicode);
+ STATIC_ASSERT(JSRegExp::FlagFromChar('y') == JSRegExp::kSticky);
int length = flags->length();
if (length == 0) {
@@ -6171,14 +6098,14 @@ JSRegExp::Flags RegExpFlagsFromString(Isolate* isolate, Handle<String> flags,
return JSRegExp::kNone;
}
// A longer flags string cannot be valid.
- if (length > JSRegExp::FlagCount()) return JSRegExp::Flags(0);
+ if (length > JSRegExp::kFlagCount) return JSRegExp::Flags(0);
// Initialize {value} to {kInvalid} to allow 2-in-1 duplicate/invalid check.
JSRegExp::Flags value = JSRegExp::kInvalid;
if (flags->IsSeqOneByteString()) {
DisallowHeapAllocation no_gc;
SeqOneByteString seq_flags = SeqOneByteString::cast(*flags);
for (int i = 0; i < length; i++) {
- JSRegExp::Flag flag = CharToFlag(seq_flags.Get(i));
+ JSRegExp::Flag flag = JSRegExp::FlagFromChar(seq_flags.Get(i));
// Duplicate or invalid flag.
if (value & flag) return JSRegExp::Flags(0);
value |= flag;
@@ -6188,7 +6115,7 @@ JSRegExp::Flags RegExpFlagsFromString(Isolate* isolate, Handle<String> flags,
DisallowHeapAllocation no_gc;
String::FlatContent flags_content = flags->GetFlatContent(no_gc);
for (int i = 0; i < length; i++) {
- JSRegExp::Flag flag = CharToFlag(flags_content.Get(i));
+ JSRegExp::Flag flag = JSRegExp::FlagFromChar(flags_content.Get(i));
// Duplicate or invalid flag.
if (value & flag) return JSRegExp::Flags(0);
value |= flag;
@@ -6224,15 +6151,20 @@ template <typename Char>
int CountRequiredEscapes(Handle<String> source) {
DisallowHeapAllocation no_gc;
int escapes = 0;
+ bool in_char_class = false;
Vector<const Char> src = source->GetCharVector<Char>(no_gc);
for (int i = 0; i < src.length(); i++) {
const Char c = src[i];
if (c == '\\') {
// Escape. Skip next character;
i++;
- } else if (c == '/') {
+ } else if (c == '/' && !in_char_class) {
// Not escaped forward-slash needs escape.
escapes++;
+ } else if (c == '[') {
+ in_char_class = true;
+ } else if (c == ']') {
+ in_char_class = false;
} else if (c == '\n') {
escapes++;
} else if (c == '\r') {
@@ -6245,6 +6177,7 @@ int CountRequiredEscapes(Handle<String> source) {
DCHECK(!unibrow::IsLineTerminator(static_cast<unibrow::uchar>(c)));
}
}
+ DCHECK(!in_char_class);
return escapes;
}
@@ -6262,16 +6195,19 @@ Handle<StringType> WriteEscapedRegExpSource(Handle<String> source,
Vector<Char> dst(result->GetChars(no_gc), result->length());
int s = 0;
int d = 0;
- // TODO(v8:1982): Fully implement
- // https://tc39.github.io/ecma262/#sec-escaperegexppattern
+ bool in_char_class = false;
while (s < src.length()) {
if (src[s] == '\\') {
// Escape. Copy this and next character.
dst[d++] = src[s++];
if (s == src.length()) break;
- } else if (src[s] == '/') {
+ } else if (src[s] == '/' && !in_char_class) {
// Not escaped forward-slash needs escape.
dst[d++] = '\\';
+ } else if (src[s] == '[') {
+ in_char_class = true;
+ } else if (src[s] == ']') {
+ in_char_class = false;
} else if (src[s] == '\n') {
WriteStringToCharVector(dst, &d, "\\n");
s++;
@@ -6292,6 +6228,7 @@ Handle<StringType> WriteEscapedRegExpSource(Handle<String> source,
dst[d++] = src[s++];
}
DCHECK_EQ(result->length(), d);
+ DCHECK(!in_char_class);
return result;
}
@@ -6348,13 +6285,13 @@ MaybeHandle<JSRegExp> JSRegExp::Initialize(Handle<JSRegExp> regexp,
source = String::Flatten(isolate, source);
+ RETURN_ON_EXCEPTION(isolate, RegExp::Compile(isolate, regexp, source, flags),
+ JSRegExp);
+
Handle<String> escaped_source;
ASSIGN_RETURN_ON_EXCEPTION(isolate, escaped_source,
EscapeRegExpSource(isolate, source), JSRegExp);
- RETURN_ON_EXCEPTION(
- isolate, RegExpImpl::Compile(isolate, regexp, source, flags), JSRegExp);
-
regexp->set_source(*escaped_source);
regexp->set_flags(Smi::FromInt(flags));
@@ -6701,8 +6638,8 @@ Handle<String> StringTable::LookupString(Isolate* isolate,
} else { // !FLAG_thin_strings
if (string->IsConsString()) {
Handle<ConsString> cons = Handle<ConsString>::cast(string);
- cons->set_first(isolate, *result);
- cons->set_second(isolate, ReadOnlyRoots(isolate).empty_string());
+ cons->set_first(*result);
+ cons->set_second(ReadOnlyRoots(isolate).empty_string());
} else if (string->IsSlicedString()) {
STATIC_ASSERT(static_cast<int>(ConsString::kSize) ==
static_cast<int>(SlicedString::kSize));
@@ -6713,8 +6650,8 @@ Handle<String> StringTable::LookupString(Isolate* isolate,
: isolate->factory()->cons_string_map();
string->set_map(*map);
Handle<ConsString> cons = Handle<ConsString>::cast(string);
- cons->set_first(isolate, *result);
- cons->set_second(isolate, ReadOnlyRoots(isolate).empty_string());
+ cons->set_first(*result);
+ cons->set_second(ReadOnlyRoots(isolate).empty_string());
}
}
return result;
@@ -7925,9 +7862,13 @@ Handle<PropertyCell> PropertyCell::PrepareForValue(
// static
void PropertyCell::SetValueWithInvalidation(Isolate* isolate,
+ const char* cell_name,
Handle<PropertyCell> cell,
Handle<Object> new_value) {
if (cell->value() != *new_value) {
+ if (FLAG_trace_protector_invalidation) {
+ isolate->TraceProtectorInvalidation(cell_name);
+ }
cell->set_value(*new_value);
cell->dependent_code().DeoptimizeDependentCodeGroup(
isolate, DependentCode::kPropertyCellChangedGroup);
@@ -8127,7 +8068,9 @@ HashTable<NameDictionary, NameDictionaryShape>::Shrink(Isolate* isolate,
int additionalCapacity);
void JSFinalizationGroup::Cleanup(
- Handle<JSFinalizationGroup> finalization_group, Isolate* isolate) {
+ Isolate* isolate, Handle<JSFinalizationGroup> finalization_group,
+ Handle<Object> cleanup) {
+ DCHECK(cleanup->IsCallable());
// It's possible that the cleared_cells list is empty, since
// FinalizationGroup.unregister() removed all its elements before this task
// ran. In that case, don't call the cleanup function.
@@ -8145,7 +8088,6 @@ void JSFinalizationGroup::Cleanup(
Handle<AllocationSite>::null()));
iterator->set_finalization_group(*finalization_group);
}
- Handle<Object> cleanup(finalization_group->cleanup(), isolate);
v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
v8::Local<v8::Value> result;
diff --git a/deps/v8/src/objects/objects.h b/deps/v8/src/objects/objects.h
index 857f3ed0f6..d706b2dfb7 100644
--- a/deps/v8/src/objects/objects.h
+++ b/deps/v8/src/objects/objects.h
@@ -15,10 +15,11 @@
#include "src/base/build_config.h"
#include "src/base/flags.h"
#include "src/base/logging.h"
+#include "src/base/memory.h"
#include "src/codegen/constants-arch.h"
#include "src/common/assert-scope.h"
#include "src/common/checks.h"
-#include "src/execution/message-template.h"
+#include "src/common/message-template.h"
#include "src/flags/flags.h"
#include "src/objects/elements-kind.h"
#include "src/objects/field-index.h"
@@ -49,22 +50,21 @@
// - JSCollection
// - JSSet
// - JSMap
-// - JSStringIterator
-// - JSSetIterator
-// - JSMapIterator
-// - JSWeakCollection
-// - JSWeakMap
-// - JSWeakSet
-// - JSRegExp
+// - JSDate
// - JSFunction
// - JSGeneratorObject
// - JSGlobalObject
// - JSGlobalProxy
-// - JSValue
-// - JSDate
+// - JSMapIterator
// - JSMessageObject
// - JSModuleNamespace
-// - JSV8BreakIterator // If V8_INTL_SUPPORT enabled.
+// - JSPrimitiveWrapper
+// - JSRegExp
+// - JSSetIterator
+// - JSStringIterator
+// - JSWeakCollection
+// - JSWeakMap
+// - JSWeakSet
// - JSCollator // If V8_INTL_SUPPORT enabled.
// - JSDateTimeFormat // If V8_INTL_SUPPORT enabled.
// - JSListFormat // If V8_INTL_SUPPORT enabled.
@@ -72,8 +72,9 @@
// - JSNumberFormat // If V8_INTL_SUPPORT enabled.
// - JSPluralRules // If V8_INTL_SUPPORT enabled.
// - JSRelativeTimeFormat // If V8_INTL_SUPPORT enabled.
-// - JSSegmentIterator // If V8_INTL_SUPPORT enabled.
// - JSSegmenter // If V8_INTL_SUPPORT enabled.
+// - JSSegmentIterator // If V8_INTL_SUPPORT enabled.
+// - JSV8BreakIterator // If V8_INTL_SUPPORT enabled.
// - WasmExceptionObject
// - WasmGlobalObject
// - WasmInstanceObject
@@ -99,7 +100,7 @@
// - TemplateList
// - TransitionArray
// - ScopeInfo
-// - ModuleInfo
+// - SourceTextModuleInfo
// - ScriptContextTable
// - ClosureFeedbackCellArray
// - FixedDoubleArray
@@ -170,7 +171,9 @@
// - PromiseRejectReactionJobTask
// - PromiseResolveThenableJobTask
// - Module
-// - ModuleInfoEntry
+// - SourceTextModule
+// - SyntheticModule
+// - SourceTextModuleInfoEntry
// - FeedbackCell
// - FeedbackVector
// - PreparseData
@@ -265,9 +268,13 @@ class Object : public TaggedImpl<HeapObjectReferenceType::STRONG, Address> {
constexpr Object() : TaggedImpl(kNullAddress) {}
explicit constexpr Object(Address ptr) : TaggedImpl(ptr) {}
-#define IS_TYPE_FUNCTION_DECL(Type) V8_INLINE bool Is##Type() const;
+#define IS_TYPE_FUNCTION_DECL(Type) \
+ V8_INLINE bool Is##Type() const; \
+ V8_INLINE bool Is##Type(Isolate* isolate) const;
OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
+ IS_TYPE_FUNCTION_DECL(HashTableBase)
+ IS_TYPE_FUNCTION_DECL(SmallOrderedHashTable)
#undef IS_TYPE_FUNCTION_DECL
// Oddball checks are faster when they are raw pointer comparisons, so the
@@ -277,18 +284,17 @@ class Object : public TaggedImpl<HeapObjectReferenceType::STRONG, Address> {
V8_INLINE bool Is##Type(ReadOnlyRoots roots) const; \
V8_INLINE bool Is##Type() const;
ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
+ IS_TYPE_FUNCTION_DECL(NullOrUndefined, /* unused */)
#undef IS_TYPE_FUNCTION_DECL
- V8_INLINE bool IsNullOrUndefined(Isolate* isolate) const;
- V8_INLINE bool IsNullOrUndefined(ReadOnlyRoots roots) const;
- V8_INLINE bool IsNullOrUndefined() const;
-
V8_INLINE bool IsZero() const;
V8_INLINE bool IsNoSharedNameSentinel() const;
enum class Conversion { kToNumber, kToNumeric };
-#define DECL_STRUCT_PREDICATE(NAME, Name, name) V8_INLINE bool Is##Name() const;
+#define DECL_STRUCT_PREDICATE(NAME, Name, name) \
+ V8_INLINE bool Is##Name() const; \
+ V8_INLINE bool Is##Name(Isolate* isolate) const;
STRUCT_LIST(DECL_STRUCT_PREDICATE)
#undef DECL_STRUCT_PREDICATE
@@ -296,9 +302,6 @@ class Object : public TaggedImpl<HeapObjectReferenceType::STRONG, Address> {
V8_INLINE
V8_WARN_UNUSED_RESULT static Maybe<bool> IsArray(Handle<Object> object);
- V8_INLINE bool IsHashTableBase() const;
- V8_INLINE bool IsSmallOrderedHashTable() const;
-
// Extract the number.
inline double Number() const;
V8_INLINE bool IsNaN() const;
@@ -306,9 +309,9 @@ class Object : public TaggedImpl<HeapObjectReferenceType::STRONG, Address> {
V8_EXPORT_PRIVATE bool ToInt32(int32_t* value);
inline bool ToUint32(uint32_t* value) const;
- inline Representation OptimalRepresentation();
+ inline Representation OptimalRepresentation(Isolate* isolate) const;
- inline ElementsKind OptimalElementsKind();
+ inline ElementsKind OptimalElementsKind(Isolate* isolate) const;
inline bool FitsRepresentation(Representation representation);
@@ -624,9 +627,9 @@ class Object : public TaggedImpl<HeapObjectReferenceType::STRONG, Address> {
#endif
if (std::is_same<T, double>::value || v8_pointer_compression_unaligned) {
// Bug(v8:8875) Double fields may be unaligned.
- return ReadUnalignedValue<T>(field_address(offset));
+ return base::ReadUnalignedValue<T>(field_address(offset));
} else {
- return Memory<T>(field_address(offset));
+ return base::Memory<T>(field_address(offset));
}
}
@@ -641,9 +644,9 @@ class Object : public TaggedImpl<HeapObjectReferenceType::STRONG, Address> {
#endif
if (std::is_same<T, double>::value || v8_pointer_compression_unaligned) {
// Bug(v8:8875) Double fields may be unaligned.
- WriteUnalignedValue<T>(field_address(offset), value);
+ base::WriteUnalignedValue<T>(field_address(offset), value);
} else {
- Memory<T>(field_address(offset)) = value;
+ base::Memory<T>(field_address(offset)) = value;
}
}
@@ -743,13 +746,13 @@ class MapWord {
// View this map word as a forwarding address.
inline HeapObject ToForwardingAddress();
- static inline MapWord FromRawValue(uintptr_t value) { return MapWord(value); }
-
- inline uintptr_t ToRawValue() { return value_; }
+ inline Address ptr() { return value_; }
private:
// HeapObject calls the private constructor and directly reads the value.
friend class HeapObject;
+ template <typename TFieldType, int kFieldOffset>
+ friend class TaggedField;
explicit MapWord(Address value) : value_(value) {}
diff --git a/deps/v8/src/objects/oddball-inl.h b/deps/v8/src/objects/oddball-inl.h
index e0d77b9043..bcca03ddca 100644
--- a/deps/v8/src/objects/oddball-inl.h
+++ b/deps/v8/src/objects/oddball-inl.h
@@ -22,7 +22,7 @@ TQ_OBJECT_CONSTRUCTORS_IMPL(Oddball)
void Oddball::set_to_number_raw_as_bits(uint64_t bits) {
// Bug(v8:8875): HeapNumber's double may be unaligned.
- WriteUnalignedValue<uint64_t>(field_address(kToNumberRawOffset), bits);
+ base::WriteUnalignedValue<uint64_t>(field_address(kToNumberRawOffset), bits);
}
byte Oddball::kind() const {
@@ -38,8 +38,8 @@ Handle<Object> Oddball::ToNumber(Isolate* isolate, Handle<Oddball> input) {
return Handle<Object>(input->to_number(), isolate);
}
-bool HeapObject::IsBoolean() const {
- return IsOddball() &&
+DEF_GETTER(HeapObject, IsBoolean, bool) {
+ return IsOddball(isolate) &&
((Oddball::cast(*this).kind() & Oddball::kNotBooleanMask) == 0);
}
diff --git a/deps/v8/src/objects/ordered-hash-table-inl.h b/deps/v8/src/objects/ordered-hash-table-inl.h
index 0eaa7567e2..a2270b0a4a 100644
--- a/deps/v8/src/objects/ordered-hash-table-inl.h
+++ b/deps/v8/src/objects/ordered-hash-table-inl.h
@@ -54,7 +54,7 @@ template <class Derived>
Object SmallOrderedHashTable<Derived>::KeyAt(int entry) const {
DCHECK_LT(entry, Capacity());
Offset entry_offset = GetDataEntryOffset(entry, Derived::kKeyIndex);
- return READ_FIELD(*this, entry_offset);
+ return TaggedField<Object>::load(*this, entry_offset);
}
template <class Derived>
@@ -63,7 +63,7 @@ Object SmallOrderedHashTable<Derived>::GetDataEntry(int entry,
DCHECK_LT(entry, Capacity());
DCHECK_LE(static_cast<unsigned>(relative_index), Derived::kEntrySize);
Offset entry_offset = GetDataEntryOffset(entry, relative_index);
- return READ_FIELD(*this, entry_offset);
+ return TaggedField<Object>::load(*this, entry_offset);
}
OBJECT_CONSTRUCTORS_IMPL(SmallOrderedHashSet,
diff --git a/deps/v8/src/objects/ordered-hash-table.cc b/deps/v8/src/objects/ordered-hash-table.cc
index c4e64d2d6a..463d0e0384 100644
--- a/deps/v8/src/objects/ordered-hash-table.cc
+++ b/deps/v8/src/objects/ordered-hash-table.cc
@@ -508,6 +508,8 @@ void SmallOrderedHashTable<Derived>::Initialize(Isolate* isolate,
SetNumberOfBuckets(num_buckets);
SetNumberOfElements(0);
SetNumberOfDeletedElements(0);
+ memset(reinterpret_cast<void*>(field_address(PaddingOffset())), 0,
+ PaddingSize());
Address hashtable_start = GetHashTableStartAddress(capacity);
memset(reinterpret_cast<byte*>(hashtable_start), kNotFound,
@@ -930,7 +932,6 @@ OrderedHashTableHandler<SmallOrderedNameDictionary,
OrderedNameDictionary>::Allocate(Isolate* isolate,
int capacity);
-#if !defined(V8_OS_WIN)
template <class SmallTable, class LargeTable>
bool OrderedHashTableHandler<SmallTable, LargeTable>::Delete(
Handle<HeapObject> table, Handle<Object> key) {
@@ -943,9 +944,7 @@ bool OrderedHashTableHandler<SmallTable, LargeTable>::Delete(
// down to a smaller hash table.
return LargeTable::Delete(Handle<LargeTable>::cast(table), key);
}
-#endif
-#if !defined(V8_OS_WIN)
template <class SmallTable, class LargeTable>
bool OrderedHashTableHandler<SmallTable, LargeTable>::HasKey(
Isolate* isolate, Handle<HeapObject> table, Handle<Object> key) {
@@ -956,7 +955,6 @@ bool OrderedHashTableHandler<SmallTable, LargeTable>::HasKey(
DCHECK(LargeTable::Is(table));
return LargeTable::HasKey(isolate, LargeTable::cast(*table), *key);
}
-#endif
template bool
OrderedHashTableHandler<SmallOrderedHashSet, OrderedHashSet>::HasKey(
diff --git a/deps/v8/src/objects/ordered-hash-table.h b/deps/v8/src/objects/ordered-hash-table.h
index a83109ed90..66dc36e81f 100644
--- a/deps/v8/src/objects/ordered-hash-table.h
+++ b/deps/v8/src/objects/ordered-hash-table.h
@@ -527,8 +527,16 @@ class SmallOrderedHashTable : public HeapObject {
return NumberOfDeletedElementsOffset() + kOneByteSize;
}
+ static constexpr Offset PaddingOffset() {
+ return NumberOfBucketsOffset() + kOneByteSize;
+ }
+
+ static constexpr size_t PaddingSize() {
+ return RoundUp<kTaggedSize>(PaddingOffset()) - PaddingOffset();
+ }
+
static constexpr Offset DataTableStartOffset() {
- return RoundUp<kTaggedSize>(NumberOfBucketsOffset());
+ return PaddingOffset() + PaddingSize();
}
static constexpr int DataTableSizeFor(int capacity) {
diff --git a/deps/v8/src/objects/property-array-inl.h b/deps/v8/src/objects/property-array-inl.h
index f23e63e50d..e9365c03a4 100644
--- a/deps/v8/src/objects/property-array-inl.h
+++ b/deps/v8/src/objects/property-array-inl.h
@@ -21,10 +21,19 @@ namespace internal {
OBJECT_CONSTRUCTORS_IMPL(PropertyArray, HeapObject)
CAST_ACCESSOR(PropertyArray)
+SMI_ACCESSORS(PropertyArray, length_and_hash, kLengthAndHashOffset)
+SYNCHRONIZED_SMI_ACCESSORS(PropertyArray, length_and_hash, kLengthAndHashOffset)
+
Object PropertyArray::get(int index) const {
+ Isolate* isolate = GetIsolateForPtrCompr(*this);
+ return get(isolate, index);
+}
+
+Object PropertyArray::get(Isolate* isolate, int index) const {
DCHECK_LT(static_cast<unsigned>(index),
static_cast<unsigned>(this->length()));
- return RELAXED_READ_FIELD(*this, OffsetOfElementAt(index));
+ return TaggedField<Object>::Relaxed_Load(isolate, *this,
+ OffsetOfElementAt(index));
}
void PropertyArray::set(int index, Object value) {
@@ -47,34 +56,24 @@ void PropertyArray::set(int index, Object value, WriteBarrierMode mode) {
ObjectSlot PropertyArray::data_start() { return RawField(kHeaderSize); }
int PropertyArray::length() const {
- Object value_obj = READ_FIELD(*this, kLengthAndHashOffset);
- int value = Smi::ToInt(value_obj);
- return LengthField::decode(value);
+ return LengthField::decode(length_and_hash());
}
void PropertyArray::initialize_length(int len) {
- DCHECK_LT(static_cast<unsigned>(len),
- static_cast<unsigned>(LengthField::kMax));
- WRITE_FIELD(*this, kLengthAndHashOffset, Smi::FromInt(len));
+ DCHECK(LengthField::is_valid(len));
+ set_length_and_hash(len);
}
int PropertyArray::synchronized_length() const {
- Object value_obj = ACQUIRE_READ_FIELD(*this, kLengthAndHashOffset);
- int value = Smi::ToInt(value_obj);
- return LengthField::decode(value);
+ return LengthField::decode(synchronized_length_and_hash());
}
-int PropertyArray::Hash() const {
- Object value_obj = READ_FIELD(*this, kLengthAndHashOffset);
- int value = Smi::ToInt(value_obj);
- return HashField::decode(value);
-}
+int PropertyArray::Hash() const { return HashField::decode(length_and_hash()); }
void PropertyArray::SetHash(int hash) {
- Object value_obj = READ_FIELD(*this, kLengthAndHashOffset);
- int value = Smi::ToInt(value_obj);
+ int value = length_and_hash();
value = HashField::update(value, hash);
- WRITE_FIELD(*this, kLengthAndHashOffset, Smi::FromInt(value));
+ set_length_and_hash(value);
}
void PropertyArray::CopyElements(Isolate* isolate, int dst_index,
diff --git a/deps/v8/src/objects/property-array.h b/deps/v8/src/objects/property-array.h
index 0c8b40ece2..5c71330280 100644
--- a/deps/v8/src/objects/property-array.h
+++ b/deps/v8/src/objects/property-array.h
@@ -30,6 +30,7 @@ class PropertyArray : public HeapObject {
inline int Hash() const;
inline Object get(int index) const;
+ inline Object get(Isolate* isolate, int index) const;
inline void set(int index, Object value);
// Setter with explicit barrier mode.
@@ -67,6 +68,11 @@ class PropertyArray : public HeapObject {
static const int kNoHashSentinel = 0;
+ private:
+ DECL_INT_ACCESSORS(length_and_hash)
+
+ DECL_SYNCHRONIZED_INT_ACCESSORS(length_and_hash)
+
OBJECT_CONSTRUCTORS(PropertyArray, HeapObject);
};
diff --git a/deps/v8/src/objects/property-cell.h b/deps/v8/src/objects/property-cell.h
index 75a5132728..b336986f62 100644
--- a/deps/v8/src/objects/property-cell.h
+++ b/deps/v8/src/objects/property-cell.h
@@ -47,7 +47,7 @@ class PropertyCell : public HeapObject {
static Handle<PropertyCell> InvalidateEntry(
Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry);
- static void SetValueWithInvalidation(Isolate* isolate,
+ static void SetValueWithInvalidation(Isolate* isolate, const char* cell_name,
Handle<PropertyCell> cell,
Handle<Object> new_value);
diff --git a/deps/v8/src/objects/property.cc b/deps/v8/src/objects/property.cc
index c226c28a76..fba6fe3405 100644
--- a/deps/v8/src/objects/property.cc
+++ b/deps/v8/src/objects/property.cc
@@ -75,9 +75,10 @@ Descriptor Descriptor::DataField(Handle<Name> key, int field_index,
Descriptor Descriptor::DataConstant(Handle<Name> key, Handle<Object> value,
PropertyAttributes attributes) {
+ Isolate* isolate = GetIsolateForPtrCompr(*key);
return Descriptor(key, MaybeObjectHandle(value), kData, attributes,
kDescriptor, PropertyConstness::kConst,
- value->OptimalRepresentation(), 0);
+ value->OptimalRepresentation(isolate), 0);
}
Descriptor Descriptor::DataConstant(Isolate* isolate, Handle<Name> key,
diff --git a/deps/v8/src/objects/prototype-inl.h b/deps/v8/src/objects/prototype-inl.h
index 5f7c3e23c5..2836186b12 100644
--- a/deps/v8/src/objects/prototype-inl.h
+++ b/deps/v8/src/objects/prototype-inl.h
@@ -48,7 +48,7 @@ PrototypeIterator::PrototypeIterator(Isolate* isolate, Map receiver_map,
if (!is_at_end_ && where_to_end_ == END_AT_NON_HIDDEN) {
DCHECK(object_.IsJSReceiver());
Map map = JSReceiver::cast(object_).map();
- is_at_end_ = !map.has_hidden_prototype();
+ is_at_end_ = !map.IsJSGlobalProxyMap();
}
}
@@ -63,7 +63,7 @@ PrototypeIterator::PrototypeIterator(Isolate* isolate, Handle<Map> receiver_map,
if (!is_at_end_ && where_to_end_ == END_AT_NON_HIDDEN) {
DCHECK(handle_->IsJSReceiver());
Map map = JSReceiver::cast(*handle_).map();
- is_at_end_ = !map.has_hidden_prototype();
+ is_at_end_ = !map.IsJSGlobalProxyMap();
}
}
@@ -96,8 +96,9 @@ void PrototypeIterator::AdvanceIgnoringProxies() {
Map map = HeapObject::cast(object).map();
HeapObject prototype = map.prototype();
- is_at_end_ = where_to_end_ == END_AT_NON_HIDDEN ? !map.has_hidden_prototype()
- : prototype.IsNull(isolate_);
+ is_at_end_ =
+ prototype.IsNull(isolate_) ||
+ (where_to_end_ == END_AT_NON_HIDDEN && !map.IsJSGlobalProxyMap());
if (handle_.is_null()) {
object_ = prototype;
diff --git a/deps/v8/src/objects/scope-info.cc b/deps/v8/src/objects/scope-info.cc
index af45e86af3..eca8bc1ecd 100644
--- a/deps/v8/src/objects/scope-info.cc
+++ b/deps/v8/src/objects/scope-info.cc
@@ -45,8 +45,9 @@ bool ScopeInfo::Equals(ScopeInfo other) const {
if (!ScopeInfo::cast(entry).Equals(ScopeInfo::cast(other_entry))) {
return false;
}
- } else if (entry.IsModuleInfo()) {
- if (!ModuleInfo::cast(entry).Equals(ModuleInfo::cast(other_entry))) {
+ } else if (entry.IsSourceTextModuleInfo()) {
+ if (!SourceTextModuleInfo::cast(entry).Equals(
+ SourceTextModuleInfo::cast(other_entry))) {
return false;
}
} else {
@@ -217,6 +218,8 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
uint32_t info =
VariableModeField::encode(var->mode()) |
InitFlagField::encode(var->initialization_flag()) |
+ RequiresBrandCheckField::encode(
+ var->get_requires_brand_check_flag()) |
MaybeAssignedFlagField::encode(var->maybe_assigned()) |
ParameterNumberField::encode(ParameterNumberField::kMax);
scope_info.set(context_local_base + local_index, *var->name(), mode);
@@ -233,6 +236,8 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
VariableModeField::encode(var->mode()) |
InitFlagField::encode(var->initialization_flag()) |
MaybeAssignedFlagField::encode(var->maybe_assigned()) |
+ RequiresBrandCheckField::encode(
+ var->get_requires_brand_check_flag()) |
ParameterNumberField::encode(ParameterNumberField::kMax);
scope_info.set(module_var_entry + kModuleVariablePropertiesOffset,
Smi::FromInt(properties));
@@ -271,6 +276,8 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
VariableModeField::encode(var->mode()) |
InitFlagField::encode(var->initialization_flag()) |
MaybeAssignedFlagField::encode(var->maybe_assigned()) |
+ RequiresBrandCheckField::encode(
+ var->get_requires_brand_check_flag()) |
ParameterNumberField::encode(ParameterNumberField::kMax);
scope_info.set(context_local_base + local_index, *var->name(), mode);
scope_info.set(context_local_info_base + local_index,
@@ -327,8 +334,8 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
// Module-specific information (only for module scopes).
if (scope->is_module_scope()) {
- Handle<ModuleInfo> module_info =
- ModuleInfo::New(isolate, zone, scope->AsModuleScope()->module());
+ 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());
@@ -444,6 +451,7 @@ Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate,
VariableModeField::encode(VariableMode::kConst) |
InitFlagField::encode(kCreatedInitialized) |
MaybeAssignedFlagField::encode(kNotAssigned) |
+ RequiresBrandCheckField::encode(kNoBrandCheck) |
ParameterNumberField::encode(ParameterNumberField::kMax);
scope_info->set(index++, Smi::FromInt(value));
}
@@ -649,9 +657,9 @@ ScopeInfo ScopeInfo::OuterScopeInfo() const {
return ScopeInfo::cast(get(OuterScopeInfoIndex()));
}
-ModuleInfo ScopeInfo::ModuleDescriptorInfo() const {
+SourceTextModuleInfo ScopeInfo::ModuleDescriptorInfo() const {
DCHECK(scope_type() == MODULE_SCOPE);
- return ModuleInfo::cast(get(ModuleInfoIndex()));
+ return SourceTextModuleInfo::cast(get(ModuleInfoIndex()));
}
String ScopeInfo::ContextLocalName(int var) const {
@@ -700,6 +708,14 @@ MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) const {
return MaybeAssignedFlagField::decode(value);
}
+RequiresBrandCheckFlag ScopeInfo::RequiresBrandCheck(int var) const {
+ DCHECK_LE(0, var);
+ DCHECK_LT(var, ContextLocalCount());
+ int info_index = ContextLocalInfosIndex() + var;
+ int value = Smi::ToInt(get(info_index));
+ return RequiresBrandCheckField::decode(value);
+}
+
// static
bool ScopeInfo::VariableIsSynthetic(String name) {
// There's currently no flag stored on the ScopeInfo to indicate that a
@@ -739,7 +755,8 @@ int ScopeInfo::ModuleIndex(String name, VariableMode* mode,
int ScopeInfo::ContextSlotIndex(ScopeInfo scope_info, String name,
VariableMode* mode,
InitializationFlag* init_flag,
- MaybeAssignedFlag* maybe_assigned_flag) {
+ MaybeAssignedFlag* maybe_assigned_flag,
+ RequiresBrandCheckFlag* requires_brand_check) {
DisallowHeapAllocation no_gc;
DCHECK(name.IsInternalizedString());
DCHECK_NOT_NULL(mode);
@@ -756,6 +773,7 @@ int ScopeInfo::ContextSlotIndex(ScopeInfo scope_info, String name,
*mode = scope_info.ContextLocalMode(var);
*init_flag = scope_info.ContextLocalInitFlag(var);
*maybe_assigned_flag = scope_info.ContextLocalMaybeAssignedFlag(var);
+ *requires_brand_check = scope_info.RequiresBrandCheck(var);
int result = Context::MIN_CONTEXT_SLOTS + var;
DCHECK_LT(result, scope_info.ContextLength());
@@ -873,15 +891,13 @@ std::ostream& operator<<(std::ostream& os,
return os;
}
-Handle<ModuleInfoEntry> ModuleInfoEntry::New(Isolate* isolate,
- Handle<Object> export_name,
- Handle<Object> local_name,
- Handle<Object> import_name,
- int module_request, int cell_index,
- int beg_pos, int end_pos) {
- Handle<ModuleInfoEntry> result =
- Handle<ModuleInfoEntry>::cast(isolate->factory()->NewStruct(
- MODULE_INFO_ENTRY_TYPE, AllocationType::kOld));
+Handle<SourceTextModuleInfoEntry> SourceTextModuleInfoEntry::New(
+ Isolate* isolate, Handle<Object> export_name, Handle<Object> local_name,
+ Handle<Object> import_name, int module_request, int cell_index, int beg_pos,
+ int end_pos) {
+ Handle<SourceTextModuleInfoEntry> result =
+ Handle<SourceTextModuleInfoEntry>::cast(isolate->factory()->NewStruct(
+ SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE, AllocationType::kOld));
result->set_export_name(*export_name);
result->set_local_name(*local_name);
result->set_import_name(*import_name);
@@ -892,8 +908,8 @@ Handle<ModuleInfoEntry> ModuleInfoEntry::New(Isolate* isolate,
return result;
}
-Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, Zone* zone,
- ModuleDescriptor* descr) {
+Handle<SourceTextModuleInfo> SourceTextModuleInfo::New(
+ Isolate* isolate, Zone* zone, SourceTextModuleDescriptor* descr) {
// Serialize module requests.
int size = static_cast<int>(descr->module_requests().size());
Handle<FixedArray> module_requests = isolate->factory()->NewFixedArray(size);
@@ -911,7 +927,8 @@ Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, Zone* zone,
{
int i = 0;
for (auto entry : descr->special_exports()) {
- Handle<ModuleInfoEntry> serialized_entry = entry->Serialize(isolate);
+ Handle<SourceTextModuleInfoEntry> serialized_entry =
+ entry->Serialize(isolate);
special_exports->set(i++, *serialized_entry);
}
}
@@ -922,7 +939,8 @@ Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, Zone* zone,
{
int i = 0;
for (auto entry : descr->namespace_imports()) {
- Handle<ModuleInfoEntry> serialized_entry = entry->Serialize(isolate);
+ Handle<SourceTextModuleInfoEntry> serialized_entry =
+ entry->Serialize(isolate);
namespace_imports->set(i++, *serialized_entry);
}
}
@@ -937,13 +955,14 @@ Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, Zone* zone,
{
int i = 0;
for (const auto& elem : descr->regular_imports()) {
- Handle<ModuleInfoEntry> serialized_entry =
+ Handle<SourceTextModuleInfoEntry> serialized_entry =
elem.second->Serialize(isolate);
regular_imports->set(i++, *serialized_entry);
}
}
- Handle<ModuleInfo> result = isolate->factory()->NewModuleInfo();
+ Handle<SourceTextModuleInfo> result =
+ isolate->factory()->NewSourceTextModuleInfo();
result->set(kModuleRequestsIndex, *module_requests);
result->set(kSpecialExportsIndex, *special_exports);
result->set(kRegularExportsIndex, *regular_exports);
@@ -953,22 +972,22 @@ Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, Zone* zone,
return result;
}
-int ModuleInfo::RegularExportCount() const {
+int SourceTextModuleInfo::RegularExportCount() const {
DCHECK_EQ(regular_exports().length() % kRegularExportLength, 0);
return regular_exports().length() / kRegularExportLength;
}
-String ModuleInfo::RegularExportLocalName(int i) const {
+String SourceTextModuleInfo::RegularExportLocalName(int i) const {
return String::cast(regular_exports().get(i * kRegularExportLength +
kRegularExportLocalNameOffset));
}
-int ModuleInfo::RegularExportCellIndex(int i) const {
+int SourceTextModuleInfo::RegularExportCellIndex(int i) const {
return Smi::ToInt(regular_exports().get(i * kRegularExportLength +
kRegularExportCellIndexOffset));
}
-FixedArray ModuleInfo::RegularExportExportNames(int i) const {
+FixedArray SourceTextModuleInfo::RegularExportExportNames(int i) const {
return FixedArray::cast(regular_exports().get(
i * kRegularExportLength + kRegularExportExportNamesOffset));
}
diff --git a/deps/v8/src/objects/scope-info.h b/deps/v8/src/objects/scope-info.h
index 8d43357631..0b8eb61b00 100644
--- a/deps/v8/src/objects/scope-info.h
+++ b/deps/v8/src/objects/scope-info.h
@@ -22,7 +22,7 @@ class Handle;
class Isolate;
template <typename T>
class MaybeHandle;
-class ModuleInfo;
+class SourceTextModuleInfo;
class Scope;
class Zone;
@@ -113,7 +113,7 @@ class ScopeInfo : public FixedArray {
int EndPosition() const;
void SetPositionInfo(int start, int end);
- ModuleInfo ModuleDescriptorInfo() const;
+ SourceTextModuleInfo ModuleDescriptorInfo() const;
// Return the name of the given context local.
String ContextLocalName(int var) const;
@@ -130,6 +130,9 @@ class ScopeInfo : public FixedArray {
// Return the initialization flag of the given context local.
MaybeAssignedFlag ContextLocalMaybeAssignedFlag(int var) const;
+ // Return whether access to the variable requries a brand check.
+ RequiresBrandCheckFlag RequiresBrandCheck(int var) const;
+
// Return true if this local was introduced by the compiler, and should not be
// exposed to the user in a debugger.
static bool VariableIsSynthetic(String name);
@@ -141,7 +144,8 @@ class ScopeInfo : public FixedArray {
// mode for that variable.
static int ContextSlotIndex(ScopeInfo scope_info, String name,
VariableMode* mode, InitializationFlag* init_flag,
- MaybeAssignedFlag* maybe_assigned_flag);
+ MaybeAssignedFlag* maybe_assigned_flag,
+ RequiresBrandCheckFlag* requires_brand_check);
// Lookup metadata of a MODULE-allocated variable. Return 0 if there is no
// module variable with the given name (the index value of a MODULE variable
@@ -284,10 +288,10 @@ class ScopeInfo : public FixedArray {
// the scope belongs to a function or script.
// 7. OuterScopeInfoIndex:
// The outer scope's ScopeInfo or the hole if there's none.
- // 8. ModuleInfo, ModuleVariableCount, and ModuleVariables:
- // For a module scope, this part contains the ModuleInfo, the number of
- // MODULE-allocated variables, and the metadata of those variables. For
- // non-module scopes it is empty.
+ // 8. 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 ReceiverInfoIndex() const;
@@ -322,8 +326,11 @@ class ScopeInfo : public FixedArray {
class VariableModeField : public BitField<VariableMode, 0, 3> {};
class InitFlagField : public BitField<InitializationFlag, 3, 1> {};
class MaybeAssignedFlagField : public BitField<MaybeAssignedFlag, 4, 1> {};
+ class RequiresBrandCheckField
+ : public BitField<RequiresBrandCheckFlag, MaybeAssignedFlagField::kNext,
+ 1> {};
class ParameterNumberField
- : public BitField<uint32_t, MaybeAssignedFlagField::kNext, 16> {};
+ : public BitField<uint32_t, RequiresBrandCheckField::kNext, 16> {};
friend class ScopeIterator;
friend std::ostream& operator<<(std::ostream& os,
diff --git a/deps/v8/src/objects/shared-function-info-inl.h b/deps/v8/src/objects/shared-function-info-inl.h
index f5413ce1de..9778db5d90 100644
--- a/deps/v8/src/objects/shared-function-info-inl.h
+++ b/deps/v8/src/objects/shared-function-info-inl.h
@@ -91,7 +91,6 @@ CAST_ACCESSOR(UncompiledData)
ACCESSORS(UncompiledData, inferred_name, String, kInferredNameOffset)
INT32_ACCESSORS(UncompiledData, start_position, kStartPositionOffset)
INT32_ACCESSORS(UncompiledData, end_position, kEndPositionOffset)
-INT32_ACCESSORS(UncompiledData, function_literal_id, kFunctionLiteralIdOffset)
void UncompiledData::clear_padding() {
if (FIELD_SIZE(kOptionalPaddingOffset) == 0) return;
@@ -106,9 +105,9 @@ CAST_ACCESSOR(UncompiledDataWithPreparseData)
ACCESSORS(UncompiledDataWithPreparseData, preparse_data, PreparseData,
kPreparseDataOffset)
-bool HeapObject::IsUncompiledData() const {
- return IsUncompiledDataWithoutPreparseData() ||
- IsUncompiledDataWithPreparseData();
+DEF_GETTER(HeapObject, IsUncompiledData, bool) {
+ return IsUncompiledDataWithoutPreparseData(isolate) ||
+ IsUncompiledDataWithPreparseData(isolate);
}
OBJECT_CONSTRUCTORS_IMPL(InterpreterData, Struct)
@@ -128,6 +127,9 @@ ACCESSORS(SharedFunctionInfo, name_or_scope_info, Object,
ACCESSORS(SharedFunctionInfo, script_or_debug_info, Object,
kScriptOrDebugInfoOffset)
+INT32_ACCESSORS(SharedFunctionInfo, function_literal_id,
+ kFunctionLiteralIdOffset)
+
#if V8_SFI_HAS_UNIQUE_ID
INT_ACCESSORS(SharedFunctionInfo, unique_id, kUniqueIdOffset)
#endif
@@ -629,7 +631,7 @@ void SharedFunctionInfo::ClearPreparseData() {
// static
void UncompiledData::Initialize(
UncompiledData data, String inferred_name, int start_position,
- int end_position, int function_literal_id,
+ int end_position,
std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
gc_notify_updated_slot) {
data.set_inferred_name(inferred_name);
@@ -637,28 +639,22 @@ void UncompiledData::Initialize(
data, data.RawField(UncompiledData::kInferredNameOffset), inferred_name);
data.set_start_position(start_position);
data.set_end_position(end_position);
- data.set_function_literal_id(function_literal_id);
data.clear_padding();
}
void UncompiledDataWithPreparseData::Initialize(
UncompiledDataWithPreparseData data, String inferred_name,
- int start_position, int end_position, int function_literal_id,
- PreparseData scope_data,
+ int start_position, int end_position, PreparseData scope_data,
std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
gc_notify_updated_slot) {
UncompiledData::Initialize(data, inferred_name, start_position, end_position,
- function_literal_id, gc_notify_updated_slot);
+ gc_notify_updated_slot);
data.set_preparse_data(scope_data);
gc_notify_updated_slot(
data, data.RawField(UncompiledDataWithPreparseData::kPreparseDataOffset),
scope_data);
}
-bool UncompiledData::has_function_literal_id() {
- return function_literal_id() != kFunctionLiteralIdInvalid;
-}
-
bool SharedFunctionInfo::HasWasmExportedFunctionData() const {
return function_data().IsWasmExportedFunctionData();
}
diff --git a/deps/v8/src/objects/shared-function-info.h b/deps/v8/src/objects/shared-function-info.h
index a3b84ee46e..f7a82964b1 100644
--- a/deps/v8/src/objects/shared-function-info.h
+++ b/deps/v8/src/objects/shared-function-info.h
@@ -104,16 +104,12 @@ class UncompiledData : public HeapObject {
DECL_ACCESSORS(inferred_name, String)
DECL_INT32_ACCESSORS(start_position)
DECL_INT32_ACCESSORS(end_position)
- DECL_INT32_ACCESSORS(function_literal_id)
-
- // Returns true if the UncompiledData contains a valid function_literal_id.
- inline bool has_function_literal_id();
DECL_CAST(UncompiledData)
inline static void Initialize(
UncompiledData data, String inferred_name, int start_position,
- int end_position, int function_literal_id,
+ int end_position,
std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
gc_notify_updated_slot =
[](HeapObject object, ObjectSlot slot, HeapObject target) {});
@@ -126,7 +122,6 @@ class UncompiledData : public HeapObject {
/* Raw data fields. */ \
V(kStartPositionOffset, kInt32Size) \
V(kEndPositionOffset, kInt32Size) \
- V(kFunctionLiteralIdOffset, kInt32Size) \
V(kOptionalPaddingOffset, POINTER_SIZE_PADDING(kOptionalPaddingOffset)) \
/* Header size. */ \
V(kSize, 0)
@@ -172,8 +167,7 @@ class UncompiledDataWithPreparseData : public UncompiledData {
inline static void Initialize(
UncompiledDataWithPreparseData data, String inferred_name,
- int start_position, int end_position, int function_literal_id,
- PreparseData scope_data,
+ int start_position, int end_position, PreparseData scope_data,
std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
gc_notify_updated_slot =
[](HeapObject object, ObjectSlot slot, HeapObject target) {});
@@ -316,6 +310,11 @@ class SharedFunctionInfo : public HeapObject {
// function. The value is only reliable when the function has been compiled.
DECL_UINT16_ACCESSORS(expected_nof_properties)
+ // [function_literal_id] - uniquely identifies the FunctionLiteral this
+ // SharedFunctionInfo represents within its script, or -1 if this
+ // SharedFunctionInfo object doesn't correspond to a parsed FunctionLiteral.
+ DECL_INT32_ACCESSORS(function_literal_id)
+
#if V8_SFI_HAS_UNIQUE_ID
// [unique_id] - For --trace-maps purposes, an identifier that's persistent
// even if the GC moves this SharedFunctionInfo.
@@ -385,9 +384,6 @@ class SharedFunctionInfo : public HeapObject {
inline bool HasInferredName();
inline String inferred_name();
- // Get the function literal id associated with this function, for parsing.
- V8_EXPORT_PRIVATE int FunctionLiteralId(Isolate* isolate) const;
-
// Break infos are contained in DebugInfo, this is a convenience method
// to simplify access.
V8_EXPORT_PRIVATE bool HasBreakInfo() const;
@@ -624,7 +620,7 @@ class SharedFunctionInfo : public HeapObject {
// Returns the unique TraceID for this SharedFunctionInfo (within the
// kTraceScope, works only for functions that have a Script and start/end
// position).
- uint64_t TraceID() const;
+ uint64_t TraceID(FunctionLiteral* literal = nullptr) const;
// Returns the unique trace ID reference for this SharedFunctionInfo
// (based on the |TraceID()| above).
@@ -634,16 +630,14 @@ class SharedFunctionInfo : public HeapObject {
class ScriptIterator {
public:
V8_EXPORT_PRIVATE ScriptIterator(Isolate* isolate, Script script);
- ScriptIterator(Isolate* isolate,
- Handle<WeakFixedArray> shared_function_infos);
+ explicit ScriptIterator(Handle<WeakFixedArray> shared_function_infos);
V8_EXPORT_PRIVATE SharedFunctionInfo Next();
int CurrentIndex() const { return index_ - 1; }
// Reset the iterator to run on |script|.
- void Reset(Script script);
+ void Reset(Isolate* isolate, Script script);
private:
- Isolate* isolate_;
Handle<WeakFixedArray> shared_function_infos_;
int index_;
DISALLOW_COPY_AND_ASSIGN(ScriptIterator);
@@ -656,6 +650,7 @@ class SharedFunctionInfo : public HeapObject {
V8_EXPORT_PRIVATE SharedFunctionInfo Next();
private:
+ Isolate* isolate_;
Script::Iterator script_iterator_;
WeakArrayList::Iterator noscript_sfi_iterator_;
SharedFunctionInfo::ScriptIterator sfi_iterator_;
@@ -744,10 +739,6 @@ class SharedFunctionInfo : public HeapObject {
friend class V8HeapExplorer;
FRIEND_TEST(PreParserTest, LazyFunctionLength);
- // Find the index of this function in the parent script. Slow path of
- // FunctionLiteralId.
- int FindIndexInScript(Isolate* isolate) const;
-
OBJECT_CONSTRUCTORS(SharedFunctionInfo, HeapObject);
};
diff --git a/deps/v8/src/objects/slots.h b/deps/v8/src/objects/slots.h
index fa8b558939..85f6525399 100644
--- a/deps/v8/src/objects/slots.h
+++ b/deps/v8/src/objects/slots.h
@@ -5,8 +5,8 @@
#ifndef V8_OBJECTS_SLOTS_H_
#define V8_OBJECTS_SLOTS_H_
+#include "src/base/memory.h"
#include "src/common/globals.h"
-#include "src/common/v8memory.h"
namespace v8 {
namespace internal {
@@ -192,11 +192,11 @@ class UnalignedSlot : public SlotBase<UnalignedSlot<T>, T, 1> {
Reference(const Reference&) V8_NOEXCEPT = default;
Reference& operator=(const Reference& other) V8_NOEXCEPT {
- WriteUnalignedValue<T>(address_, other.value());
+ base::WriteUnalignedValue<T>(address_, other.value());
return *this;
}
Reference& operator=(T value) {
- WriteUnalignedValue<T>(address_, value);
+ base::WriteUnalignedValue<T>(address_, value);
return *this;
}
@@ -206,8 +206,8 @@ class UnalignedSlot : public SlotBase<UnalignedSlot<T>, T, 1> {
void swap(Reference& other) {
T tmp = value();
- WriteUnalignedValue<T>(address_, other.value());
- WriteUnalignedValue<T>(other.address_, tmp);
+ base::WriteUnalignedValue<T>(address_, other.value());
+ base::WriteUnalignedValue<T>(other.address_, tmp);
}
bool operator<(const Reference& other) const {
@@ -219,7 +219,7 @@ class UnalignedSlot : public SlotBase<UnalignedSlot<T>, T, 1> {
}
private:
- T value() const { return ReadUnalignedValue<T>(address_); }
+ T value() const { return base::ReadUnalignedValue<T>(address_); }
Address address_;
};
diff --git a/deps/v8/src/objects/source-text-module.cc b/deps/v8/src/objects/source-text-module.cc
new file mode 100644
index 0000000000..e6637415c1
--- /dev/null
+++ b/deps/v8/src/objects/source-text-module.cc
@@ -0,0 +1,661 @@
+// Copyright 2019 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.
+
+#include "src/objects/source-text-module.h"
+
+#include "src/api/api-inl.h"
+#include "src/ast/modules.h"
+#include "src/builtins/accessors.h"
+#include "src/objects/js-generator-inl.h"
+#include "src/objects/module-inl.h"
+#include "src/objects/objects-inl.h"
+#include "src/objects/shared-function-info.h"
+#include "src/utils/ostreams.h"
+
+namespace v8 {
+namespace internal {
+
+struct StringHandleHash {
+ V8_INLINE size_t operator()(Handle<String> string) const {
+ return string->Hash();
+ }
+};
+
+struct StringHandleEqual {
+ V8_INLINE bool operator()(Handle<String> lhs, Handle<String> rhs) const {
+ return lhs->Equals(*rhs);
+ }
+};
+
+class UnorderedStringSet
+ : public std::unordered_set<Handle<String>, StringHandleHash,
+ StringHandleEqual,
+ ZoneAllocator<Handle<String>>> {
+ public:
+ explicit UnorderedStringSet(Zone* zone)
+ : std::unordered_set<Handle<String>, StringHandleHash, StringHandleEqual,
+ ZoneAllocator<Handle<String>>>(
+ 2 /* bucket count */, StringHandleHash(), StringHandleEqual(),
+ ZoneAllocator<Handle<String>>(zone)) {}
+};
+
+class UnorderedStringMap
+ : public std::unordered_map<
+ Handle<String>, Handle<Object>, StringHandleHash, StringHandleEqual,
+ ZoneAllocator<std::pair<const Handle<String>, Handle<Object>>>> {
+ public:
+ explicit UnorderedStringMap(Zone* zone)
+ : std::unordered_map<
+ Handle<String>, Handle<Object>, StringHandleHash, StringHandleEqual,
+ ZoneAllocator<std::pair<const Handle<String>, Handle<Object>>>>(
+ 2 /* bucket count */, StringHandleHash(), StringHandleEqual(),
+ ZoneAllocator<std::pair<const Handle<String>, Handle<Object>>>(
+ zone)) {}
+};
+
+class Module::ResolveSet
+ : public std::unordered_map<
+ Handle<Module>, UnorderedStringSet*, ModuleHandleHash,
+ ModuleHandleEqual,
+ ZoneAllocator<std::pair<const Handle<Module>, UnorderedStringSet*>>> {
+ public:
+ explicit ResolveSet(Zone* zone)
+ : std::unordered_map<Handle<Module>, UnorderedStringSet*,
+ ModuleHandleHash, ModuleHandleEqual,
+ ZoneAllocator<std::pair<const Handle<Module>,
+ UnorderedStringSet*>>>(
+ 2 /* bucket count */, ModuleHandleHash(), ModuleHandleEqual(),
+ ZoneAllocator<std::pair<const Handle<Module>, UnorderedStringSet*>>(
+ zone)),
+ zone_(zone) {}
+
+ Zone* zone() const { return zone_; }
+
+ private:
+ Zone* zone_;
+};
+
+SharedFunctionInfo SourceTextModule::GetSharedFunctionInfo() const {
+ DisallowHeapAllocation no_alloc;
+ DCHECK_NE(status(), Module::kEvaluating);
+ DCHECK_NE(status(), Module::kEvaluated);
+ switch (status()) {
+ case kUninstantiated:
+ case kPreInstantiating:
+ DCHECK(code().IsSharedFunctionInfo());
+ return SharedFunctionInfo::cast(code());
+ case kInstantiating:
+ DCHECK(code().IsJSFunction());
+ return JSFunction::cast(code()).shared();
+ case kInstantiated:
+ DCHECK(code().IsJSGeneratorObject());
+ return JSGeneratorObject::cast(code()).function().shared();
+ case kEvaluating:
+ case kEvaluated:
+ case kErrored:
+ UNREACHABLE();
+ }
+
+ UNREACHABLE();
+}
+
+int SourceTextModule::ExportIndex(int cell_index) {
+ DCHECK_EQ(SourceTextModuleDescriptor::GetCellIndexKind(cell_index),
+ SourceTextModuleDescriptor::kExport);
+ return cell_index - 1;
+}
+
+int SourceTextModule::ImportIndex(int cell_index) {
+ DCHECK_EQ(SourceTextModuleDescriptor::GetCellIndexKind(cell_index),
+ SourceTextModuleDescriptor::kImport);
+ return -cell_index - 1;
+}
+
+void SourceTextModule::CreateIndirectExport(
+ Isolate* isolate, Handle<SourceTextModule> module, Handle<String> name,
+ Handle<SourceTextModuleInfoEntry> entry) {
+ Handle<ObjectHashTable> exports(module->exports(), isolate);
+ DCHECK(exports->Lookup(name).IsTheHole(isolate));
+ exports = ObjectHashTable::Put(exports, name, entry);
+ module->set_exports(*exports);
+}
+
+void SourceTextModule::CreateExport(Isolate* isolate,
+ Handle<SourceTextModule> module,
+ int cell_index, Handle<FixedArray> names) {
+ DCHECK_LT(0, names->length());
+ Handle<Cell> cell =
+ isolate->factory()->NewCell(isolate->factory()->undefined_value());
+ module->regular_exports().set(ExportIndex(cell_index), *cell);
+
+ Handle<ObjectHashTable> exports(module->exports(), isolate);
+ for (int i = 0, n = names->length(); i < n; ++i) {
+ Handle<String> name(String::cast(names->get(i)), isolate);
+ DCHECK(exports->Lookup(name).IsTheHole(isolate));
+ exports = ObjectHashTable::Put(exports, name, cell);
+ }
+ module->set_exports(*exports);
+}
+
+Cell SourceTextModule::GetCell(int cell_index) {
+ DisallowHeapAllocation no_gc;
+ Object cell;
+ switch (SourceTextModuleDescriptor::GetCellIndexKind(cell_index)) {
+ case SourceTextModuleDescriptor::kImport:
+ cell = regular_imports().get(ImportIndex(cell_index));
+ break;
+ case SourceTextModuleDescriptor::kExport:
+ cell = regular_exports().get(ExportIndex(cell_index));
+ break;
+ case SourceTextModuleDescriptor::kInvalid:
+ UNREACHABLE();
+ break;
+ }
+ return Cell::cast(cell);
+}
+
+Handle<Object> SourceTextModule::LoadVariable(Isolate* isolate,
+ Handle<SourceTextModule> module,
+ int cell_index) {
+ return handle(module->GetCell(cell_index).value(), isolate);
+}
+
+void SourceTextModule::StoreVariable(Handle<SourceTextModule> module,
+ int cell_index, Handle<Object> value) {
+ DisallowHeapAllocation no_gc;
+ DCHECK_EQ(SourceTextModuleDescriptor::GetCellIndexKind(cell_index),
+ SourceTextModuleDescriptor::kExport);
+ module->GetCell(cell_index).set_value(*value);
+}
+
+MaybeHandle<Cell> SourceTextModule::ResolveExport(
+ Isolate* isolate, Handle<SourceTextModule> module,
+ Handle<String> module_specifier, Handle<String> export_name,
+ MessageLocation loc, bool must_resolve, Module::ResolveSet* resolve_set) {
+ Handle<Object> object(module->exports().Lookup(export_name), isolate);
+ if (object->IsCell()) {
+ // Already resolved (e.g. because it's a local export).
+ return Handle<Cell>::cast(object);
+ }
+
+ // Check for cycle before recursing.
+ {
+ // Attempt insertion with a null string set.
+ auto result = resolve_set->insert({module, nullptr});
+ UnorderedStringSet*& name_set = result.first->second;
+ if (result.second) {
+ // |module| wasn't in the map previously, so allocate a new name set.
+ Zone* zone = resolve_set->zone();
+ name_set =
+ new (zone->New(sizeof(UnorderedStringSet))) UnorderedStringSet(zone);
+ } else if (name_set->count(export_name)) {
+ // Cycle detected.
+ if (must_resolve) {
+ return isolate->Throw<Cell>(
+ isolate->factory()->NewSyntaxError(
+ MessageTemplate::kCyclicModuleDependency, export_name,
+ module_specifier),
+ &loc);
+ }
+ return MaybeHandle<Cell>();
+ }
+ name_set->insert(export_name);
+ }
+
+ if (object->IsSourceTextModuleInfoEntry()) {
+ // Not yet resolved indirect export.
+ Handle<SourceTextModuleInfoEntry> entry =
+ Handle<SourceTextModuleInfoEntry>::cast(object);
+ Handle<String> import_name(String::cast(entry->import_name()), isolate);
+ Handle<Script> script(module->script(), isolate);
+ MessageLocation new_loc(script, entry->beg_pos(), entry->end_pos());
+
+ Handle<Cell> cell;
+ if (!ResolveImport(isolate, module, import_name, entry->module_request(),
+ new_loc, true, resolve_set)
+ .ToHandle(&cell)) {
+ DCHECK(isolate->has_pending_exception());
+ return MaybeHandle<Cell>();
+ }
+
+ // The export table may have changed but the entry in question should be
+ // unchanged.
+ Handle<ObjectHashTable> exports(module->exports(), isolate);
+ DCHECK(exports->Lookup(export_name).IsSourceTextModuleInfoEntry());
+
+ exports = ObjectHashTable::Put(exports, export_name, cell);
+ module->set_exports(*exports);
+ return cell;
+ }
+
+ DCHECK(object->IsTheHole(isolate));
+ return SourceTextModule::ResolveExportUsingStarExports(
+ isolate, module, module_specifier, export_name, loc, must_resolve,
+ resolve_set);
+}
+
+MaybeHandle<Cell> SourceTextModule::ResolveImport(
+ Isolate* isolate, Handle<SourceTextModule> module, Handle<String> name,
+ int module_request, MessageLocation loc, bool must_resolve,
+ Module::ResolveSet* resolve_set) {
+ Handle<Module> requested_module(
+ Module::cast(module->requested_modules().get(module_request)), isolate);
+ Handle<String> specifier(
+ String::cast(module->info().module_requests().get(module_request)),
+ isolate);
+ MaybeHandle<Cell> result =
+ Module::ResolveExport(isolate, requested_module, specifier, name, loc,
+ must_resolve, resolve_set);
+ DCHECK_IMPLIES(isolate->has_pending_exception(), result.is_null());
+ return result;
+}
+
+MaybeHandle<Cell> SourceTextModule::ResolveExportUsingStarExports(
+ Isolate* isolate, Handle<SourceTextModule> module,
+ Handle<String> module_specifier, Handle<String> export_name,
+ MessageLocation loc, bool must_resolve, Module::ResolveSet* resolve_set) {
+ if (!export_name->Equals(ReadOnlyRoots(isolate).default_string())) {
+ // Go through all star exports looking for the given name. If multiple star
+ // exports provide the name, make sure they all map it to the same cell.
+ Handle<Cell> unique_cell;
+ Handle<FixedArray> special_exports(module->info().special_exports(),
+ isolate);
+ for (int i = 0, n = special_exports->length(); i < n; ++i) {
+ i::Handle<i::SourceTextModuleInfoEntry> entry(
+ i::SourceTextModuleInfoEntry::cast(special_exports->get(i)), isolate);
+ if (!entry->export_name().IsUndefined(isolate)) {
+ continue; // Indirect export.
+ }
+
+ Handle<Script> script(module->script(), isolate);
+ MessageLocation new_loc(script, entry->beg_pos(), entry->end_pos());
+
+ Handle<Cell> cell;
+ if (ResolveImport(isolate, module, export_name, entry->module_request(),
+ new_loc, false, resolve_set)
+ .ToHandle(&cell)) {
+ if (unique_cell.is_null()) unique_cell = cell;
+ if (*unique_cell != *cell) {
+ return isolate->Throw<Cell>(isolate->factory()->NewSyntaxError(
+ MessageTemplate::kAmbiguousExport,
+ module_specifier, export_name),
+ &loc);
+ }
+ } else if (isolate->has_pending_exception()) {
+ return MaybeHandle<Cell>();
+ }
+ }
+
+ if (!unique_cell.is_null()) {
+ // Found a unique star export for this name.
+ Handle<ObjectHashTable> exports(module->exports(), isolate);
+ DCHECK(exports->Lookup(export_name).IsTheHole(isolate));
+ exports = ObjectHashTable::Put(exports, export_name, unique_cell);
+ module->set_exports(*exports);
+ return unique_cell;
+ }
+ }
+
+ // Unresolvable.
+ if (must_resolve) {
+ return isolate->Throw<Cell>(
+ isolate->factory()->NewSyntaxError(MessageTemplate::kUnresolvableExport,
+ module_specifier, export_name),
+ &loc);
+ }
+ return MaybeHandle<Cell>();
+}
+
+bool SourceTextModule::PrepareInstantiate(
+ Isolate* isolate, Handle<SourceTextModule> module,
+ v8::Local<v8::Context> context, v8::Module::ResolveCallback callback) {
+ // Obtain requested modules.
+ Handle<SourceTextModuleInfo> module_info(module->info(), isolate);
+ Handle<FixedArray> module_requests(module_info->module_requests(), isolate);
+ Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
+ for (int i = 0, length = module_requests->length(); i < length; ++i) {
+ Handle<String> specifier(String::cast(module_requests->get(i)), isolate);
+ v8::Local<v8::Module> api_requested_module;
+ if (!callback(context, v8::Utils::ToLocal(specifier),
+ v8::Utils::ToLocal(Handle<Module>::cast(module)))
+ .ToLocal(&api_requested_module)) {
+ isolate->PromoteScheduledException();
+ return false;
+ }
+ Handle<Module> requested_module = Utils::OpenHandle(*api_requested_module);
+ requested_modules->set(i, *requested_module);
+ }
+
+ // Recurse.
+ for (int i = 0, length = requested_modules->length(); i < length; ++i) {
+ Handle<Module> requested_module(Module::cast(requested_modules->get(i)),
+ isolate);
+ if (!Module::PrepareInstantiate(isolate, requested_module, context,
+ callback)) {
+ return false;
+ }
+ }
+
+ // Set up local exports.
+ // TODO(neis): Create regular_exports array here instead of in factory method?
+ for (int i = 0, n = module_info->RegularExportCount(); i < n; ++i) {
+ int cell_index = module_info->RegularExportCellIndex(i);
+ Handle<FixedArray> export_names(module_info->RegularExportExportNames(i),
+ isolate);
+ CreateExport(isolate, module, cell_index, export_names);
+ }
+
+ // Partially set up indirect exports.
+ // For each indirect export, we create the appropriate slot in the export
+ // table and store its SourceTextModuleInfoEntry there. When we later find
+ // the correct Cell in the module that actually provides the value, we replace
+ // the SourceTextModuleInfoEntry by that Cell (see ResolveExport).
+ Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
+ for (int i = 0, n = special_exports->length(); i < n; ++i) {
+ Handle<SourceTextModuleInfoEntry> entry(
+ SourceTextModuleInfoEntry::cast(special_exports->get(i)), isolate);
+ Handle<Object> export_name(entry->export_name(), isolate);
+ if (export_name->IsUndefined(isolate)) continue; // Star export.
+ CreateIndirectExport(isolate, module, Handle<String>::cast(export_name),
+ entry);
+ }
+
+ DCHECK_EQ(module->status(), kPreInstantiating);
+ return true;
+}
+
+bool SourceTextModule::RunInitializationCode(Isolate* isolate,
+ Handle<SourceTextModule> module) {
+ DCHECK_EQ(module->status(), kInstantiating);
+ Handle<JSFunction> function(JSFunction::cast(module->code()), isolate);
+ DCHECK_EQ(MODULE_SCOPE, function->shared().scope_info().scope_type());
+ Handle<Object> receiver = isolate->factory()->undefined_value();
+ Handle<Object> argv[] = {module};
+ MaybeHandle<Object> maybe_generator =
+ Execution::Call(isolate, function, receiver, arraysize(argv), argv);
+ Handle<Object> generator;
+ if (!maybe_generator.ToHandle(&generator)) {
+ DCHECK(isolate->has_pending_exception());
+ return false;
+ }
+ DCHECK_EQ(*function, Handle<JSGeneratorObject>::cast(generator)->function());
+ module->set_code(*generator);
+ return true;
+}
+
+bool SourceTextModule::MaybeTransitionComponent(
+ Isolate* isolate, Handle<SourceTextModule> module,
+ ZoneForwardList<Handle<SourceTextModule>>* stack, Status new_status) {
+ DCHECK(new_status == kInstantiated || new_status == kEvaluated);
+ SLOW_DCHECK(
+ // {module} is on the {stack}.
+ std::count_if(stack->begin(), stack->end(),
+ [&](Handle<Module> m) { return *m == *module; }) == 1);
+ DCHECK_LE(module->dfs_ancestor_index(), module->dfs_index());
+ if (module->dfs_ancestor_index() == module->dfs_index()) {
+ // This is the root of its strongly connected component.
+ Handle<SourceTextModule> ancestor;
+ do {
+ ancestor = stack->front();
+ stack->pop_front();
+ DCHECK_EQ(ancestor->status(),
+ new_status == kInstantiated ? kInstantiating : kEvaluating);
+ if (new_status == kInstantiated) {
+ if (!SourceTextModule::RunInitializationCode(isolate, ancestor))
+ return false;
+ }
+ ancestor->SetStatus(new_status);
+ } while (*ancestor != *module);
+ }
+ return true;
+}
+
+bool SourceTextModule::FinishInstantiate(
+ Isolate* isolate, Handle<SourceTextModule> module,
+ ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index,
+ Zone* zone) {
+ // Instantiate SharedFunctionInfo and mark module as instantiating for
+ // the recursion.
+ Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(module->code()),
+ isolate);
+ Handle<JSFunction> function =
+ isolate->factory()->NewFunctionFromSharedFunctionInfo(
+ shared, isolate->native_context());
+ module->set_code(*function);
+ module->SetStatus(kInstantiating);
+ module->set_dfs_index(*dfs_index);
+ module->set_dfs_ancestor_index(*dfs_index);
+ stack->push_front(module);
+ (*dfs_index)++;
+
+ // Recurse.
+ Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
+ for (int i = 0, length = requested_modules->length(); i < length; ++i) {
+ Handle<Module> requested_module(Module::cast(requested_modules->get(i)),
+ isolate);
+ if (!Module::FinishInstantiate(isolate, requested_module, stack, dfs_index,
+ zone)) {
+ return false;
+ }
+
+ DCHECK_NE(requested_module->status(), kEvaluating);
+ DCHECK_GE(requested_module->status(), kInstantiating);
+ SLOW_DCHECK(
+ // {requested_module} is instantiating iff it's on the {stack}.
+ (requested_module->status() == kInstantiating) ==
+ std::count_if(stack->begin(), stack->end(), [&](Handle<Module> m) {
+ return *m == *requested_module;
+ }));
+
+ if (requested_module->status() == kInstantiating) {
+ // SyntheticModules go straight to kInstantiated so this must be a
+ // SourceTextModule
+ module->set_dfs_ancestor_index(
+ std::min(module->dfs_ancestor_index(),
+ Handle<SourceTextModule>::cast(requested_module)
+ ->dfs_ancestor_index()));
+ }
+ }
+
+ Handle<Script> script(module->script(), isolate);
+ Handle<SourceTextModuleInfo> module_info(module->info(), isolate);
+
+ // Resolve imports.
+ Handle<FixedArray> regular_imports(module_info->regular_imports(), isolate);
+ for (int i = 0, n = regular_imports->length(); i < n; ++i) {
+ Handle<SourceTextModuleInfoEntry> entry(
+ SourceTextModuleInfoEntry::cast(regular_imports->get(i)), isolate);
+ Handle<String> name(String::cast(entry->import_name()), isolate);
+ MessageLocation loc(script, entry->beg_pos(), entry->end_pos());
+ ResolveSet resolve_set(zone);
+ Handle<Cell> cell;
+ if (!ResolveImport(isolate, module, name, entry->module_request(), loc,
+ true, &resolve_set)
+ .ToHandle(&cell)) {
+ return false;
+ }
+ module->regular_imports().set(ImportIndex(entry->cell_index()), *cell);
+ }
+
+ // Resolve indirect exports.
+ Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
+ for (int i = 0, n = special_exports->length(); i < n; ++i) {
+ Handle<SourceTextModuleInfoEntry> entry(
+ SourceTextModuleInfoEntry::cast(special_exports->get(i)), isolate);
+ Handle<Object> name(entry->export_name(), isolate);
+ if (name->IsUndefined(isolate)) continue; // Star export.
+ MessageLocation loc(script, entry->beg_pos(), entry->end_pos());
+ ResolveSet resolve_set(zone);
+ if (ResolveExport(isolate, module, Handle<String>(),
+ Handle<String>::cast(name), loc, true, &resolve_set)
+ .is_null()) {
+ return false;
+ }
+ }
+
+ return MaybeTransitionComponent(isolate, module, stack, kInstantiated);
+}
+
+void SourceTextModule::FetchStarExports(Isolate* isolate,
+ Handle<SourceTextModule> module,
+ Zone* zone,
+ UnorderedModuleSet* visited) {
+ DCHECK_GE(module->status(), Module::kInstantiating);
+
+ if (module->module_namespace().IsJSModuleNamespace()) return; // Shortcut.
+
+ bool cycle = !visited->insert(module).second;
+ if (cycle) return;
+ Handle<ObjectHashTable> exports(module->exports(), isolate);
+ UnorderedStringMap more_exports(zone);
+
+ // TODO(neis): Only allocate more_exports if there are star exports.
+ // Maybe split special_exports into indirect_exports and star_exports.
+
+ ReadOnlyRoots roots(isolate);
+ Handle<FixedArray> special_exports(module->info().special_exports(), isolate);
+ for (int i = 0, n = special_exports->length(); i < n; ++i) {
+ Handle<SourceTextModuleInfoEntry> entry(
+ SourceTextModuleInfoEntry::cast(special_exports->get(i)), isolate);
+ if (!entry->export_name().IsUndefined(roots)) {
+ continue; // Indirect export.
+ }
+
+ Handle<Module> requested_module(
+ Module::cast(module->requested_modules().get(entry->module_request())),
+ isolate);
+
+ // Recurse.
+ if (requested_module->IsSourceTextModule())
+ FetchStarExports(isolate,
+ Handle<SourceTextModule>::cast(requested_module), zone,
+ visited);
+
+ // Collect all of [requested_module]'s exports that must be added to
+ // [module]'s exports (i.e. to [exports]). We record these in
+ // [more_exports]. Ambiguities (conflicting exports) are marked by mapping
+ // the name to undefined instead of a Cell.
+ Handle<ObjectHashTable> requested_exports(requested_module->exports(),
+ isolate);
+ for (int i = 0, n = requested_exports->Capacity(); i < n; ++i) {
+ Object key;
+ if (!requested_exports->ToKey(roots, i, &key)) continue;
+ Handle<String> name(String::cast(key), isolate);
+
+ if (name->Equals(roots.default_string())) continue;
+ if (!exports->Lookup(name).IsTheHole(roots)) continue;
+
+ Handle<Cell> cell(Cell::cast(requested_exports->ValueAt(i)), isolate);
+ auto insert_result = more_exports.insert(std::make_pair(name, cell));
+ if (!insert_result.second) {
+ auto it = insert_result.first;
+ if (*it->second == *cell || it->second->IsUndefined(roots)) {
+ // We already recorded this mapping before, or the name is already
+ // known to be ambiguous. In either case, there's nothing to do.
+ } else {
+ DCHECK(it->second->IsCell());
+ // Different star exports provide different cells for this name, hence
+ // mark the name as ambiguous.
+ it->second = roots.undefined_value_handle();
+ }
+ }
+ }
+ }
+
+ // Copy [more_exports] into [exports].
+ for (const auto& elem : more_exports) {
+ if (elem.second->IsUndefined(isolate)) continue; // Ambiguous export.
+ DCHECK(!elem.first->Equals(ReadOnlyRoots(isolate).default_string()));
+ DCHECK(elem.second->IsCell());
+ exports = ObjectHashTable::Put(exports, elem.first, elem.second);
+ }
+ module->set_exports(*exports);
+}
+
+Handle<JSModuleNamespace> SourceTextModule::GetModuleNamespace(
+ Isolate* isolate, Handle<SourceTextModule> module, int module_request) {
+ Handle<Module> requested_module(
+ Module::cast(module->requested_modules().get(module_request)), isolate);
+ return Module::GetModuleNamespace(isolate, requested_module);
+}
+
+MaybeHandle<Object> SourceTextModule::Evaluate(
+ Isolate* isolate, Handle<SourceTextModule> module,
+ ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index) {
+ Handle<JSGeneratorObject> generator(JSGeneratorObject::cast(module->code()),
+ isolate);
+ module->set_code(
+ generator->function().shared().scope_info().ModuleDescriptorInfo());
+ module->SetStatus(kEvaluating);
+ module->set_dfs_index(*dfs_index);
+ module->set_dfs_ancestor_index(*dfs_index);
+ stack->push_front(module);
+ (*dfs_index)++;
+
+ // Recursion.
+ Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
+ for (int i = 0, length = requested_modules->length(); i < length; ++i) {
+ Handle<Module> requested_module(Module::cast(requested_modules->get(i)),
+ isolate);
+ RETURN_ON_EXCEPTION(
+ isolate, Module::Evaluate(isolate, requested_module, stack, dfs_index),
+ Object);
+
+ DCHECK_GE(requested_module->status(), kEvaluating);
+ DCHECK_NE(requested_module->status(), kErrored);
+ SLOW_DCHECK(
+ // {requested_module} is evaluating iff it's on the {stack}.
+ (requested_module->status() == kEvaluating) ==
+ std::count_if(stack->begin(), stack->end(), [&](Handle<Module> m) {
+ return *m == *requested_module;
+ }));
+
+ if (requested_module->status() == kEvaluating) {
+ // SyntheticModules go straight to kEvaluated so this must be a
+ // SourceTextModule
+ module->set_dfs_ancestor_index(
+ std::min(module->dfs_ancestor_index(),
+ Handle<SourceTextModule>::cast(requested_module)
+ ->dfs_ancestor_index()));
+ }
+ }
+
+ // Evaluation of module body.
+ Handle<JSFunction> resume(
+ isolate->native_context()->generator_next_internal(), isolate);
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result, Execution::Call(isolate, resume, generator, 0, nullptr),
+ Object);
+ DCHECK(JSIteratorResult::cast(*result).done().BooleanValue(isolate));
+
+ CHECK(MaybeTransitionComponent(isolate, module, stack, kEvaluated));
+ return handle(JSIteratorResult::cast(*result).value(), isolate);
+}
+
+void SourceTextModule::Reset(Isolate* isolate,
+ Handle<SourceTextModule> module) {
+ Factory* factory = isolate->factory();
+
+ DCHECK(module->import_meta().IsTheHole(isolate));
+
+ Handle<FixedArray> regular_exports =
+ factory->NewFixedArray(module->regular_exports().length());
+ Handle<FixedArray> regular_imports =
+ factory->NewFixedArray(module->regular_imports().length());
+ Handle<FixedArray> requested_modules =
+ factory->NewFixedArray(module->requested_modules().length());
+
+ if (module->status() == kInstantiating) {
+ module->set_code(JSFunction::cast(module->code()).shared());
+ }
+ module->set_regular_exports(*regular_exports);
+ module->set_regular_imports(*regular_imports);
+ module->set_requested_modules(*requested_modules);
+ module->set_dfs_index(-1);
+ module->set_dfs_ancestor_index(-1);
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/src/objects/source-text-module.h b/deps/v8/src/objects/source-text-module.h
new file mode 100644
index 0000000000..5c20b7018b
--- /dev/null
+++ b/deps/v8/src/objects/source-text-module.h
@@ -0,0 +1,220 @@
+// Copyright 2019 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_SOURCE_TEXT_MODULE_H_
+#define V8_OBJECTS_SOURCE_TEXT_MODULE_H_
+
+#include "src/objects/module.h"
+
+// Has to be the last include (doesn't have include guards):
+#include "src/objects/object-macros.h"
+
+namespace v8 {
+namespace internal {
+
+class UnorderedModuleSet;
+
+// The runtime representation of an ECMAScript Source Text Module Record.
+// https://tc39.github.io/ecma262/#sec-source-text-module-records
+class SourceTextModule : public Module {
+ public:
+ NEVER_READ_ONLY_SPACE
+ DECL_CAST(SourceTextModule)
+ DECL_VERIFIER(SourceTextModule)
+ DECL_PRINTER(SourceTextModule)
+
+ // The code representing this module, or an abstraction thereof.
+ // This is either a SharedFunctionInfo, a JSFunction, a JSGeneratorObject, or
+ // a SourceTextModuleInfo, depending on the state (status) the module is in.
+ // See SourceTextModule::SourceTextModuleVerify() for the precise invariant.
+ DECL_ACCESSORS(code, Object)
+
+ // Arrays of cells corresponding to regular exports and regular imports.
+ // A cell's position in the array is determined by the cell index of the
+ // associated module entry (which coincides with the variable index of the
+ // associated variable).
+ DECL_ACCESSORS(regular_exports, FixedArray)
+ DECL_ACCESSORS(regular_imports, FixedArray)
+
+ // The shared function info in case {status} is not kEvaluating, kEvaluated or
+ // kErrored.
+ SharedFunctionInfo GetSharedFunctionInfo() const;
+
+ // Modules imported or re-exported by this module.
+ // Corresponds 1-to-1 to the module specifier strings in
+ // SourceTextModuleInfo::module_requests.
+ DECL_ACCESSORS(requested_modules, FixedArray)
+
+ // [script]: Script from which the module originates.
+ DECL_ACCESSORS(script, Script)
+
+ // The value of import.meta inside of this module.
+ // Lazily initialized on first access. It's the hole before first access and
+ // a JSObject afterwards.
+ DECL_ACCESSORS(import_meta, Object)
+
+ // Get the SourceTextModuleInfo associated with the code.
+ inline SourceTextModuleInfo info() const;
+
+ Cell GetCell(int cell_index);
+ static Handle<Object> LoadVariable(Isolate* isolate,
+ Handle<SourceTextModule> module,
+ int cell_index);
+ static void StoreVariable(Handle<SourceTextModule> module, int cell_index,
+ Handle<Object> value);
+
+ static int ImportIndex(int cell_index);
+ static int ExportIndex(int cell_index);
+
+ // Get the namespace object for [module_request] of [module]. If it doesn't
+ // exist yet, it is created.
+ static Handle<JSModuleNamespace> GetModuleNamespace(
+ Isolate* isolate, Handle<SourceTextModule> module, int module_request);
+
+ // Layout description.
+ DEFINE_FIELD_OFFSET_CONSTANTS(Module::kHeaderSize,
+ TORQUE_GENERATED_SOURCE_TEXT_MODULE_FIELDS)
+
+ using BodyDescriptor =
+ SubclassBodyDescriptor<Module::BodyDescriptor,
+ FixedBodyDescriptor<kCodeOffset, kSize, kSize>>;
+
+ private:
+ friend class Factory;
+ friend class Module;
+
+ // TODO(neis): Don't store those in the module object?
+ DECL_INT_ACCESSORS(dfs_index)
+ DECL_INT_ACCESSORS(dfs_ancestor_index)
+
+ // Helpers for Instantiate and Evaluate.
+
+ static void CreateExport(Isolate* isolate, Handle<SourceTextModule> module,
+ int cell_index, Handle<FixedArray> names);
+ static void CreateIndirectExport(Isolate* isolate,
+ Handle<SourceTextModule> module,
+ Handle<String> name,
+ Handle<SourceTextModuleInfoEntry> entry);
+
+ static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveExport(
+ Isolate* isolate, Handle<SourceTextModule> module,
+ Handle<String> module_specifier, Handle<String> export_name,
+ MessageLocation loc, bool must_resolve, ResolveSet* resolve_set);
+ static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveImport(
+ Isolate* isolate, Handle<SourceTextModule> module, Handle<String> name,
+ int module_request, MessageLocation loc, bool must_resolve,
+ ResolveSet* resolve_set);
+
+ static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveExportUsingStarExports(
+ Isolate* isolate, Handle<SourceTextModule> module,
+ Handle<String> module_specifier, Handle<String> export_name,
+ MessageLocation loc, bool must_resolve, ResolveSet* resolve_set);
+
+ static V8_WARN_UNUSED_RESULT bool PrepareInstantiate(
+ Isolate* isolate, Handle<SourceTextModule> module,
+ v8::Local<v8::Context> context, v8::Module::ResolveCallback callback);
+ static V8_WARN_UNUSED_RESULT bool FinishInstantiate(
+ Isolate* isolate, Handle<SourceTextModule> module,
+ ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index,
+ Zone* zone);
+ static V8_WARN_UNUSED_RESULT bool RunInitializationCode(
+ Isolate* isolate, Handle<SourceTextModule> module);
+
+ static void FetchStarExports(Isolate* isolate,
+ Handle<SourceTextModule> module, Zone* zone,
+ UnorderedModuleSet* visited);
+
+ static V8_WARN_UNUSED_RESULT MaybeHandle<Object> Evaluate(
+ Isolate* isolate, Handle<SourceTextModule> module,
+ ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index);
+
+ static V8_WARN_UNUSED_RESULT bool MaybeTransitionComponent(
+ Isolate* isolate, Handle<SourceTextModule> module,
+ ZoneForwardList<Handle<SourceTextModule>>* stack, Status new_status);
+
+ static void Reset(Isolate* isolate, Handle<SourceTextModule> module);
+
+ OBJECT_CONSTRUCTORS(SourceTextModule, Module);
+};
+
+// SourceTextModuleInfo is to SourceTextModuleDescriptor what ScopeInfo is to
+// Scope.
+class SourceTextModuleInfo : public FixedArray {
+ public:
+ DECL_CAST(SourceTextModuleInfo)
+
+ static Handle<SourceTextModuleInfo> New(Isolate* isolate, Zone* zone,
+ SourceTextModuleDescriptor* descr);
+
+ inline FixedArray module_requests() const;
+ inline FixedArray special_exports() const;
+ inline FixedArray regular_exports() const;
+ inline FixedArray regular_imports() const;
+ inline FixedArray namespace_imports() const;
+ inline FixedArray module_request_positions() const;
+
+ // Accessors for [regular_exports].
+ int RegularExportCount() const;
+ String RegularExportLocalName(int i) const;
+ int RegularExportCellIndex(int i) const;
+ FixedArray RegularExportExportNames(int i) const;
+
+#ifdef DEBUG
+ inline bool Equals(SourceTextModuleInfo other) const;
+#endif
+
+ private:
+ friend class Factory;
+ friend class SourceTextModuleDescriptor;
+ enum {
+ kModuleRequestsIndex,
+ kSpecialExportsIndex,
+ kRegularExportsIndex,
+ kNamespaceImportsIndex,
+ kRegularImportsIndex,
+ kModuleRequestPositionsIndex,
+ kLength
+ };
+ enum {
+ kRegularExportLocalNameOffset,
+ kRegularExportCellIndexOffset,
+ kRegularExportExportNamesOffset,
+ kRegularExportLength
+ };
+
+ OBJECT_CONSTRUCTORS(SourceTextModuleInfo, FixedArray);
+};
+
+class SourceTextModuleInfoEntry : public Struct {
+ public:
+ DECL_CAST(SourceTextModuleInfoEntry)
+ DECL_PRINTER(SourceTextModuleInfoEntry)
+ DECL_VERIFIER(SourceTextModuleInfoEntry)
+
+ DECL_ACCESSORS(export_name, Object)
+ DECL_ACCESSORS(local_name, Object)
+ DECL_ACCESSORS(import_name, Object)
+ DECL_INT_ACCESSORS(module_request)
+ DECL_INT_ACCESSORS(cell_index)
+ DECL_INT_ACCESSORS(beg_pos)
+ DECL_INT_ACCESSORS(end_pos)
+
+ static Handle<SourceTextModuleInfoEntry> New(
+ Isolate* isolate, Handle<Object> export_name, Handle<Object> local_name,
+ Handle<Object> import_name, int module_request, int cell_index,
+ int beg_pos, int end_pos);
+
+ DEFINE_FIELD_OFFSET_CONSTANTS(
+ Struct::kHeaderSize,
+ TORQUE_GENERATED_SOURCE_TEXT_MODULE_INFO_ENTRY_FIELDS)
+
+ OBJECT_CONSTRUCTORS(SourceTextModuleInfoEntry, Struct);
+};
+
+} // namespace internal
+} // namespace v8
+
+#include "src/objects/object-macros-undef.h"
+
+#endif // V8_OBJECTS_SOURCE_TEXT_MODULE_H_
diff --git a/deps/v8/src/objects/stack-frame-info-inl.h b/deps/v8/src/objects/stack-frame-info-inl.h
index 8069e6e5c9..e72af4df94 100644
--- a/deps/v8/src/objects/stack-frame-info-inl.h
+++ b/deps/v8/src/objects/stack-frame-info-inl.h
@@ -32,11 +32,15 @@ ACCESSORS(StackFrameInfo, script_name, Object, kScriptNameOffset)
ACCESSORS(StackFrameInfo, script_name_or_source_url, Object,
kScriptNameOrSourceUrlOffset)
ACCESSORS(StackFrameInfo, function_name, Object, kFunctionNameOffset)
+ACCESSORS(StackFrameInfo, method_name, Object, kMethodNameOffset)
+ACCESSORS(StackFrameInfo, type_name, Object, kTypeNameOffset)
+ACCESSORS(StackFrameInfo, eval_origin, Object, kEvalOriginOffset)
ACCESSORS(StackFrameInfo, wasm_module_name, Object, kWasmModuleNameOffset)
SMI_ACCESSORS(StackFrameInfo, flag, kFlagOffset)
BOOL_ACCESSORS(StackFrameInfo, flag, is_eval, kIsEvalBit)
BOOL_ACCESSORS(StackFrameInfo, flag, is_constructor, kIsConstructorBit)
BOOL_ACCESSORS(StackFrameInfo, flag, is_wasm, kIsWasmBit)
+BOOL_ACCESSORS(StackFrameInfo, flag, is_asmjs_wasm, kIsAsmJsWasmBit)
BOOL_ACCESSORS(StackFrameInfo, flag, is_user_java_script, kIsUserJavaScriptBit)
BOOL_ACCESSORS(StackFrameInfo, flag, is_toplevel, kIsToplevelBit)
BOOL_ACCESSORS(StackFrameInfo, flag, is_async, kIsAsyncBit)
diff --git a/deps/v8/src/objects/stack-frame-info.cc b/deps/v8/src/objects/stack-frame-info.cc
index f427d7eae2..558449d85a 100644
--- a/deps/v8/src/objects/stack-frame-info.cc
+++ b/deps/v8/src/objects/stack-frame-info.cc
@@ -5,85 +5,144 @@
#include "src/objects/stack-frame-info.h"
#include "src/objects/stack-frame-info-inl.h"
+#include "src/strings/string-builder-inl.h"
namespace v8 {
namespace internal {
+// static
int StackTraceFrame::GetLineNumber(Handle<StackTraceFrame> frame) {
int line = GetFrameInfo(frame)->line_number();
return line != StackFrameBase::kNone ? line : Message::kNoLineNumberInfo;
}
+// static
+int StackTraceFrame::GetOneBasedLineNumber(Handle<StackTraceFrame> frame) {
+ // JavaScript line numbers are already 1-based. Wasm line numbers need
+ // to be adjusted.
+ int line = StackTraceFrame::GetLineNumber(frame);
+ if (StackTraceFrame::IsWasm(frame) && line >= 0) line++;
+ return line;
+}
+
+// static
int StackTraceFrame::GetColumnNumber(Handle<StackTraceFrame> frame) {
int column = GetFrameInfo(frame)->column_number();
return column != StackFrameBase::kNone ? column : Message::kNoColumnInfo;
}
+// static
+int StackTraceFrame::GetOneBasedColumnNumber(Handle<StackTraceFrame> frame) {
+ // JavaScript colun numbers are already 1-based. Wasm column numbers need
+ // to be adjusted.
+ int column = StackTraceFrame::GetColumnNumber(frame);
+ if (StackTraceFrame::IsWasm(frame) && column >= 0) column++;
+ return column;
+}
+
+// static
int StackTraceFrame::GetScriptId(Handle<StackTraceFrame> frame) {
int id = GetFrameInfo(frame)->script_id();
return id != StackFrameBase::kNone ? id : Message::kNoScriptIdInfo;
}
+// static
int StackTraceFrame::GetPromiseAllIndex(Handle<StackTraceFrame> frame) {
return GetFrameInfo(frame)->promise_all_index();
}
+// static
Handle<Object> StackTraceFrame::GetFileName(Handle<StackTraceFrame> frame) {
auto name = GetFrameInfo(frame)->script_name();
return handle(name, frame->GetIsolate());
}
+// static
Handle<Object> StackTraceFrame::GetScriptNameOrSourceUrl(
Handle<StackTraceFrame> frame) {
auto name = GetFrameInfo(frame)->script_name_or_source_url();
return handle(name, frame->GetIsolate());
}
+// static
Handle<Object> StackTraceFrame::GetFunctionName(Handle<StackTraceFrame> frame) {
auto name = GetFrameInfo(frame)->function_name();
return handle(name, frame->GetIsolate());
}
+// static
+Handle<Object> StackTraceFrame::GetMethodName(Handle<StackTraceFrame> frame) {
+ auto name = GetFrameInfo(frame)->method_name();
+ return handle(name, frame->GetIsolate());
+}
+
+// static
+Handle<Object> StackTraceFrame::GetTypeName(Handle<StackTraceFrame> frame) {
+ auto name = GetFrameInfo(frame)->type_name();
+ return handle(name, frame->GetIsolate());
+}
+
+// static
+Handle<Object> StackTraceFrame::GetEvalOrigin(Handle<StackTraceFrame> frame) {
+ auto origin = GetFrameInfo(frame)->eval_origin();
+ return handle(origin, frame->GetIsolate());
+}
+
+// static
Handle<Object> StackTraceFrame::GetWasmModuleName(
Handle<StackTraceFrame> frame) {
auto module = GetFrameInfo(frame)->wasm_module_name();
return handle(module, frame->GetIsolate());
}
+// static
bool StackTraceFrame::IsEval(Handle<StackTraceFrame> frame) {
return GetFrameInfo(frame)->is_eval();
}
+// static
bool StackTraceFrame::IsConstructor(Handle<StackTraceFrame> frame) {
return GetFrameInfo(frame)->is_constructor();
}
+// static
bool StackTraceFrame::IsWasm(Handle<StackTraceFrame> frame) {
return GetFrameInfo(frame)->is_wasm();
}
+// static
+bool StackTraceFrame::IsAsmJsWasm(Handle<StackTraceFrame> frame) {
+ return GetFrameInfo(frame)->is_asmjs_wasm();
+}
+
+// static
bool StackTraceFrame::IsUserJavaScript(Handle<StackTraceFrame> frame) {
return GetFrameInfo(frame)->is_user_java_script();
}
+// static
bool StackTraceFrame::IsToplevel(Handle<StackTraceFrame> frame) {
return GetFrameInfo(frame)->is_toplevel();
}
+// static
bool StackTraceFrame::IsAsync(Handle<StackTraceFrame> frame) {
return GetFrameInfo(frame)->is_async();
}
+// static
bool StackTraceFrame::IsPromiseAll(Handle<StackTraceFrame> frame) {
return GetFrameInfo(frame)->is_promise_all();
}
+// static
Handle<StackFrameInfo> StackTraceFrame::GetFrameInfo(
Handle<StackTraceFrame> frame) {
if (frame->frame_info().IsUndefined()) InitializeFrameInfo(frame);
return handle(StackFrameInfo::cast(frame->frame_info()), frame->GetIsolate());
}
+// static
void StackTraceFrame::InitializeFrameInfo(Handle<StackTraceFrame> frame) {
Isolate* isolate = frame->GetIsolate();
Handle<StackFrameInfo> frame_info = isolate->factory()->NewStackFrameInfo(
@@ -97,5 +156,259 @@ void StackTraceFrame::InitializeFrameInfo(Handle<StackTraceFrame> frame) {
frame->set_frame_index(-1);
}
+Handle<FrameArray> GetFrameArrayFromStackTrace(Isolate* isolate,
+ Handle<FixedArray> stack_trace) {
+ // For the empty case, a empty FrameArray needs to be allocated so the rest
+ // of the code doesn't has to be special cased everywhere.
+ if (stack_trace->length() == 0) {
+ return isolate->factory()->NewFrameArray(0);
+ }
+
+ // Retrieve the FrameArray from the first StackTraceFrame.
+ DCHECK_GT(stack_trace->length(), 0);
+ Handle<StackTraceFrame> frame(StackTraceFrame::cast(stack_trace->get(0)),
+ isolate);
+ return handle(FrameArray::cast(frame->frame_array()), isolate);
+}
+
+namespace {
+
+bool IsNonEmptyString(Handle<Object> object) {
+ return (object->IsString() && String::cast(*object).length() > 0);
+}
+
+void AppendFileLocation(Isolate* isolate, Handle<StackTraceFrame> frame,
+ IncrementalStringBuilder* builder) {
+ Handle<Object> file_name = StackTraceFrame::GetScriptNameOrSourceUrl(frame);
+ if (!file_name->IsString() && StackTraceFrame::IsEval(frame)) {
+ Handle<Object> eval_origin = StackTraceFrame::GetEvalOrigin(frame);
+ DCHECK(eval_origin->IsString());
+ builder->AppendString(Handle<String>::cast(eval_origin));
+ builder->AppendCString(", "); // Expecting source position to follow.
+ }
+
+ if (IsNonEmptyString(file_name)) {
+ builder->AppendString(Handle<String>::cast(file_name));
+ } else {
+ // Source code does not originate from a file and is not native, but we
+ // can still get the source position inside the source string, e.g. in
+ // an eval string.
+ builder->AppendCString("<anonymous>");
+ }
+
+ int line_number = StackTraceFrame::GetLineNumber(frame);
+ if (line_number != Message::kNoLineNumberInfo) {
+ builder->AppendCharacter(':');
+ builder->AppendInt(line_number);
+
+ int column_number = StackTraceFrame::GetColumnNumber(frame);
+ if (column_number != Message::kNoColumnInfo) {
+ builder->AppendCharacter(':');
+ builder->AppendInt(column_number);
+ }
+ }
+}
+
+int StringIndexOf(Isolate* isolate, Handle<String> subject,
+ Handle<String> pattern) {
+ if (pattern->length() > subject->length()) return -1;
+ return String::IndexOf(isolate, subject, pattern, 0);
+}
+
+// Returns true iff
+// 1. the subject ends with '.' + pattern, or
+// 2. subject == pattern.
+bool StringEndsWithMethodName(Isolate* isolate, Handle<String> subject,
+ Handle<String> pattern) {
+ if (String::Equals(isolate, subject, pattern)) return true;
+
+ FlatStringReader subject_reader(isolate, String::Flatten(isolate, subject));
+ FlatStringReader pattern_reader(isolate, String::Flatten(isolate, pattern));
+
+ int pattern_index = pattern_reader.length() - 1;
+ int subject_index = subject_reader.length() - 1;
+ for (int i = 0; i <= pattern_reader.length(); i++) { // Iterate over len + 1.
+ if (subject_index < 0) {
+ return false;
+ }
+
+ const uc32 subject_char = subject_reader.Get(subject_index);
+ if (i == pattern_reader.length()) {
+ if (subject_char != '.') return false;
+ } else if (subject_char != pattern_reader.Get(pattern_index)) {
+ return false;
+ }
+
+ pattern_index--;
+ subject_index--;
+ }
+
+ return true;
+}
+
+void AppendMethodCall(Isolate* isolate, Handle<StackTraceFrame> frame,
+ IncrementalStringBuilder* builder) {
+ Handle<Object> type_name = StackTraceFrame::GetTypeName(frame);
+ Handle<Object> method_name = StackTraceFrame::GetMethodName(frame);
+ Handle<Object> function_name = StackTraceFrame::GetFunctionName(frame);
+
+ if (IsNonEmptyString(function_name)) {
+ Handle<String> function_string = Handle<String>::cast(function_name);
+ if (IsNonEmptyString(type_name)) {
+ Handle<String> type_string = Handle<String>::cast(type_name);
+ bool starts_with_type_name =
+ (StringIndexOf(isolate, function_string, type_string) == 0);
+ if (!starts_with_type_name) {
+ builder->AppendString(type_string);
+ builder->AppendCharacter('.');
+ }
+ }
+ builder->AppendString(function_string);
+
+ if (IsNonEmptyString(method_name)) {
+ Handle<String> method_string = Handle<String>::cast(method_name);
+ if (!StringEndsWithMethodName(isolate, function_string, method_string)) {
+ builder->AppendCString(" [as ");
+ builder->AppendString(method_string);
+ builder->AppendCharacter(']');
+ }
+ }
+ } else {
+ if (IsNonEmptyString(type_name)) {
+ builder->AppendString(Handle<String>::cast(type_name));
+ builder->AppendCharacter('.');
+ }
+ if (IsNonEmptyString(method_name)) {
+ builder->AppendString(Handle<String>::cast(method_name));
+ } else {
+ builder->AppendCString("<anonymous>");
+ }
+ }
+}
+
+void SerializeJSStackFrame(
+ Isolate* isolate, Handle<StackTraceFrame> frame,
+ IncrementalStringBuilder& builder // NOLINT(runtime/references)
+) {
+ Handle<Object> function_name = StackTraceFrame::GetFunctionName(frame);
+
+ const bool is_toplevel = StackTraceFrame::IsToplevel(frame);
+ const bool is_async = StackTraceFrame::IsAsync(frame);
+ const bool is_promise_all = StackTraceFrame::IsPromiseAll(frame);
+ const bool is_constructor = StackTraceFrame::IsConstructor(frame);
+ // Note: Keep the {is_method_call} predicate in sync with the corresponding
+ // predicate in factory.cc where the StackFrameInfo is created.
+ // Otherwise necessary fields for serialzing this frame might be
+ // missing.
+ const bool is_method_call = !(is_toplevel || is_constructor);
+
+ if (is_async) {
+ builder.AppendCString("async ");
+ }
+ if (is_promise_all) {
+ builder.AppendCString("Promise.all (index ");
+ builder.AppendInt(StackTraceFrame::GetPromiseAllIndex(frame));
+ builder.AppendCString(")");
+ return;
+ }
+ if (is_method_call) {
+ AppendMethodCall(isolate, frame, &builder);
+ } else if (is_constructor) {
+ builder.AppendCString("new ");
+ if (IsNonEmptyString(function_name)) {
+ builder.AppendString(Handle<String>::cast(function_name));
+ } else {
+ builder.AppendCString("<anonymous>");
+ }
+ } else if (IsNonEmptyString(function_name)) {
+ builder.AppendString(Handle<String>::cast(function_name));
+ } else {
+ AppendFileLocation(isolate, frame, &builder);
+ return;
+ }
+
+ builder.AppendCString(" (");
+ AppendFileLocation(isolate, frame, &builder);
+ builder.AppendCString(")");
+}
+
+void SerializeAsmJsWasmStackFrame(
+ Isolate* isolate, Handle<StackTraceFrame> frame,
+ IncrementalStringBuilder& builder // NOLINT(runtime/references)
+) {
+ // The string should look exactly as the respective javascript frame string.
+ // Keep this method in line to
+ // JSStackFrame::ToString(IncrementalStringBuilder&).
+ Handle<Object> function_name = StackTraceFrame::GetFunctionName(frame);
+
+ if (IsNonEmptyString(function_name)) {
+ builder.AppendString(Handle<String>::cast(function_name));
+ builder.AppendCString(" (");
+ }
+
+ AppendFileLocation(isolate, frame, &builder);
+
+ if (IsNonEmptyString(function_name)) builder.AppendCString(")");
+
+ return;
+}
+
+void SerializeWasmStackFrame(
+ Isolate* isolate, Handle<StackTraceFrame> frame,
+ IncrementalStringBuilder& builder // NOLINT(runtime/references)
+) {
+ Handle<Object> module_name = StackTraceFrame::GetWasmModuleName(frame);
+ Handle<Object> function_name = StackTraceFrame::GetFunctionName(frame);
+ const bool has_name = !module_name->IsNull() || !function_name->IsNull();
+ if (has_name) {
+ if (module_name->IsNull()) {
+ builder.AppendString(Handle<String>::cast(function_name));
+ } else {
+ builder.AppendString(Handle<String>::cast(module_name));
+ if (!function_name->IsNull()) {
+ builder.AppendCString(".");
+ builder.AppendString(Handle<String>::cast(function_name));
+ }
+ }
+ builder.AppendCString(" (");
+ }
+
+ const int wasm_func_index = StackTraceFrame::GetLineNumber(frame);
+
+ builder.AppendCString("wasm-function[");
+ builder.AppendInt(wasm_func_index);
+ builder.AppendCString("]:");
+
+ char buffer[16];
+ SNPrintF(ArrayVector(buffer), "0x%x",
+ StackTraceFrame::GetColumnNumber(frame));
+ builder.AppendCString(buffer);
+
+ if (has_name) builder.AppendCString(")");
+}
+
+} // namespace
+
+void SerializeStackTraceFrame(
+ Isolate* isolate, Handle<StackTraceFrame> frame,
+ IncrementalStringBuilder& builder // NOLINT(runtime/references)
+) {
+ // Ordering here is important, as AsmJs frames are also marked as Wasm.
+ if (StackTraceFrame::IsAsmJsWasm(frame)) {
+ SerializeAsmJsWasmStackFrame(isolate, frame, builder);
+ } else if (StackTraceFrame::IsWasm(frame)) {
+ SerializeWasmStackFrame(isolate, frame, builder);
+ } else {
+ SerializeJSStackFrame(isolate, frame, builder);
+ }
+}
+
+MaybeHandle<String> SerializeStackTraceFrame(Isolate* isolate,
+ Handle<StackTraceFrame> frame) {
+ IncrementalStringBuilder builder(isolate);
+ SerializeStackTraceFrame(isolate, frame, builder);
+ return builder.Finish();
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/stack-frame-info.h b/deps/v8/src/objects/stack-frame-info.h
index 44826f67e6..3d91c5374f 100644
--- a/deps/v8/src/objects/stack-frame-info.h
+++ b/deps/v8/src/objects/stack-frame-info.h
@@ -25,10 +25,14 @@ class StackFrameInfo : public Struct {
DECL_ACCESSORS(script_name, Object)
DECL_ACCESSORS(script_name_or_source_url, Object)
DECL_ACCESSORS(function_name, Object)
+ DECL_ACCESSORS(method_name, Object)
+ DECL_ACCESSORS(type_name, Object)
+ DECL_ACCESSORS(eval_origin, Object)
DECL_ACCESSORS(wasm_module_name, Object)
DECL_BOOLEAN_ACCESSORS(is_eval)
DECL_BOOLEAN_ACCESSORS(is_constructor)
DECL_BOOLEAN_ACCESSORS(is_wasm)
+ DECL_BOOLEAN_ACCESSORS(is_asmjs_wasm)
DECL_BOOLEAN_ACCESSORS(is_user_java_script)
DECL_BOOLEAN_ACCESSORS(is_toplevel)
DECL_BOOLEAN_ACCESSORS(is_async)
@@ -49,10 +53,11 @@ class StackFrameInfo : public Struct {
static const int kIsEvalBit = 0;
static const int kIsConstructorBit = 1;
static const int kIsWasmBit = 2;
- static const int kIsUserJavaScriptBit = 3;
- static const int kIsToplevelBit = 4;
- static const int kIsAsyncBit = 5;
- static const int kIsPromiseAllBit = 6;
+ static const int kIsAsmJsWasmBit = 3;
+ static const int kIsUserJavaScriptBit = 4;
+ static const int kIsToplevelBit = 5;
+ static const int kIsAsyncBit = 6;
+ static const int kIsPromiseAllBit = 7;
OBJECT_CONSTRUCTORS(StackFrameInfo, Struct);
};
@@ -80,18 +85,24 @@ class StackTraceFrame : public Struct {
TORQUE_GENERATED_STACK_TRACE_FRAME_FIELDS)
static int GetLineNumber(Handle<StackTraceFrame> frame);
+ static int GetOneBasedLineNumber(Handle<StackTraceFrame> frame);
static int GetColumnNumber(Handle<StackTraceFrame> frame);
+ static int GetOneBasedColumnNumber(Handle<StackTraceFrame> frame);
static int GetScriptId(Handle<StackTraceFrame> frame);
static int GetPromiseAllIndex(Handle<StackTraceFrame> frame);
static Handle<Object> GetFileName(Handle<StackTraceFrame> frame);
static Handle<Object> GetScriptNameOrSourceUrl(Handle<StackTraceFrame> frame);
static Handle<Object> GetFunctionName(Handle<StackTraceFrame> frame);
+ static Handle<Object> GetMethodName(Handle<StackTraceFrame> frame);
+ static Handle<Object> GetTypeName(Handle<StackTraceFrame> frame);
+ static Handle<Object> GetEvalOrigin(Handle<StackTraceFrame> frame);
static Handle<Object> GetWasmModuleName(Handle<StackTraceFrame> frame);
static bool IsEval(Handle<StackTraceFrame> frame);
static bool IsConstructor(Handle<StackTraceFrame> frame);
static bool IsWasm(Handle<StackTraceFrame> frame);
+ static bool IsAsmJsWasm(Handle<StackTraceFrame> frame);
static bool IsUserJavaScript(Handle<StackTraceFrame> frame);
static bool IsToplevel(Handle<StackTraceFrame> frame);
static bool IsAsync(Handle<StackTraceFrame> frame);
@@ -104,6 +115,22 @@ class StackTraceFrame : public Struct {
static void InitializeFrameInfo(Handle<StackTraceFrame> frame);
};
+// Small helper that retrieves the FrameArray from a stack-trace
+// consisting of a FixedArray of StackTraceFrame objects.
+// This helper is only temporary until all FrameArray use-sites have
+// been converted to use StackTraceFrame and StackFrameInfo objects.
+V8_EXPORT_PRIVATE
+Handle<FrameArray> GetFrameArrayFromStackTrace(Isolate* isolate,
+ Handle<FixedArray> stack_trace);
+
+class IncrementalStringBuilder;
+void SerializeStackTraceFrame(
+ Isolate* isolate, Handle<StackTraceFrame> frame,
+ IncrementalStringBuilder& builder // NOLINT(runtime/references)
+);
+MaybeHandle<String> SerializeStackTraceFrame(Isolate* isolate,
+ Handle<StackTraceFrame> frame);
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/string-inl.h b/deps/v8/src/objects/string-inl.h
index 0d8f83ca86..db724e0cf1 100644
--- a/deps/v8/src/objects/string-inl.h
+++ b/deps/v8/src/objects/string-inl.h
@@ -22,8 +22,6 @@
namespace v8 {
namespace internal {
-INT32_ACCESSORS(String, length, kLengthOffset)
-
int String::synchronized_length() const {
return base::AsAtomic32::Acquire_Load(
reinterpret_cast<const int32_t*>(FIELD_ADDR(*this, kLengthOffset)));
@@ -34,29 +32,21 @@ void String::synchronized_set_length(int value) {
reinterpret_cast<int32_t*>(FIELD_ADDR(*this, kLengthOffset)), value);
}
-OBJECT_CONSTRUCTORS_IMPL(String, Name)
-OBJECT_CONSTRUCTORS_IMPL(SeqString, String)
-OBJECT_CONSTRUCTORS_IMPL(SeqOneByteString, SeqString)
-OBJECT_CONSTRUCTORS_IMPL(SeqTwoByteString, SeqString)
-OBJECT_CONSTRUCTORS_IMPL(InternalizedString, String)
-OBJECT_CONSTRUCTORS_IMPL(ConsString, String)
-OBJECT_CONSTRUCTORS_IMPL(ThinString, String)
-OBJECT_CONSTRUCTORS_IMPL(SlicedString, String)
+TQ_OBJECT_CONSTRUCTORS_IMPL(String)
+TQ_OBJECT_CONSTRUCTORS_IMPL(SeqString)
+TQ_OBJECT_CONSTRUCTORS_IMPL(SeqOneByteString)
+TQ_OBJECT_CONSTRUCTORS_IMPL(SeqTwoByteString)
+TQ_OBJECT_CONSTRUCTORS_IMPL(InternalizedString)
+TQ_OBJECT_CONSTRUCTORS_IMPL(ConsString)
+TQ_OBJECT_CONSTRUCTORS_IMPL(ThinString)
+TQ_OBJECT_CONSTRUCTORS_IMPL(SlicedString)
OBJECT_CONSTRUCTORS_IMPL(ExternalString, String)
OBJECT_CONSTRUCTORS_IMPL(ExternalOneByteString, ExternalString)
OBJECT_CONSTRUCTORS_IMPL(ExternalTwoByteString, ExternalString)
-CAST_ACCESSOR(ConsString)
CAST_ACCESSOR(ExternalOneByteString)
CAST_ACCESSOR(ExternalString)
CAST_ACCESSOR(ExternalTwoByteString)
-CAST_ACCESSOR(InternalizedString)
-CAST_ACCESSOR(SeqOneByteString)
-CAST_ACCESSOR(SeqString)
-CAST_ACCESSOR(SeqTwoByteString)
-CAST_ACCESSOR(SlicedString)
-CAST_ACCESSOR(String)
-CAST_ACCESSOR(ThinString)
StringShape::StringShape(const String str) : type_(str.map().instance_type()) {
set_valid();
@@ -147,16 +137,17 @@ STATIC_ASSERT((kExternalStringTag | kTwoByteStringTag) ==
STATIC_ASSERT(v8::String::TWO_BYTE_ENCODING == kTwoByteStringTag);
-bool String::IsOneByteRepresentation() const {
- uint32_t type = map().instance_type();
+DEF_GETTER(String, IsOneByteRepresentation, bool) {
+ uint32_t type = map(isolate).instance_type();
return (type & kStringEncodingMask) == kOneByteStringTag;
}
-bool String::IsTwoByteRepresentation() const {
- uint32_t type = map().instance_type();
+DEF_GETTER(String, IsTwoByteRepresentation, bool) {
+ uint32_t type = map(isolate).instance_type();
return (type & kStringEncodingMask) == kTwoByteStringTag;
}
+// static
bool String::IsOneByteRepresentationUnderneath(String string) {
while (true) {
uint32_t type = string.map().instance_type();
@@ -398,7 +389,7 @@ String String::GetUnderlying() {
STATIC_ASSERT(static_cast<int>(ConsString::kFirstOffset) ==
static_cast<int>(ThinString::kActualOffset));
const int kUnderlyingOffset = SlicedString::kParentOffset;
- return String::cast(READ_FIELD(*this, kUnderlyingOffset));
+ return TaggedField<String, kUnderlyingOffset>::load(*this);
}
template <class Visitor>
@@ -527,49 +518,23 @@ int SeqOneByteString::SeqOneByteStringSize(InstanceType instance_type) {
return SizeFor(length());
}
-String SlicedString::parent() {
- return String::cast(READ_FIELD(*this, kParentOffset));
-}
-
-void SlicedString::set_parent(Isolate* isolate, String parent,
- WriteBarrierMode mode) {
+void SlicedString::set_parent(String parent, WriteBarrierMode mode) {
DCHECK(parent.IsSeqString() || parent.IsExternalString());
- WRITE_FIELD(*this, kParentOffset, parent);
- CONDITIONAL_WRITE_BARRIER(*this, kParentOffset, parent, mode);
-}
-
-SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
-
-String ConsString::first() {
- return String::cast(READ_FIELD(*this, kFirstOffset));
+ TorqueGeneratedSlicedString<SlicedString, Super>::set_parent(parent, mode);
}
-Object ConsString::unchecked_first() { return READ_FIELD(*this, kFirstOffset); }
+TQ_SMI_ACCESSORS(SlicedString, offset)
-void ConsString::set_first(Isolate* isolate, String value,
- WriteBarrierMode mode) {
- WRITE_FIELD(*this, kFirstOffset, value);
- CONDITIONAL_WRITE_BARRIER(*this, kFirstOffset, value, mode);
-}
-
-String ConsString::second() {
- return String::cast(READ_FIELD(*this, kSecondOffset));
+Object ConsString::unchecked_first() {
+ return TaggedField<Object, kFirstOffset>::load(*this);
}
Object ConsString::unchecked_second() {
return RELAXED_READ_FIELD(*this, kSecondOffset);
}
-void ConsString::set_second(Isolate* isolate, String value,
- WriteBarrierMode mode) {
- WRITE_FIELD(*this, kSecondOffset, value);
- CONDITIONAL_WRITE_BARRIER(*this, kSecondOffset, value, mode);
-}
-
-ACCESSORS(ThinString, actual, String, kActualOffset)
-
-HeapObject ThinString::unchecked_actual() const {
- return HeapObject::unchecked_cast(READ_FIELD(*this, kActualOffset));
+DEF_GETTER(ThinString, unchecked_actual, HeapObject) {
+ return TaggedField<HeapObject, kActualOffset>::load(isolate, *this);
}
bool ExternalString::is_uncached() const {
diff --git a/deps/v8/src/objects/string.cc b/deps/v8/src/objects/string.cc
index cc513f88cb..d1981fd24d 100644
--- a/deps/v8/src/objects/string.cc
+++ b/deps/v8/src/objects/string.cc
@@ -61,8 +61,8 @@ Handle<String> String::SlowFlatten(Isolate* isolate, Handle<ConsString> cons,
WriteToFlat(*cons, flat->GetChars(no_gc), 0, length);
result = flat;
}
- cons->set_first(isolate, *result);
- cons->set_second(isolate, ReadOnlyRoots(isolate).empty_string());
+ cons->set_first(*result);
+ cons->set_second(ReadOnlyRoots(isolate).empty_string());
DCHECK(result->IsFlat());
return result;
}
@@ -146,15 +146,15 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
int size = this->Size(); // Byte size of the original string.
// Abort if size does not allow in-place conversion.
if (size < ExternalString::kUncachedSize) return false;
- Isolate* isolate;
// Read-only strings cannot be made external, since that would mutate the
// string.
- if (!GetIsolateFromWritableObject(*this, &isolate)) return false;
- Heap* heap = isolate->heap();
+ if (IsReadOnlyHeapObject(*this)) return false;
+ Isolate* isolate = GetIsolateFromWritableObject(*this);
bool is_internalized = this->IsInternalizedString();
bool has_pointers = StringShape(*this).IsIndirect();
+
if (has_pointers) {
- heap->NotifyObjectLayoutChange(*this, size, no_allocation);
+ isolate->heap()->NotifyObjectLayoutChange(*this, size, no_allocation);
}
// Morph the string to an external string by replacing the map and
// reinitializing the fields. This won't work if the space the existing
@@ -163,7 +163,7 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
// the address of the backing store. When we encounter uncached external
// strings in generated code, we need to bailout to runtime.
Map new_map;
- ReadOnlyRoots roots(heap);
+ ReadOnlyRoots roots(isolate);
if (size < ExternalString::kSizeOfAllExternalStrings) {
if (is_internalized) {
new_map = roots.uncached_external_internalized_string_map();
@@ -177,10 +177,11 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
// Byte size of the external String object.
int new_size = this->SizeFromMap(new_map);
- heap->CreateFillerObjectAt(this->address() + new_size, size - new_size,
- ClearRecordedSlots::kNo);
+ isolate->heap()->CreateFillerObjectAt(
+ this->address() + new_size, size - new_size, ClearRecordedSlots::kNo);
if (has_pointers) {
- heap->ClearRecordedSlotRange(this->address(), this->address() + new_size);
+ isolate->heap()->ClearRecordedSlotRange(this->address(),
+ this->address() + new_size);
}
// We are storing the new map using release store after creating a filler for
@@ -189,7 +190,7 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
ExternalTwoByteString self = ExternalTwoByteString::cast(*this);
self.SetResource(isolate, resource);
- heap->RegisterExternalString(*this);
+ isolate->heap()->RegisterExternalString(*this);
if (is_internalized) self.Hash(); // Force regeneration of the hash value.
return true;
}
@@ -218,18 +219,16 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
int size = this->Size(); // Byte size of the original string.
// Abort if size does not allow in-place conversion.
if (size < ExternalString::kUncachedSize) return false;
- Isolate* isolate;
// Read-only strings cannot be made external, since that would mutate the
// string.
- if (!GetIsolateFromWritableObject(*this, &isolate)) return false;
- Heap* heap = isolate->heap();
+ if (IsReadOnlyHeapObject(*this)) return false;
+ Isolate* isolate = GetIsolateFromWritableObject(*this);
bool is_internalized = this->IsInternalizedString();
bool has_pointers = StringShape(*this).IsIndirect();
if (has_pointers) {
- heap->NotifyObjectLayoutChange(*this, size, no_allocation);
+ isolate->heap()->NotifyObjectLayoutChange(*this, size, no_allocation);
}
-
// Morph the string to an external string by replacing the map and
// reinitializing the fields. This won't work if the space the existing
// string occupies is too small for a regular external string. Instead, we
@@ -237,7 +236,7 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
// the address of the backing store. When we encounter uncached external
// strings in generated code, we need to bailout to runtime.
Map new_map;
- ReadOnlyRoots roots(heap);
+ ReadOnlyRoots roots(isolate);
if (size < ExternalString::kSizeOfAllExternalStrings) {
new_map = is_internalized
? roots.uncached_external_one_byte_internalized_string_map()
@@ -250,10 +249,11 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
// Byte size of the external String object.
int new_size = this->SizeFromMap(new_map);
- heap->CreateFillerObjectAt(this->address() + new_size, size - new_size,
- ClearRecordedSlots::kNo);
+ isolate->heap()->CreateFillerObjectAt(
+ this->address() + new_size, size - new_size, ClearRecordedSlots::kNo);
if (has_pointers) {
- heap->ClearRecordedSlotRange(this->address(), this->address() + new_size);
+ isolate->heap()->ClearRecordedSlotRange(this->address(),
+ this->address() + new_size);
}
// We are storing the new map using release store after creating a filler for
@@ -262,7 +262,7 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
ExternalOneByteString self = ExternalOneByteString::cast(*this);
self.SetResource(isolate, resource);
- heap->RegisterExternalString(*this);
+ isolate->heap()->RegisterExternalString(*this);
if (is_internalized) self.Hash(); // Force regeneration of the hash value.
return true;
}
@@ -272,9 +272,8 @@ bool String::SupportsExternalization() {
return i::ThinString::cast(*this).actual().SupportsExternalization();
}
- Isolate* isolate;
// RO_SPACE strings cannot be externalized.
- if (!GetIsolateFromWritableObject(*this, &isolate)) {
+ if (IsReadOnlyHeapObject(*this)) {
return false;
}
@@ -290,6 +289,7 @@ bool String::SupportsExternalization() {
DCHECK_LE(ExternalString::kUncachedSize, this->Size());
#endif
+ Isolate* isolate = GetIsolateFromWritableObject(*this);
return !isolate->heap()->IsInGCPostProcessing();
}
diff --git a/deps/v8/src/objects/string.h b/deps/v8/src/objects/string.h
index 74fc8fa763..1a826eee3b 100644
--- a/deps/v8/src/objects/string.h
+++ b/deps/v8/src/objects/string.h
@@ -79,7 +79,7 @@ class StringShape {
// ordered sequence of zero or more 16-bit unsigned integer values.
//
// All string values have a length field.
-class String : public Name {
+class String : public TorqueGeneratedString<String, Name> {
public:
enum Encoding { ONE_BYTE_ENCODING, TWO_BYTE_ENCODING };
@@ -152,21 +152,18 @@ class String : public Name {
template <typename Char>
inline const Char* GetChars(const DisallowHeapAllocation& no_gc);
- // Get and set the length of the string.
- inline int length() const;
- inline void set_length(int value);
-
// Get and set the length of the string using acquire loads and release
// stores.
- inline int synchronized_length() const;
- inline void synchronized_set_length(int value);
+ DECL_SYNCHRONIZED_INT_ACCESSORS(length)
// Returns whether this string has only one-byte chars, i.e. all of them can
// be one-byte encoded. This might be the case even if the string is
// two-byte. Such strings may appear when the embedder prefers
// two-byte external representations even for one-byte data.
inline bool IsOneByteRepresentation() const;
+ inline bool IsOneByteRepresentation(Isolate* isolate) const;
inline bool IsTwoByteRepresentation() const;
+ inline bool IsTwoByteRepresentation(Isolate* isolate) const;
// Cons and slices have an encoding flag that may not represent the actual
// encoding of the underlying string. This is taken into account here.
@@ -320,8 +317,6 @@ class String : public Name {
static Handle<String> Trim(Isolate* isolate, Handle<String> string,
TrimMode mode);
- DECL_CAST(String)
-
V8_EXPORT_PRIVATE void PrintOn(FILE* out);
// For use during stack traces. Performs rudimentary sanity check.
@@ -338,9 +333,6 @@ class String : public Name {
inline bool IsFlat();
- DEFINE_FIELD_OFFSET_CONSTANTS(Name::kHeaderSize,
- TORQUE_GENERATED_STRING_FIELDS)
-
// Max char codes.
static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar;
@@ -453,7 +445,7 @@ class String : public Name {
// Compute and set the hash code.
V8_EXPORT_PRIVATE uint32_t ComputeAndSetHash();
- OBJECT_CONSTRUCTORS(String, Name);
+ TQ_OBJECT_CONSTRUCTORS(String)
};
// clang-format off
@@ -477,30 +469,29 @@ class SubStringRange {
};
// The SeqString abstract class captures sequential string values.
-class SeqString : public String {
+class SeqString : public TorqueGeneratedSeqString<SeqString, String> {
public:
- DECL_CAST(SeqString)
-
// Truncate the string in-place if possible and return the result.
// In case of new_length == 0, the empty string is returned without
// truncating the original string.
V8_WARN_UNUSED_RESULT static Handle<String> Truncate(Handle<SeqString> string,
int new_length);
- OBJECT_CONSTRUCTORS(SeqString, String);
+ TQ_OBJECT_CONSTRUCTORS(SeqString)
};
-class InternalizedString : public String {
+class InternalizedString
+ : public TorqueGeneratedInternalizedString<InternalizedString, String> {
public:
- DECL_CAST(InternalizedString)
// TODO(neis): Possibly move some stuff from String here.
- OBJECT_CONSTRUCTORS(InternalizedString, String);
+ TQ_OBJECT_CONSTRUCTORS(InternalizedString)
};
// The OneByteString class captures sequential one-byte string objects.
// Each character in the OneByteString is an one-byte character.
-class SeqOneByteString : public SeqString {
+class SeqOneByteString
+ : public TorqueGeneratedSeqOneByteString<SeqOneByteString, SeqString> {
public:
static const bool kHasOneByteEncoding = true;
using Char = uint8_t;
@@ -518,8 +509,6 @@ class SeqOneByteString : public SeqString {
// is deterministic.
void clear_padding();
- DECL_CAST(SeqOneByteString)
-
// Garbage collection support. This method is called by the
// garbage collector to compute the actual size of an OneByteString
// instance.
@@ -537,12 +526,13 @@ class SeqOneByteString : public SeqString {
class BodyDescriptor;
- OBJECT_CONSTRUCTORS(SeqOneByteString, SeqString);
+ TQ_OBJECT_CONSTRUCTORS(SeqOneByteString)
};
// The TwoByteString class captures sequential unicode string objects.
// Each character in the TwoByteString is a two-byte uint16_t.
-class SeqTwoByteString : public SeqString {
+class SeqTwoByteString
+ : public TorqueGeneratedSeqTwoByteString<SeqTwoByteString, SeqString> {
public:
static const bool kHasOneByteEncoding = false;
using Char = uint16_t;
@@ -560,8 +550,6 @@ class SeqTwoByteString : public SeqString {
// is deterministic.
void clear_padding();
- DECL_CAST(SeqTwoByteString)
-
// Garbage collection support. This method is called by the
// garbage collector to compute the actual size of a TwoByteString
// instance.
@@ -580,7 +568,7 @@ class SeqTwoByteString : public SeqString {
class BodyDescriptor;
- OBJECT_CONSTRUCTORS(SeqTwoByteString, SeqString);
+ TQ_OBJECT_CONSTRUCTORS(SeqTwoByteString)
};
// The ConsString class describes string values built by using the
@@ -591,32 +579,19 @@ class SeqTwoByteString : public SeqString {
// are non-ConsString string values. The string value represented by
// a ConsString can be obtained by concatenating the leaf string
// values in a left-to-right depth-first traversal of the tree.
-class ConsString : public String {
+class ConsString : public TorqueGeneratedConsString<ConsString, String> {
public:
- // First string of the cons cell.
- inline String first();
// Doesn't check that the result is a string, even in debug mode. This is
// useful during GC where the mark bits confuse the checks.
inline Object unchecked_first();
- inline void set_first(Isolate* isolate, String first,
- WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- // Second string of the cons cell.
- inline String second();
// Doesn't check that the result is a string, even in debug mode. This is
// useful during GC where the mark bits confuse the checks.
inline Object unchecked_second();
- inline void set_second(Isolate* isolate, String second,
- WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
// Dispatched behavior.
V8_EXPORT_PRIVATE uint16_t Get(int index);
- DECL_CAST(ConsString)
-
- DEFINE_FIELD_OFFSET_CONSTANTS(String::kHeaderSize,
- TORQUE_GENERATED_CONS_STRING_FIELDS)
-
// Minimum length for a cons string.
static const int kMinLength = 13;
@@ -624,7 +599,7 @@ class ConsString : public String {
DECL_VERIFIER(ConsString)
- OBJECT_CONSTRUCTORS(ConsString, String);
+ TQ_OBJECT_CONSTRUCTORS(ConsString)
};
// The ThinString class describes string objects that are just references
@@ -634,25 +609,18 @@ class ConsString : public String {
// internalized version (which is allocated as a new object).
// In terms of memory layout and most algorithms operating on strings,
// ThinStrings can be thought of as "one-part cons strings".
-class ThinString : public String {
+class ThinString : public TorqueGeneratedThinString<ThinString, String> {
public:
- // Actual string that this ThinString refers to.
- inline String actual() const;
inline HeapObject unchecked_actual() const;
- inline void set_actual(String s,
- WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+ inline HeapObject unchecked_actual(Isolate* isolate) const;
V8_EXPORT_PRIVATE uint16_t Get(int index);
- DECL_CAST(ThinString)
DECL_VERIFIER(ThinString)
- DEFINE_FIELD_OFFSET_CONSTANTS(String::kHeaderSize,
- TORQUE_GENERATED_THIN_STRING_FIELDS)
-
using BodyDescriptor = FixedBodyDescriptor<kActualOffset, kSize, kSize>;
- OBJECT_CONSTRUCTORS(ThinString, String);
+ TQ_OBJECT_CONSTRUCTORS(ThinString)
};
// The Sliced String class describes strings that are substrings of another
@@ -667,22 +635,14 @@ class ThinString : public String {
// - handling externalized parent strings
// - external strings as parent
// - truncating sliced string to enable otherwise unneeded parent to be GC'ed.
-class SlicedString : public String {
+class SlicedString : public TorqueGeneratedSlicedString<SlicedString, String> {
public:
- inline String parent();
- inline void set_parent(Isolate* isolate, String parent,
+ inline void set_parent(String parent,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline int offset() const;
- inline void set_offset(int offset);
-
+ DECL_INT_ACCESSORS(offset)
// Dispatched behavior.
V8_EXPORT_PRIVATE uint16_t Get(int index);
- DECL_CAST(SlicedString)
-
- DEFINE_FIELD_OFFSET_CONSTANTS(String::kHeaderSize,
- TORQUE_GENERATED_SLICED_STRING_FIELDS)
-
// Minimum length for a sliced string.
static const int kMinLength = 13;
@@ -690,7 +650,7 @@ class SlicedString : public String {
DECL_VERIFIER(SlicedString)
- OBJECT_CONSTRUCTORS(SlicedString, String);
+ TQ_OBJECT_CONSTRUCTORS(SlicedString)
};
// The ExternalString class describes string values that are backed by
@@ -705,6 +665,7 @@ class SlicedString : public String {
class ExternalString : public String {
public:
DECL_CAST(ExternalString)
+ DECL_VERIFIER(ExternalString)
DEFINE_FIELD_OFFSET_CONSTANTS(String::kHeaderSize,
TORQUE_GENERATED_EXTERNAL_STRING_FIELDS)
diff --git a/deps/v8/src/objects/synthetic-module.cc b/deps/v8/src/objects/synthetic-module.cc
new file mode 100644
index 0000000000..0cca30a37b
--- /dev/null
+++ b/deps/v8/src/objects/synthetic-module.cc
@@ -0,0 +1,108 @@
+// Copyright 2019 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.
+
+#include "src/objects/synthetic-module.h"
+
+#include "src/api/api-inl.h"
+#include "src/builtins/accessors.h"
+#include "src/objects/js-generator-inl.h"
+#include "src/objects/module-inl.h"
+#include "src/objects/objects-inl.h"
+#include "src/objects/shared-function-info.h"
+#include "src/utils/ostreams.h"
+
+namespace v8 {
+namespace internal {
+
+// Implements SetSyntheticModuleBinding:
+// https://heycam.github.io/webidl/#setsyntheticmoduleexport
+void SyntheticModule::SetExport(Isolate* isolate,
+ Handle<SyntheticModule> module,
+ Handle<String> export_name,
+ Handle<Object> export_value) {
+ Handle<ObjectHashTable> exports(module->exports(), isolate);
+ Handle<Object> export_object(exports->Lookup(export_name), isolate);
+ CHECK(export_object->IsCell());
+ Handle<Cell> export_cell(Handle<Cell>::cast(export_object));
+ // Spec step 2: Set the mutable binding of export_name to export_value
+ export_cell->set_value(*export_value);
+}
+
+// Implements Synthetic Module Record's ResolveExport concrete method:
+// https://heycam.github.io/webidl/#smr-resolveexport
+MaybeHandle<Cell> SyntheticModule::ResolveExport(
+ Isolate* isolate, Handle<SyntheticModule> module,
+ Handle<String> module_specifier, Handle<String> export_name,
+ MessageLocation loc, bool must_resolve) {
+ Handle<Object> object(module->exports().Lookup(export_name), isolate);
+ if (object->IsCell()) {
+ return Handle<Cell>::cast(object);
+ }
+
+ if (must_resolve) {
+ return isolate->Throw<Cell>(
+ isolate->factory()->NewSyntaxError(MessageTemplate::kUnresolvableExport,
+ module_specifier, export_name),
+ &loc);
+ }
+
+ return MaybeHandle<Cell>();
+}
+
+// Implements Synthetic Module Record's Instantiate concrete method :
+// https://heycam.github.io/webidl/#smr-instantiate
+bool SyntheticModule::PrepareInstantiate(Isolate* isolate,
+ Handle<SyntheticModule> module,
+ v8::Local<v8::Context> context,
+ v8::Module::ResolveCallback callback) {
+ Handle<ObjectHashTable> exports(module->exports(), isolate);
+ Handle<FixedArray> export_names(module->export_names(), isolate);
+ // Spec step 7: For each export_name in module->export_names...
+ for (int i = 0, n = export_names->length(); i < n; ++i) {
+ // Spec step 7.1: Create a new mutable binding for export_name.
+ // Spec step 7.2: Initialize the new mutable binding to undefined.
+ Handle<Cell> cell =
+ isolate->factory()->NewCell(isolate->factory()->undefined_value());
+ Handle<String> name(String::cast(export_names->get(i)), isolate);
+ CHECK(exports->Lookup(name).IsTheHole(isolate));
+ exports = ObjectHashTable::Put(exports, name, cell);
+ }
+ module->set_exports(*exports);
+ return true;
+}
+
+// Second step of module instantiation. No real work to do for SyntheticModule
+// as there are no imports or indirect exports to resolve;
+// just update status.
+bool SyntheticModule::FinishInstantiate(Isolate* isolate,
+ Handle<SyntheticModule> module) {
+ module->SetStatus(kInstantiated);
+ return true;
+}
+
+// Implements Synthetic Module Record's Evaluate concrete method:
+// https://heycam.github.io/webidl/#smr-evaluate
+MaybeHandle<Object> SyntheticModule::Evaluate(Isolate* isolate,
+ Handle<SyntheticModule> module) {
+ module->SetStatus(kEvaluating);
+
+ v8::Module::SyntheticModuleEvaluationSteps evaluation_steps =
+ FUNCTION_CAST<v8::Module::SyntheticModuleEvaluationSteps>(
+ module->evaluation_steps().foreign_address());
+ v8::Local<v8::Value> result;
+ if (!evaluation_steps(
+ Utils::ToLocal(Handle<Context>::cast(isolate->native_context())),
+ Utils::ToLocal(Handle<Module>::cast(module)))
+ .ToLocal(&result)) {
+ isolate->PromoteScheduledException();
+ module->RecordError(isolate);
+ return MaybeHandle<Object>();
+ }
+
+ module->SetStatus(kEvaluated);
+ return Utils::OpenHandle(*result);
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/src/objects/synthetic-module.h b/deps/v8/src/objects/synthetic-module.h
new file mode 100644
index 0000000000..9f91f2ce4a
--- /dev/null
+++ b/deps/v8/src/objects/synthetic-module.h
@@ -0,0 +1,69 @@
+// Copyright 2019 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_SYNTHETIC_MODULE_H_
+#define V8_OBJECTS_SYNTHETIC_MODULE_H_
+
+#include "src/objects/module.h"
+
+// Has to be the last include (doesn't have include guards):
+#include "src/objects/object-macros.h"
+
+namespace v8 {
+namespace internal {
+
+// The runtime representation of a Synthetic Module Record, a module that can be
+// instantiated by an embedder with embedder-defined exports and evaluation
+// steps.
+// https://heycam.github.io/webidl/#synthetic-module-records
+class SyntheticModule : public Module {
+ public:
+ NEVER_READ_ONLY_SPACE
+ DECL_CAST(SyntheticModule)
+ DECL_VERIFIER(SyntheticModule)
+ DECL_PRINTER(SyntheticModule)
+
+ // The list of all names exported by this module
+ DECL_ACCESSORS(name, String)
+ DECL_ACCESSORS(export_names, FixedArray)
+ DECL_ACCESSORS(evaluation_steps, Foreign)
+
+ static void SetExport(Isolate* isolate, Handle<SyntheticModule> module,
+ Handle<String> export_name,
+ Handle<Object> export_value);
+
+ // Layout description.
+ DEFINE_FIELD_OFFSET_CONSTANTS(Module::kHeaderSize,
+ TORQUE_GENERATED_SYNTHETIC_MODULE_FIELDS)
+
+ using BodyDescriptor = SubclassBodyDescriptor<
+ Module::BodyDescriptor,
+ FixedBodyDescriptor<kExportNamesOffset, kSize, kSize>>;
+
+ private:
+ friend class Module;
+
+ static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveExport(
+ Isolate* isolate, Handle<SyntheticModule> module,
+ Handle<String> module_specifier, Handle<String> export_name,
+ MessageLocation loc, bool must_resolve);
+
+ static V8_WARN_UNUSED_RESULT bool PrepareInstantiate(
+ Isolate* isolate, Handle<SyntheticModule> module,
+ v8::Local<v8::Context> context, v8::Module::ResolveCallback callback);
+ static V8_WARN_UNUSED_RESULT bool FinishInstantiate(
+ Isolate* isolate, Handle<SyntheticModule> module);
+
+ static V8_WARN_UNUSED_RESULT MaybeHandle<Object> Evaluate(
+ Isolate* isolate, Handle<SyntheticModule> module);
+
+ OBJECT_CONSTRUCTORS(SyntheticModule, Module);
+};
+
+} // namespace internal
+} // namespace v8
+
+#include "src/objects/object-macros-undef.h"
+
+#endif // V8_OBJECTS_SYNTHETIC_MODULE_H_
diff --git a/deps/v8/src/objects/tagged-field-inl.h b/deps/v8/src/objects/tagged-field-inl.h
new file mode 100644
index 0000000000..3cce536a14
--- /dev/null
+++ b/deps/v8/src/objects/tagged-field-inl.h
@@ -0,0 +1,162 @@
+// Copyright 2019 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_TAGGED_FIELD_INL_H_
+#define V8_OBJECTS_TAGGED_FIELD_INL_H_
+
+#include "src/objects/tagged-field.h"
+
+#include "src/common/ptr-compr-inl.h"
+
+namespace v8 {
+namespace internal {
+
+// static
+template <typename T, int kFieldOffset>
+Address TaggedField<T, kFieldOffset>::address(HeapObject host, int offset) {
+ return host.address() + kFieldOffset + offset;
+}
+
+// static
+template <typename T, int kFieldOffset>
+Tagged_t* TaggedField<T, kFieldOffset>::location(HeapObject host, int offset) {
+ return reinterpret_cast<Tagged_t*>(address(host, offset));
+}
+
+// static
+template <typename T, int kFieldOffset>
+template <typename TOnHeapAddress>
+Address TaggedField<T, kFieldOffset>::tagged_to_full(
+ TOnHeapAddress on_heap_addr, Tagged_t tagged_value) {
+#ifdef V8_COMPRESS_POINTERS
+ if (kIsSmi) {
+ return DecompressTaggedSigned(tagged_value);
+ } else if (kIsHeapObject) {
+ return DecompressTaggedPointer(on_heap_addr, tagged_value);
+ } else {
+ return DecompressTaggedAny(on_heap_addr, tagged_value);
+ }
+#else
+ return tagged_value;
+#endif
+}
+
+// static
+template <typename T, int kFieldOffset>
+Tagged_t TaggedField<T, kFieldOffset>::full_to_tagged(Address value) {
+#ifdef V8_COMPRESS_POINTERS
+ return CompressTagged(value);
+#else
+ return value;
+#endif
+}
+
+// static
+template <typename T, int kFieldOffset>
+T TaggedField<T, kFieldOffset>::load(HeapObject host, int offset) {
+ Tagged_t value = *location(host, offset);
+ return T(tagged_to_full(host.ptr(), value));
+}
+
+// static
+template <typename T, int kFieldOffset>
+T TaggedField<T, kFieldOffset>::load(Isolate* isolate, HeapObject host,
+ int offset) {
+ Tagged_t value = *location(host, offset);
+ return T(tagged_to_full(isolate, value));
+}
+
+// static
+template <typename T, int kFieldOffset>
+void TaggedField<T, kFieldOffset>::store(HeapObject host, T value) {
+#ifdef V8_CONCURRENT_MARKING
+ Relaxed_Store(host, value);
+#else
+ *location(host) = full_to_tagged(value.ptr());
+#endif
+}
+
+// static
+template <typename T, int kFieldOffset>
+void TaggedField<T, kFieldOffset>::store(HeapObject host, int offset, T value) {
+#ifdef V8_CONCURRENT_MARKING
+ Relaxed_Store(host, offset, value);
+#else
+ *location(host, offset) = full_to_tagged(value.ptr());
+#endif
+}
+
+// static
+template <typename T, int kFieldOffset>
+T TaggedField<T, kFieldOffset>::Relaxed_Load(HeapObject host, int offset) {
+ AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location(host, offset));
+ return T(tagged_to_full(host.ptr(), value));
+}
+
+// static
+template <typename T, int kFieldOffset>
+T TaggedField<T, kFieldOffset>::Relaxed_Load(Isolate* isolate, HeapObject host,
+ int offset) {
+ AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location(host, offset));
+ return T(tagged_to_full(isolate, value));
+}
+
+// static
+template <typename T, int kFieldOffset>
+void TaggedField<T, kFieldOffset>::Relaxed_Store(HeapObject host, T value) {
+ AsAtomicTagged::Relaxed_Store(location(host), full_to_tagged(value.ptr()));
+}
+
+// static
+template <typename T, int kFieldOffset>
+void TaggedField<T, kFieldOffset>::Relaxed_Store(HeapObject host, int offset,
+ T value) {
+ AsAtomicTagged::Relaxed_Store(location(host, offset),
+ full_to_tagged(value.ptr()));
+}
+
+// static
+template <typename T, int kFieldOffset>
+T TaggedField<T, kFieldOffset>::Acquire_Load(HeapObject host, int offset) {
+ AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location(host, offset));
+ return T(tagged_to_full(host.ptr(), value));
+}
+
+// static
+template <typename T, int kFieldOffset>
+T TaggedField<T, kFieldOffset>::Acquire_Load(Isolate* isolate, HeapObject host,
+ int offset) {
+ AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location(host, offset));
+ return T(tagged_to_full(isolate, value));
+}
+
+// static
+template <typename T, int kFieldOffset>
+void TaggedField<T, kFieldOffset>::Release_Store(HeapObject host, T value) {
+ AsAtomicTagged::Release_Store(location(host), full_to_tagged(value.ptr()));
+}
+
+// static
+template <typename T, int kFieldOffset>
+void TaggedField<T, kFieldOffset>::Release_Store(HeapObject host, int offset,
+ T value) {
+ AsAtomicTagged::Release_Store(location(host, offset),
+ full_to_tagged(value.ptr()));
+}
+
+// static
+template <typename T, int kFieldOffset>
+Tagged_t TaggedField<T, kFieldOffset>::Release_CompareAndSwap(HeapObject host,
+ T old, T value) {
+ Tagged_t old_value = full_to_tagged(old.ptr());
+ Tagged_t new_value = full_to_tagged(value.ptr());
+ Tagged_t result = AsAtomicTagged::Release_CompareAndSwap(
+ location(host), old_value, new_value);
+ return result;
+}
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_OBJECTS_TAGGED_FIELD_INL_H_
diff --git a/deps/v8/src/objects/tagged-field.h b/deps/v8/src/objects/tagged-field.h
new file mode 100644
index 0000000000..fbaaee5930
--- /dev/null
+++ b/deps/v8/src/objects/tagged-field.h
@@ -0,0 +1,76 @@
+// Copyright 2019 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_TAGGED_FIELD_H_
+#define V8_OBJECTS_TAGGED_FIELD_H_
+
+#include "src/common/globals.h"
+
+#include "src/objects/objects.h"
+#include "src/objects/tagged-value.h"
+
+namespace v8 {
+namespace internal {
+
+// This helper static class represents a tagged field of type T at offset
+// kFieldOffset inside some host HeapObject.
+// For full-pointer mode this type adds no overhead but when pointer
+// compression is enabled such class allows us to use proper decompression
+// function depending on the field type.
+template <typename T, int kFieldOffset = 0>
+class TaggedField : public AllStatic {
+ public:
+ static_assert(std::is_base_of<Object, T>::value ||
+ std::is_same<MapWord, T>::value ||
+ std::is_same<MaybeObject, T>::value,
+ "T must be strong or weak tagged type or MapWord");
+
+ // True for Smi fields.
+ static constexpr bool kIsSmi = std::is_base_of<Smi, T>::value;
+
+ // True for HeapObject and MapWord fields. The latter may look like a Smi
+ // if it contains forwarding pointer but still requires tagged pointer
+ // decompression.
+ static constexpr bool kIsHeapObject =
+ std::is_base_of<HeapObject, T>::value || std::is_same<MapWord, T>::value;
+
+ static inline Address address(HeapObject host, int offset = 0);
+
+ static inline T load(HeapObject host, int offset = 0);
+ static inline T load(Isolate* isolate, HeapObject host, int offset = 0);
+
+ static inline void store(HeapObject host, T value);
+ static inline void store(HeapObject host, int offset, T value);
+
+ static inline T Relaxed_Load(HeapObject host, int offset = 0);
+ static inline T Relaxed_Load(Isolate* isolate, HeapObject host,
+ int offset = 0);
+
+ static inline void Relaxed_Store(HeapObject host, T value);
+ static inline void Relaxed_Store(HeapObject host, int offset, T value);
+
+ static inline T Acquire_Load(HeapObject host, int offset = 0);
+ static inline T Acquire_Load(Isolate* isolate, HeapObject host,
+ int offset = 0);
+
+ static inline void Release_Store(HeapObject host, T value);
+ static inline void Release_Store(HeapObject host, int offset, T value);
+
+ static inline Tagged_t Release_CompareAndSwap(HeapObject host, T old,
+ T value);
+
+ private:
+ static inline Tagged_t* location(HeapObject host, int offset = 0);
+
+ template <typename TOnHeapAddress>
+ static inline Address tagged_to_full(TOnHeapAddress on_heap_addr,
+ Tagged_t tagged_value);
+
+ static inline Tagged_t full_to_tagged(Address value);
+};
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_OBJECTS_TAGGED_FIELD_H_
diff --git a/deps/v8/src/objects/tagged-impl-inl.h b/deps/v8/src/objects/tagged-impl-inl.h
index f735a241a8..909f65a959 100644
--- a/deps/v8/src/objects/tagged-impl-inl.h
+++ b/deps/v8/src/objects/tagged-impl-inl.h
@@ -52,11 +52,11 @@ bool TaggedImpl<kRefType, StorageType>::GetHeapObject(
template <HeapObjectReferenceType kRefType, typename StorageType>
bool TaggedImpl<kRefType, StorageType>::GetHeapObject(
- ROOT_PARAM, HeapObject* result) const {
+ Isolate* isolate, HeapObject* result) const {
if (kIsFull) return GetHeapObject(result);
// Implementation for compressed pointers.
if (!IsStrongOrWeak()) return false;
- *result = GetHeapObject(ROOT_VALUE);
+ *result = GetHeapObject(isolate);
return true;
}
@@ -79,14 +79,14 @@ bool TaggedImpl<kRefType, StorageType>::GetHeapObject(
template <HeapObjectReferenceType kRefType, typename StorageType>
bool TaggedImpl<kRefType, StorageType>::GetHeapObject(
- ROOT_PARAM, HeapObject* result,
+ Isolate* isolate, HeapObject* result,
HeapObjectReferenceType* reference_type) const {
if (kIsFull) return GetHeapObject(result, reference_type);
// Implementation for compressed pointers.
if (!IsStrongOrWeak()) return false;
*reference_type = IsWeakOrCleared() ? HeapObjectReferenceType::WEAK
: HeapObjectReferenceType::STRONG;
- *result = GetHeapObject(ROOT_VALUE);
+ *result = GetHeapObject(isolate);
return true;
}
@@ -107,12 +107,12 @@ bool TaggedImpl<kRefType, StorageType>::GetHeapObjectIfStrong(
template <HeapObjectReferenceType kRefType, typename StorageType>
bool TaggedImpl<kRefType, StorageType>::GetHeapObjectIfStrong(
- ROOT_PARAM, HeapObject* result) const {
+ Isolate* isolate, HeapObject* result) const {
if (kIsFull) return GetHeapObjectIfStrong(result);
// Implementation for compressed pointers.
if (IsStrong()) {
- *result =
- HeapObject::cast(Object(DecompressTaggedPointer(ROOT_VALUE, ptr_)));
+ *result = HeapObject::cast(
+ Object(DecompressTaggedPointer(isolate, static_cast<Tagged_t>(ptr_))));
return true;
}
return false;
@@ -132,11 +132,12 @@ HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObjectAssumeStrong()
template <HeapObjectReferenceType kRefType, typename StorageType>
HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObjectAssumeStrong(
- ROOT_PARAM) const {
+ Isolate* isolate) const {
if (kIsFull) return GetHeapObjectAssumeStrong();
// Implementation for compressed pointers.
DCHECK(IsStrong());
- return HeapObject::cast(Object(DecompressTaggedPointer(ROOT_VALUE, ptr_)));
+ return HeapObject::cast(
+ Object(DecompressTaggedPointer(isolate, static_cast<Tagged_t>(ptr_))));
}
//
@@ -161,12 +162,12 @@ bool TaggedImpl<kRefType, StorageType>::GetHeapObjectIfWeak(
template <HeapObjectReferenceType kRefType, typename StorageType>
bool TaggedImpl<kRefType, StorageType>::GetHeapObjectIfWeak(
- ROOT_PARAM, HeapObject* result) const {
+ Isolate* isolate, HeapObject* result) const {
if (kIsFull) return GetHeapObjectIfWeak(result);
// Implementation for compressed pointers.
if (kCanBeWeak) {
if (IsWeak()) {
- *result = GetHeapObject(ROOT_VALUE);
+ *result = GetHeapObject(isolate);
return true;
}
return false;
@@ -189,11 +190,11 @@ HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObjectAssumeWeak() const {
template <HeapObjectReferenceType kRefType, typename StorageType>
HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObjectAssumeWeak(
- ROOT_PARAM) const {
+ Isolate* isolate) const {
if (kIsFull) return GetHeapObjectAssumeWeak();
// Implementation for compressed pointers.
DCHECK(IsWeak());
- return GetHeapObject(ROOT_VALUE);
+ return GetHeapObject(isolate);
}
//
@@ -214,17 +215,19 @@ HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObject() const {
}
template <HeapObjectReferenceType kRefType, typename StorageType>
-HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObject(ROOT_PARAM) const {
+HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObject(
+ Isolate* isolate) const {
if (kIsFull) return GetHeapObject();
// Implementation for compressed pointers.
DCHECK(!IsSmi());
if (kCanBeWeak) {
DCHECK(!IsCleared());
- return HeapObject::cast(Object(
- DecompressTaggedPointer(ROOT_VALUE, ptr_ & ~kWeakHeapObjectMask)));
+ return HeapObject::cast(Object(DecompressTaggedPointer(
+ isolate, static_cast<Tagged_t>(ptr_) & ~kWeakHeapObjectMask)));
} else {
DCHECK(!HAS_WEAK_HEAP_OBJECT_TAG(ptr_));
- return HeapObject::cast(Object(DecompressTaggedPointer(ROOT_VALUE, ptr_)));
+ return HeapObject::cast(
+ Object(DecompressTaggedPointer(isolate, static_cast<Tagged_t>(ptr_))));
}
}
@@ -242,13 +245,14 @@ Object TaggedImpl<kRefType, StorageType>::GetHeapObjectOrSmi() const {
}
template <HeapObjectReferenceType kRefType, typename StorageType>
-Object TaggedImpl<kRefType, StorageType>::GetHeapObjectOrSmi(ROOT_PARAM) const {
+Object TaggedImpl<kRefType, StorageType>::GetHeapObjectOrSmi(
+ Isolate* isolate) const {
if (kIsFull) return GetHeapObjectOrSmi();
// Implementation for compressed pointers.
if (IsSmi()) {
- return Object(DecompressTaggedSigned(ptr_));
+ return Object(DecompressTaggedSigned(static_cast<Tagged_t>(ptr_)));
}
- return GetHeapObject(ROOT_VALUE);
+ return GetHeapObject(isolate);
}
} // namespace internal
diff --git a/deps/v8/src/objects/tagged-impl.h b/deps/v8/src/objects/tagged-impl.h
index e3d982565f..111eabae2f 100644
--- a/deps/v8/src/objects/tagged-impl.h
+++ b/deps/v8/src/objects/tagged-impl.h
@@ -40,16 +40,24 @@ class TaggedImpl {
// Make clang on Linux catch what MSVC complains about on Windows:
operator bool() const = delete;
- constexpr bool operator==(TaggedImpl other) const {
- return ptr_ == other.ptr_;
+ template <typename U>
+ constexpr bool operator==(TaggedImpl<kRefType, U> other) const {
+ static_assert(
+ std::is_same<U, Address>::value || std::is_same<U, Tagged_t>::value,
+ "U must be either Address or Tagged_t");
+ return static_cast<Tagged_t>(ptr_) == static_cast<Tagged_t>(other.ptr());
}
- constexpr bool operator!=(TaggedImpl other) const {
- return ptr_ != other.ptr_;
+ template <typename U>
+ constexpr bool operator!=(TaggedImpl<kRefType, U> other) const {
+ static_assert(
+ std::is_same<U, Address>::value || std::is_same<U, Tagged_t>::value,
+ "U must be either Address or Tagged_t");
+ return static_cast<Tagged_t>(ptr_) != static_cast<Tagged_t>(other.ptr());
}
// For using in std::set and std::map.
constexpr bool operator<(TaggedImpl other) const {
- return ptr_ < other.ptr();
+ return static_cast<Tagged_t>(ptr_) < static_cast<Tagged_t>(other.ptr());
}
constexpr StorageType ptr() const { return ptr_; }
@@ -99,50 +107,51 @@ class TaggedImpl {
//
// The following set of methods get HeapObject out of the tagged value
- // which may involve decompression in which case the ROOT_PARAM is required.
+ // which may involve decompression in which case the isolate root is required.
// If the pointer compression is not enabled then the variants with
- // ROOT_PARAM will be exactly the same as non-ROOT_PARAM ones.
+ // isolate parameter will be exactly the same as the ones witout isolate
+ // parameter.
//
// If this tagged value is a strong pointer to a HeapObject, returns true and
// sets *result. Otherwise returns false.
inline bool GetHeapObjectIfStrong(HeapObject* result) const;
- inline bool GetHeapObjectIfStrong(ROOT_PARAM, HeapObject* result) const;
+ inline bool GetHeapObjectIfStrong(Isolate* isolate, HeapObject* result) const;
// DCHECKs that this tagged value is a strong pointer to a HeapObject and
// returns the HeapObject.
inline HeapObject GetHeapObjectAssumeStrong() const;
- inline HeapObject GetHeapObjectAssumeStrong(ROOT_PARAM) const;
+ inline HeapObject GetHeapObjectAssumeStrong(Isolate* isolate) const;
// If this tagged value is a weak pointer to a HeapObject, returns true and
// sets *result. Otherwise returns false.
inline bool GetHeapObjectIfWeak(HeapObject* result) const;
- inline bool GetHeapObjectIfWeak(ROOT_PARAM, HeapObject* result) const;
+ inline bool GetHeapObjectIfWeak(Isolate* isolate, HeapObject* result) const;
// DCHECKs that this tagged value is a weak pointer to a HeapObject and
// returns the HeapObject.
inline HeapObject GetHeapObjectAssumeWeak() const;
- inline HeapObject GetHeapObjectAssumeWeak(ROOT_PARAM) const;
+ inline HeapObject GetHeapObjectAssumeWeak(Isolate* isolate) const;
// If this tagged value is a strong or weak pointer to a HeapObject, returns
// true and sets *result. Otherwise returns false.
inline bool GetHeapObject(HeapObject* result) const;
- inline bool GetHeapObject(ROOT_PARAM, HeapObject* result) const;
+ inline bool GetHeapObject(Isolate* isolate, HeapObject* result) const;
inline bool GetHeapObject(HeapObject* result,
HeapObjectReferenceType* reference_type) const;
- inline bool GetHeapObject(ROOT_PARAM, HeapObject* result,
+ inline bool GetHeapObject(Isolate* isolate, HeapObject* result,
HeapObjectReferenceType* reference_type) const;
// DCHECKs that this tagged value is a strong or a weak pointer to a
// HeapObject and returns the HeapObject.
inline HeapObject GetHeapObject() const;
- inline HeapObject GetHeapObject(ROOT_PARAM) const;
+ inline HeapObject GetHeapObject(Isolate* isolate) const;
// DCHECKs that this tagged value is a strong or a weak pointer to a
// HeapObject or a Smi and returns the HeapObject or Smi.
inline Object GetHeapObjectOrSmi() const;
- inline Object GetHeapObjectOrSmi(ROOT_PARAM) const;
+ inline Object GetHeapObjectOrSmi(Isolate* isolate) const;
// Cast operation is available only for full non-weak tagged values.
template <typename T>
diff --git a/deps/v8/src/objects/tagged-value-inl.h b/deps/v8/src/objects/tagged-value-inl.h
index 5eb0e20947..f409a4006b 100644
--- a/deps/v8/src/objects/tagged-value-inl.h
+++ b/deps/v8/src/objects/tagged-value-inl.h
@@ -9,7 +9,8 @@
#include "include/v8-internal.h"
#include "src/common/ptr-compr-inl.h"
-#include "src/objects/heap-object-inl.h"
+#include "src/objects/maybe-object.h"
+#include "src/objects/objects.h"
#include "src/objects/oddball.h"
#include "src/objects/tagged-impl-inl.h"
#include "src/roots/roots-inl.h"
@@ -17,17 +18,37 @@
namespace v8 {
namespace internal {
-Object StrongTaggedValue::ToObject(WITH_ROOT_PARAM(StrongTaggedValue object)) {
+inline StrongTaggedValue::StrongTaggedValue(Object o)
+ :
#ifdef V8_COMPRESS_POINTERS
- return Object(DecompressTaggedAny(ROOT_VALUE, object.ptr()));
+ TaggedImpl(CompressTagged(o.ptr()))
+#else
+ TaggedImpl(o.ptr())
+#endif
+{
+}
+
+Object StrongTaggedValue::ToObject(Isolate* isolate, StrongTaggedValue object) {
+#ifdef V8_COMPRESS_POINTERS
+ return Object(DecompressTaggedAny(isolate, object.ptr()));
#else
return Object(object.ptr());
#endif
}
-MaybeObject TaggedValue::ToMaybeObject(WITH_ROOT_PARAM(TaggedValue object)) {
+inline TaggedValue::TaggedValue(MaybeObject o)
+ :
+#ifdef V8_COMPRESS_POINTERS
+ TaggedImpl(CompressTagged(o.ptr()))
+#else
+ TaggedImpl(o.ptr())
+#endif
+{
+}
+
+MaybeObject TaggedValue::ToMaybeObject(Isolate* isolate, TaggedValue object) {
#ifdef V8_COMPRESS_POINTERS
- return MaybeObject(DecompressTaggedAny(ROOT_VALUE, object.ptr()));
+ return MaybeObject(DecompressTaggedAny(isolate, object.ptr()));
#else
return MaybeObject(object.ptr());
#endif
diff --git a/deps/v8/src/objects/tagged-value.h b/deps/v8/src/objects/tagged-value.h
index bb7609f7c3..7b6192204a 100644
--- a/deps/v8/src/objects/tagged-value.h
+++ b/deps/v8/src/objects/tagged-value.h
@@ -21,8 +21,9 @@ class StrongTaggedValue
public:
constexpr StrongTaggedValue() : TaggedImpl() {}
explicit constexpr StrongTaggedValue(Tagged_t ptr) : TaggedImpl(ptr) {}
+ explicit StrongTaggedValue(Object o);
- inline static Object ToObject(WITH_ROOT_PARAM(StrongTaggedValue object));
+ inline static Object ToObject(Isolate* isolate, StrongTaggedValue object);
};
// Almost same as MaybeObject but this one deals with in-heap and potentially
@@ -32,8 +33,9 @@ class TaggedValue : public TaggedImpl<HeapObjectReferenceType::WEAK, Tagged_t> {
public:
constexpr TaggedValue() : TaggedImpl() {}
explicit constexpr TaggedValue(Tagged_t ptr) : TaggedImpl(ptr) {}
+ explicit TaggedValue(MaybeObject o);
- inline static MaybeObject ToMaybeObject(WITH_ROOT_PARAM(TaggedValue object));
+ inline static MaybeObject ToMaybeObject(Isolate* isolate, TaggedValue object);
};
} // namespace internal
diff --git a/deps/v8/src/objects/template-objects.cc b/deps/v8/src/objects/template-objects.cc
index 2f34a48a2a..d5b6293afe 100644
--- a/deps/v8/src/objects/template-objects.cc
+++ b/deps/v8/src/objects/template-objects.cc
@@ -16,11 +16,9 @@ namespace internal {
// static
Handle<JSArray> TemplateObjectDescription::GetTemplateObject(
- Isolate* isolate, Handle<Context> native_context,
+ Isolate* isolate, Handle<NativeContext> native_context,
Handle<TemplateObjectDescription> description,
Handle<SharedFunctionInfo> shared_info, int slot_id) {
- DCHECK(native_context->IsNativeContext());
-
// Check the template weakmap to see if the template object already exists.
Handle<EphemeronHashTable> template_weakmap =
native_context->template_weakmap().IsUndefined(isolate)
diff --git a/deps/v8/src/objects/template-objects.h b/deps/v8/src/objects/template-objects.h
index 220f9dab1e..20ad742338 100644
--- a/deps/v8/src/objects/template-objects.h
+++ b/deps/v8/src/objects/template-objects.h
@@ -47,7 +47,7 @@ class TemplateObjectDescription final : public Struct {
DECL_CAST(TemplateObjectDescription)
static Handle<JSArray> GetTemplateObject(
- Isolate* isolate, Handle<Context> native_context,
+ Isolate* isolate, Handle<NativeContext> native_context,
Handle<TemplateObjectDescription> description,
Handle<SharedFunctionInfo> shared_info, int slot_id);
diff --git a/deps/v8/src/objects/templates-inl.h b/deps/v8/src/objects/templates-inl.h
index a1a098ffc0..d344174a0c 100644
--- a/deps/v8/src/objects/templates-inl.h
+++ b/deps/v8/src/objects/templates-inl.h
@@ -55,7 +55,7 @@ SMI_ACCESSORS(FunctionTemplateInfo, flag, kFlagOffset)
// static
FunctionTemplateRareData FunctionTemplateInfo::EnsureFunctionTemplateRareData(
Isolate* isolate, Handle<FunctionTemplateInfo> function_template_info) {
- HeapObject extra = function_template_info->rare_data();
+ HeapObject extra = function_template_info->rare_data(isolate);
if (extra.IsUndefined(isolate)) {
return AllocateFunctionTemplateRareData(isolate, function_template_info);
} else {
@@ -64,9 +64,9 @@ FunctionTemplateRareData FunctionTemplateInfo::EnsureFunctionTemplateRareData(
}
#define RARE_ACCESSORS(Name, CamelName, Type) \
- Type FunctionTemplateInfo::Get##CamelName() { \
- HeapObject extra = rare_data(); \
- HeapObject undefined = GetReadOnlyRoots().undefined_value(); \
+ DEF_GETTER(FunctionTemplateInfo, Get##CamelName, Type) { \
+ HeapObject extra = rare_data(isolate); \
+ HeapObject undefined = GetReadOnlyRoots(isolate).undefined_value(); \
return extra == undefined ? undefined \
: FunctionTemplateRareData::cast(extra).Name(); \
} \
diff --git a/deps/v8/src/objects/templates.h b/deps/v8/src/objects/templates.h
index 66cd038114..99142266ed 100644
--- a/deps/v8/src/objects/templates.h
+++ b/deps/v8/src/objects/templates.h
@@ -86,7 +86,7 @@ class FunctionTemplateInfo : public TemplateInfo {
DECL_ACCESSORS(rare_data, HeapObject)
#define DECL_RARE_ACCESSORS(Name, CamelName, Type) \
- inline Type Get##CamelName(); \
+ DECL_GETTER(Get##CamelName, Type) \
static inline void Set##CamelName( \
Isolate* isolate, Handle<FunctionTemplateInfo> function_template_info, \
Handle<Type> Name);
diff --git a/deps/v8/src/objects/transitions-inl.h b/deps/v8/src/objects/transitions-inl.h
index 893de78dc4..048774f49b 100644
--- a/deps/v8/src/objects/transitions-inl.h
+++ b/deps/v8/src/objects/transitions-inl.h
@@ -102,9 +102,8 @@ PropertyDetails TransitionsAccessor::GetTargetDetails(Name name, Map target) {
return descriptors.GetDetails(descriptor);
}
-// static
PropertyDetails TransitionsAccessor::GetSimpleTargetDetails(Map transition) {
- return transition.GetLastDescriptorDetails();
+ return transition.GetLastDescriptorDetails(isolate_);
}
// static
@@ -195,13 +194,13 @@ void TransitionsAccessor::Reload() {
}
void TransitionsAccessor::Initialize() {
- raw_transitions_ = map_.raw_transitions();
+ raw_transitions_ = map_.raw_transitions(isolate_);
HeapObject heap_object;
if (raw_transitions_->IsSmi() || raw_transitions_->IsCleared()) {
encoding_ = kUninitialized;
} else if (raw_transitions_->IsWeak()) {
encoding_ = kWeakRef;
- } else if (raw_transitions_->GetHeapObjectIfStrong(&heap_object)) {
+ } else if (raw_transitions_->GetHeapObjectIfStrong(isolate_, &heap_object)) {
if (heap_object.IsTransitionArray()) {
encoding_ = kFullTransitionArray;
} else if (heap_object.IsPrototypeInfo()) {
diff --git a/deps/v8/src/objects/transitions.cc b/deps/v8/src/objects/transitions.cc
index a2cd102aaf..843b790b7d 100644
--- a/deps/v8/src/objects/transitions.cc
+++ b/deps/v8/src/objects/transitions.cc
@@ -226,7 +226,7 @@ MaybeHandle<Map> TransitionsAccessor::FindTransitionToDataProperty(
PropertyAttributes attributes = name->IsPrivate() ? DONT_ENUM : NONE;
Map target = SearchTransition(*name, kData, attributes);
if (target.is_null()) return MaybeHandle<Map>();
- PropertyDetails details = target.GetLastDescriptorDetails();
+ PropertyDetails details = target.GetLastDescriptorDetails(isolate_);
DCHECK_EQ(attributes, details.attributes());
DCHECK_EQ(kData, details.kind());
if (requested_location == kFieldOnly && details.location() != kField) {
diff --git a/deps/v8/src/objects/transitions.h b/deps/v8/src/objects/transitions.h
index b4dadcc22a..f21e8cd54e 100644
--- a/deps/v8/src/objects/transitions.h
+++ b/deps/v8/src/objects/transitions.h
@@ -147,7 +147,7 @@ class V8_EXPORT_PRIVATE TransitionsAccessor {
friend class MarkCompactCollector; // For HasSimpleTransitionTo.
friend class TransitionArray;
- static inline PropertyDetails GetSimpleTargetDetails(Map transition);
+ inline PropertyDetails GetSimpleTargetDetails(Map transition);
static inline Name GetSimpleTransitionKey(Map transition);
diff --git a/deps/v8/src/objects/value-serializer.cc b/deps/v8/src/objects/value-serializer.cc
index 331a12b157..5a72dd6532 100644
--- a/deps/v8/src/objects/value-serializer.cc
+++ b/deps/v8/src/objects/value-serializer.cc
@@ -22,6 +22,7 @@
#include "src/objects/objects-inl.h"
#include "src/objects/oddball-inl.h"
#include "src/objects/ordered-hash-table-inl.h"
+#include "src/objects/property-descriptor.h"
#include "src/objects/smi.h"
#include "src/objects/transitions-inl.h"
#include "src/snapshot/code-serializer.h"
@@ -65,9 +66,6 @@ static size_t BytesNeededForVarint(T value) {
return result;
}
-// Note that some additional tag values are defined in Blink's
-// Source/bindings/core/v8/serialization/SerializationTag.h, which must
-// not clash with values defined here.
enum class SerializationTag : uint8_t {
// version:uint32_t (if at beginning of data, sets version > 0)
kVersion = 0xFF,
@@ -161,6 +159,40 @@ enum class SerializationTag : uint8_t {
// A transferred WebAssembly.Memory object. maximumPages:int32_t, then by
// SharedArrayBuffer tag and its data.
kWasmMemoryTransfer = 'm',
+ // A list of (subtag: ErrorTag, [subtag dependent data]). See ErrorTag for
+ // details.
+ kError = 'r',
+
+ // The following tags are reserved because they were in use in Chromium before
+ // the kHostObject tag was introduced in format version 13, at
+ // v8 refs/heads/master@{#43466}
+ // chromium/src refs/heads/master@{#453568}
+ //
+ // They must not be reused without a version check to prevent old values from
+ // starting to deserialize incorrectly. For simplicity, it's recommended to
+ // avoid them altogether.
+ //
+ // This is the set of tags that existed in SerializationTag.h at that time and
+ // still exist at the time of this writing (i.e., excluding those that were
+ // removed on the Chromium side because there should be no real user data
+ // containing them).
+ //
+ // It might be possible to also free up other tags which were never persisted
+ // (e.g. because they were used only for transfer) in the future.
+ kLegacyReservedMessagePort = 'M',
+ kLegacyReservedBlob = 'b',
+ kLegacyReservedBlobIndex = 'i',
+ kLegacyReservedFile = 'f',
+ kLegacyReservedFileIndex = 'e',
+ kLegacyReservedDOMFileSystem = 'd',
+ kLegacyReservedFileList = 'l',
+ kLegacyReservedFileListIndex = 'L',
+ kLegacyReservedImageData = '#',
+ kLegacyReservedImageBitmap = 'g',
+ kLegacyReservedImageBitmapTransfer = 'G',
+ kLegacyReservedOffscreenCanvas = 'H',
+ kLegacyReservedCryptoKey = 'K',
+ kLegacyReservedRTCCertificate = 'k',
};
namespace {
@@ -184,6 +216,28 @@ enum class WasmEncodingTag : uint8_t {
kRawBytes = 'y',
};
+// Sub-tags only meaningful for error serialization.
+enum class ErrorTag : uint8_t {
+ // The error is a EvalError. No accompanying data.
+ kEvalErrorPrototype = 'E',
+ // The error is a RangeError. No accompanying data.
+ kRangeErrorPrototype = 'R',
+ // The error is a ReferenceError. No accompanying data.
+ kReferenceErrorPrototype = 'F',
+ // The error is a SyntaxError. No accompanying data.
+ kSyntaxErrorPrototype = 'S',
+ // The error is a TypeError. No accompanying data.
+ kTypeErrorPrototype = 'T',
+ // The error is a URIError. No accompanying data.
+ kUriErrorPrototype = 'U',
+ // Followed by message: string.
+ kMessage = 'm',
+ // Followed by stack: string.
+ kStack = 's',
+ // The end of this error information.
+ kEnd = '.',
+};
+
} // namespace
ValueSerializer::ValueSerializer(Isolate* isolate,
@@ -505,8 +559,9 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) {
case JS_DATE_TYPE:
WriteJSDate(JSDate::cast(*receiver));
return ThrowIfOutOfMemory();
- case JS_VALUE_TYPE:
- return WriteJSValue(Handle<JSValue>::cast(receiver));
+ case JS_PRIMITIVE_WRAPPER_TYPE:
+ return WriteJSPrimitiveWrapper(
+ Handle<JSPrimitiveWrapper>::cast(receiver));
case JS_REGEXP_TYPE:
WriteJSRegExp(JSRegExp::cast(*receiver));
return ThrowIfOutOfMemory();
@@ -519,6 +574,8 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) {
case JS_TYPED_ARRAY_TYPE:
case JS_DATA_VIEW_TYPE:
return WriteJSArrayBufferView(JSArrayBufferView::cast(*receiver));
+ case JS_ERROR_TYPE:
+ return WriteJSError(Handle<JSObject>::cast(receiver));
case WASM_MODULE_TYPE: {
auto enabled_features = wasm::WasmFeaturesFromIsolate(isolate_);
if (!FLAG_wasm_disable_structured_cloning || enabled_features.threads) {
@@ -720,7 +777,8 @@ void ValueSerializer::WriteJSDate(JSDate date) {
WriteDouble(date.value().Number());
}
-Maybe<bool> ValueSerializer::WriteJSValue(Handle<JSValue> value) {
+Maybe<bool> ValueSerializer::WriteJSPrimitiveWrapper(
+ Handle<JSPrimitiveWrapper> value) {
Object inner_value = value->value();
if (inner_value.IsTrue(isolate_)) {
WriteTag(SerializationTag::kTrueObject);
@@ -874,6 +932,60 @@ Maybe<bool> ValueSerializer::WriteJSArrayBufferView(JSArrayBufferView view) {
return ThrowIfOutOfMemory();
}
+Maybe<bool> ValueSerializer::WriteJSError(Handle<JSObject> error) {
+ Handle<Object> stack;
+ PropertyDescriptor message_desc;
+ Maybe<bool> message_found = JSReceiver::GetOwnPropertyDescriptor(
+ isolate_, error, isolate_->factory()->message_string(), &message_desc);
+ MAYBE_RETURN(message_found, Nothing<bool>());
+
+ WriteTag(SerializationTag::kError);
+
+ Handle<HeapObject> prototype;
+ if (!JSObject::GetPrototype(isolate_, error).ToHandle(&prototype)) {
+ return Nothing<bool>();
+ }
+
+ if (*prototype == isolate_->eval_error_function()->prototype()) {
+ WriteVarint(static_cast<uint8_t>(ErrorTag::kEvalErrorPrototype));
+ } else if (*prototype == isolate_->range_error_function()->prototype()) {
+ WriteVarint(static_cast<uint8_t>(ErrorTag::kRangeErrorPrototype));
+ } else if (*prototype == isolate_->reference_error_function()->prototype()) {
+ WriteVarint(static_cast<uint8_t>(ErrorTag::kReferenceErrorPrototype));
+ } else if (*prototype == isolate_->syntax_error_function()->prototype()) {
+ WriteVarint(static_cast<uint8_t>(ErrorTag::kSyntaxErrorPrototype));
+ } else if (*prototype == isolate_->type_error_function()->prototype()) {
+ WriteVarint(static_cast<uint8_t>(ErrorTag::kTypeErrorPrototype));
+ } else if (*prototype == isolate_->uri_error_function()->prototype()) {
+ WriteVarint(static_cast<uint8_t>(ErrorTag::kUriErrorPrototype));
+ } else {
+ // The default prototype in the deserialization side is Error.prototype, so
+ // we don't have to do anything here.
+ }
+
+ if (message_found.FromJust() &&
+ PropertyDescriptor::IsDataDescriptor(&message_desc)) {
+ Handle<String> message;
+ if (!Object::ToString(isolate_, message_desc.value()).ToHandle(&message)) {
+ return Nothing<bool>();
+ }
+ WriteVarint(static_cast<uint8_t>(ErrorTag::kMessage));
+ WriteString(message);
+ }
+
+ if (!Object::GetProperty(isolate_, error, isolate_->factory()->stack_string())
+ .ToHandle(&stack)) {
+ return Nothing<bool>();
+ }
+ if (stack->IsString()) {
+ WriteVarint(static_cast<uint8_t>(ErrorTag::kStack));
+ WriteString(Handle<String>::cast(stack));
+ }
+
+ WriteVarint(static_cast<uint8_t>(ErrorTag::kEnd));
+ return ThrowIfOutOfMemory();
+}
+
Maybe<bool> ValueSerializer::WriteWasmModule(Handle<WasmModuleObject> object) {
if (delegate_ != nullptr) {
// TODO(titzer): introduce a Utils::ToLocal for WasmModuleObject.
@@ -1238,7 +1350,7 @@ MaybeHandle<Object> ValueDeserializer::ReadObjectInternal() {
case SerializationTag::kNumberObject:
case SerializationTag::kBigIntObject:
case SerializationTag::kStringObject:
- return ReadJSValue(tag);
+ return ReadJSPrimitiveWrapper(tag);
case SerializationTag::kRegExp:
return ReadJSRegExp();
case SerializationTag::kBeginJSMap:
@@ -1256,6 +1368,8 @@ MaybeHandle<Object> ValueDeserializer::ReadObjectInternal() {
const bool is_shared = true;
return ReadJSArrayBuffer(is_shared);
}
+ case SerializationTag::kError:
+ return ReadJSError();
case SerializationTag::kWasmModule:
return ReadWasmModule();
case SerializationTag::kWasmModuleTransfer:
@@ -1519,24 +1633,25 @@ MaybeHandle<JSDate> ValueDeserializer::ReadJSDate() {
return date;
}
-MaybeHandle<JSValue> ValueDeserializer::ReadJSValue(SerializationTag tag) {
+MaybeHandle<JSPrimitiveWrapper> ValueDeserializer::ReadJSPrimitiveWrapper(
+ SerializationTag tag) {
uint32_t id = next_id_++;
- Handle<JSValue> value;
+ Handle<JSPrimitiveWrapper> value;
switch (tag) {
case SerializationTag::kTrueObject:
- value = Handle<JSValue>::cast(isolate_->factory()->NewJSObject(
+ value = Handle<JSPrimitiveWrapper>::cast(isolate_->factory()->NewJSObject(
isolate_->boolean_function(), allocation_));
value->set_value(ReadOnlyRoots(isolate_).true_value());
break;
case SerializationTag::kFalseObject:
- value = Handle<JSValue>::cast(isolate_->factory()->NewJSObject(
+ value = Handle<JSPrimitiveWrapper>::cast(isolate_->factory()->NewJSObject(
isolate_->boolean_function(), allocation_));
value->set_value(ReadOnlyRoots(isolate_).false_value());
break;
case SerializationTag::kNumberObject: {
double number;
- if (!ReadDouble().To(&number)) return MaybeHandle<JSValue>();
- value = Handle<JSValue>::cast(isolate_->factory()->NewJSObject(
+ if (!ReadDouble().To(&number)) return MaybeHandle<JSPrimitiveWrapper>();
+ value = Handle<JSPrimitiveWrapper>::cast(isolate_->factory()->NewJSObject(
isolate_->number_function(), allocation_));
Handle<Object> number_object =
isolate_->factory()->NewNumber(number, allocation_);
@@ -1545,16 +1660,18 @@ MaybeHandle<JSValue> ValueDeserializer::ReadJSValue(SerializationTag tag) {
}
case SerializationTag::kBigIntObject: {
Handle<BigInt> bigint;
- if (!ReadBigInt().ToHandle(&bigint)) return MaybeHandle<JSValue>();
- value = Handle<JSValue>::cast(isolate_->factory()->NewJSObject(
+ if (!ReadBigInt().ToHandle(&bigint))
+ return MaybeHandle<JSPrimitiveWrapper>();
+ value = Handle<JSPrimitiveWrapper>::cast(isolate_->factory()->NewJSObject(
isolate_->bigint_function(), allocation_));
value->set_value(*bigint);
break;
}
case SerializationTag::kStringObject: {
Handle<String> string;
- if (!ReadString().ToHandle(&string)) return MaybeHandle<JSValue>();
- value = Handle<JSValue>::cast(isolate_->factory()->NewJSObject(
+ if (!ReadString().ToHandle(&string))
+ return MaybeHandle<JSPrimitiveWrapper>();
+ value = Handle<JSPrimitiveWrapper>::cast(isolate_->factory()->NewJSObject(
isolate_->string_function(), allocation_));
value->set_value(*string);
break;
@@ -1578,7 +1695,7 @@ MaybeHandle<JSRegExp> ValueDeserializer::ReadJSRegExp() {
// Ensure the deserialized flags are valid.
// TODO(adamk): Can we remove this check now that dotAll is always-on?
- uint32_t flags_mask = static_cast<uint32_t>(-1) << JSRegExp::FlagCount();
+ uint32_t flags_mask = static_cast<uint32_t>(-1) << JSRegExp::kFlagCount;
if ((raw_flags & flags_mask) ||
!JSRegExp::New(isolate_, pattern, static_cast<JSRegExp::Flags>(raw_flags))
.ToHandle(&regexp)) {
@@ -1768,6 +1885,78 @@ MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView(
return typed_array;
}
+MaybeHandle<Object> ValueDeserializer::ReadJSError() {
+ Handle<Object> message = isolate_->factory()->undefined_value();
+ Handle<Object> stack = isolate_->factory()->undefined_value();
+ Handle<Object> no_caller;
+ auto constructor = isolate_->error_function();
+ bool done = false;
+
+ while (!done) {
+ uint8_t tag;
+ if (!ReadVarint<uint8_t>().To(&tag)) {
+ return MaybeHandle<JSObject>();
+ }
+ switch (static_cast<ErrorTag>(tag)) {
+ case ErrorTag::kEvalErrorPrototype:
+ constructor = isolate_->eval_error_function();
+ break;
+ case ErrorTag::kRangeErrorPrototype:
+ constructor = isolate_->range_error_function();
+ break;
+ case ErrorTag::kReferenceErrorPrototype:
+ constructor = isolate_->reference_error_function();
+ break;
+ case ErrorTag::kSyntaxErrorPrototype:
+ constructor = isolate_->syntax_error_function();
+ break;
+ case ErrorTag::kTypeErrorPrototype:
+ constructor = isolate_->type_error_function();
+ break;
+ case ErrorTag::kUriErrorPrototype:
+ constructor = isolate_->uri_error_function();
+ break;
+ case ErrorTag::kMessage: {
+ Handle<String> message_string;
+ if (!ReadString().ToHandle(&message_string)) {
+ return MaybeHandle<JSObject>();
+ }
+ message = message_string;
+ break;
+ }
+ case ErrorTag::kStack: {
+ Handle<String> stack_string;
+ if (!ReadString().ToHandle(&stack_string)) {
+ return MaybeHandle<JSObject>();
+ }
+ stack = stack_string;
+ break;
+ }
+ case ErrorTag::kEnd:
+ done = true;
+ break;
+ default:
+ return MaybeHandle<JSObject>();
+ }
+ }
+
+ Handle<Object> error;
+ if (!ErrorUtils::Construct(isolate_, constructor, constructor, message,
+ SKIP_NONE, no_caller,
+ ErrorUtils::StackTraceCollection::kNone)
+ .ToHandle(&error)) {
+ return MaybeHandle<Object>();
+ }
+
+ if (Object::SetProperty(
+ isolate_, error, isolate_->factory()->stack_trace_symbol(), stack,
+ StoreOrigin::kMaybeKeyed, Just(ShouldThrow::kThrowOnError))
+ .is_null()) {
+ return MaybeHandle<Object>();
+ }
+ return error;
+}
+
MaybeHandle<JSObject> ValueDeserializer::ReadWasmModuleTransfer() {
auto enabled_features = wasm::WasmFeaturesFromIsolate(isolate_);
if ((FLAG_wasm_disable_structured_cloning && !enabled_features.threads) ||
diff --git a/deps/v8/src/objects/value-serializer.h b/deps/v8/src/objects/value-serializer.h
index b83227d9d3..9e381d7e76 100644
--- a/deps/v8/src/objects/value-serializer.h
+++ b/deps/v8/src/objects/value-serializer.h
@@ -11,7 +11,7 @@
#include "include/v8.h"
#include "src/base/compiler-specific.h"
#include "src/base/macros.h"
-#include "src/execution/message-template.h"
+#include "src/common/message-template.h"
#include "src/handles/maybe-handles.h"
#include "src/utils/identity-map.h"
#include "src/utils/vector.h"
@@ -27,9 +27,9 @@ class JSArrayBuffer;
class JSArrayBufferView;
class JSDate;
class JSMap;
+class JSPrimitiveWrapper;
class JSRegExp;
class JSSet;
-class JSValue;
class MutableHeapNumber;
class Object;
class Oddball;
@@ -120,13 +120,15 @@ class ValueSerializer {
Maybe<bool> WriteJSObjectSlow(Handle<JSObject> object) V8_WARN_UNUSED_RESULT;
Maybe<bool> WriteJSArray(Handle<JSArray> array) V8_WARN_UNUSED_RESULT;
void WriteJSDate(JSDate date);
- Maybe<bool> WriteJSValue(Handle<JSValue> value) V8_WARN_UNUSED_RESULT;
+ Maybe<bool> WriteJSPrimitiveWrapper(Handle<JSPrimitiveWrapper> value)
+ V8_WARN_UNUSED_RESULT;
void WriteJSRegExp(JSRegExp regexp);
Maybe<bool> WriteJSMap(Handle<JSMap> map) V8_WARN_UNUSED_RESULT;
Maybe<bool> WriteJSSet(Handle<JSSet> map) V8_WARN_UNUSED_RESULT;
Maybe<bool> WriteJSArrayBuffer(Handle<JSArrayBuffer> array_buffer)
V8_WARN_UNUSED_RESULT;
Maybe<bool> WriteJSArrayBufferView(JSArrayBufferView array_buffer);
+ Maybe<bool> WriteJSError(Handle<JSObject> error) V8_WARN_UNUSED_RESULT;
Maybe<bool> WriteWasmModule(Handle<WasmModuleObject> object)
V8_WARN_UNUSED_RESULT;
Maybe<bool> WriteWasmMemory(Handle<WasmMemoryObject> object)
@@ -264,7 +266,8 @@ class ValueDeserializer {
MaybeHandle<JSArray> ReadSparseJSArray() V8_WARN_UNUSED_RESULT;
MaybeHandle<JSArray> ReadDenseJSArray() V8_WARN_UNUSED_RESULT;
MaybeHandle<JSDate> ReadJSDate() V8_WARN_UNUSED_RESULT;
- MaybeHandle<JSValue> ReadJSValue(SerializationTag tag) V8_WARN_UNUSED_RESULT;
+ MaybeHandle<JSPrimitiveWrapper> ReadJSPrimitiveWrapper(SerializationTag tag)
+ V8_WARN_UNUSED_RESULT;
MaybeHandle<JSRegExp> ReadJSRegExp() V8_WARN_UNUSED_RESULT;
MaybeHandle<JSMap> ReadJSMap() V8_WARN_UNUSED_RESULT;
MaybeHandle<JSSet> ReadJSSet() V8_WARN_UNUSED_RESULT;
@@ -274,6 +277,7 @@ class ValueDeserializer {
V8_WARN_UNUSED_RESULT;
MaybeHandle<JSArrayBufferView> ReadJSArrayBufferView(
Handle<JSArrayBuffer> buffer) V8_WARN_UNUSED_RESULT;
+ MaybeHandle<Object> ReadJSError() V8_WARN_UNUSED_RESULT;
MaybeHandle<JSObject> ReadWasmModule() V8_WARN_UNUSED_RESULT;
MaybeHandle<JSObject> ReadWasmModuleTransfer() V8_WARN_UNUSED_RESULT;
MaybeHandle<WasmMemoryObject> ReadWasmMemory() V8_WARN_UNUSED_RESULT;