deps: patch V8 to 6.5.254.38
PR-URL: https://github.com/nodejs/node/pull/19303 Refs: https://github.com/v8/v8/compare/6.5.254.31...6.5.254.38 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
parent
14809aaa98
commit
040dd244de
1
deps/v8/AUTHORS
vendored
1
deps/v8/AUTHORS
vendored
@ -136,7 +136,6 @@ Sanjoy Das <sanjoy@playingwithpointers.com>
|
|||||||
Seo Sanghyeon <sanxiyn@gmail.com>
|
Seo Sanghyeon <sanxiyn@gmail.com>
|
||||||
Stefan Penner <stefan.penner@gmail.com>
|
Stefan Penner <stefan.penner@gmail.com>
|
||||||
Sylvestre Ledru <sledru@mozilla.com>
|
Sylvestre Ledru <sledru@mozilla.com>
|
||||||
Taketoshi Aono <brn@b6n.ch>
|
|
||||||
Tiancheng "Timothy" Gu <timothygu99@gmail.com>
|
Tiancheng "Timothy" Gu <timothygu99@gmail.com>
|
||||||
Tobias Burnus <burnus@net-b.de>
|
Tobias Burnus <burnus@net-b.de>
|
||||||
Victor Costan <costan@gmail.com>
|
Victor Costan <costan@gmail.com>
|
||||||
|
2
deps/v8/include/v8-version.h
vendored
2
deps/v8/include/v8-version.h
vendored
@ -11,7 +11,7 @@
|
|||||||
#define V8_MAJOR_VERSION 6
|
#define V8_MAJOR_VERSION 6
|
||||||
#define V8_MINOR_VERSION 5
|
#define V8_MINOR_VERSION 5
|
||||||
#define V8_BUILD_NUMBER 254
|
#define V8_BUILD_NUMBER 254
|
||||||
#define V8_PATCH_LEVEL 31
|
#define V8_PATCH_LEVEL 38
|
||||||
|
|
||||||
// Use 1 for candidates and 0 otherwise.
|
// Use 1 for candidates and 0 otherwise.
|
||||||
// (Boolean macro values are not supported by all preprocessors.)
|
// (Boolean macro values are not supported by all preprocessors.)
|
||||||
|
4
deps/v8/src/bootstrapper.cc
vendored
4
deps/v8/src/bootstrapper.cc
vendored
@ -1508,9 +1508,9 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
|||||||
object_function, "keys", Builtins::kObjectKeys, 1, true);
|
object_function, "keys", Builtins::kObjectKeys, 1, true);
|
||||||
native_context()->set_object_keys(*object_keys);
|
native_context()->set_object_keys(*object_keys);
|
||||||
SimpleInstallFunction(object_function, factory->entries_string(),
|
SimpleInstallFunction(object_function, factory->entries_string(),
|
||||||
Builtins::kObjectEntries, 1, true);
|
Builtins::kObjectEntries, 1, false);
|
||||||
SimpleInstallFunction(object_function, factory->values_string(),
|
SimpleInstallFunction(object_function, factory->values_string(),
|
||||||
Builtins::kObjectValues, 1, true);
|
Builtins::kObjectValues, 1, false);
|
||||||
|
|
||||||
SimpleInstallFunction(isolate->initial_object_prototype(),
|
SimpleInstallFunction(isolate->initial_object_prototype(),
|
||||||
"__defineGetter__", Builtins::kObjectDefineGetter, 2,
|
"__defineGetter__", Builtins::kObjectDefineGetter, 2,
|
||||||
|
4
deps/v8/src/builtins/builtins-definitions.h
vendored
4
deps/v8/src/builtins/builtins-definitions.h
vendored
@ -755,7 +755,7 @@ namespace internal {
|
|||||||
CPP(ObjectDefineProperties) \
|
CPP(ObjectDefineProperties) \
|
||||||
CPP(ObjectDefineProperty) \
|
CPP(ObjectDefineProperty) \
|
||||||
CPP(ObjectDefineSetter) \
|
CPP(ObjectDefineSetter) \
|
||||||
TFJ(ObjectEntries, 1, kObject) \
|
CPP(ObjectEntries) \
|
||||||
CPP(ObjectFreeze) \
|
CPP(ObjectFreeze) \
|
||||||
TFJ(ObjectGetOwnPropertyDescriptor, \
|
TFJ(ObjectGetOwnPropertyDescriptor, \
|
||||||
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
||||||
@ -785,7 +785,7 @@ namespace internal {
|
|||||||
/* ES #sec-object.prototype.tolocalestring */ \
|
/* ES #sec-object.prototype.tolocalestring */ \
|
||||||
TFJ(ObjectPrototypeToLocaleString, 0) \
|
TFJ(ObjectPrototypeToLocaleString, 0) \
|
||||||
CPP(ObjectSeal) \
|
CPP(ObjectSeal) \
|
||||||
TFJ(ObjectValues, 1, kObject) \
|
CPP(ObjectValues) \
|
||||||
\
|
\
|
||||||
/* instanceof */ \
|
/* instanceof */ \
|
||||||
TFC(OrdinaryHasInstance, Compare, 1) \
|
TFC(OrdinaryHasInstance, Compare, 1) \
|
||||||
|
301
deps/v8/src/builtins/builtins-object-gen.cc
vendored
301
deps/v8/src/builtins/builtins-object-gen.cc
vendored
@ -16,8 +16,6 @@ namespace internal {
|
|||||||
// ES6 section 19.1 Object Objects
|
// ES6 section 19.1 Object Objects
|
||||||
|
|
||||||
typedef compiler::Node Node;
|
typedef compiler::Node Node;
|
||||||
template <class T>
|
|
||||||
using TNode = CodeStubAssembler::TNode<T>;
|
|
||||||
|
|
||||||
class ObjectBuiltinsAssembler : public CodeStubAssembler {
|
class ObjectBuiltinsAssembler : public CodeStubAssembler {
|
||||||
public:
|
public:
|
||||||
@ -36,46 +34,6 @@ class ObjectBuiltinsAssembler : public CodeStubAssembler {
|
|||||||
Node* ConstructDataDescriptor(Node* context, Node* value, Node* writable,
|
Node* ConstructDataDescriptor(Node* context, Node* value, Node* writable,
|
||||||
Node* enumerable, Node* configurable);
|
Node* enumerable, Node* configurable);
|
||||||
Node* GetAccessorOrUndefined(Node* accessor, Label* if_bailout);
|
Node* GetAccessorOrUndefined(Node* accessor, Label* if_bailout);
|
||||||
|
|
||||||
Node* IsSpecialReceiverMap(SloppyTNode<Map> map);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ObjectEntriesValuesBuiltinsAssembler : public ObjectBuiltinsAssembler {
|
|
||||||
public:
|
|
||||||
explicit ObjectEntriesValuesBuiltinsAssembler(
|
|
||||||
compiler::CodeAssemblerState* state)
|
|
||||||
: ObjectBuiltinsAssembler(state) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
enum CollectType { kEntries, kValues };
|
|
||||||
|
|
||||||
TNode<Word32T> IsStringWrapperElementsKind(TNode<Map> map);
|
|
||||||
|
|
||||||
TNode<BoolT> IsPropertyEnumerable(TNode<Uint32T> details);
|
|
||||||
|
|
||||||
TNode<BoolT> IsPropertyKindAccessor(TNode<Uint32T> kind);
|
|
||||||
|
|
||||||
TNode<BoolT> IsPropertyKindData(TNode<Uint32T> kind);
|
|
||||||
|
|
||||||
TNode<Uint32T> HasHiddenPrototype(TNode<Map> map);
|
|
||||||
|
|
||||||
TNode<Uint32T> LoadPropertyKind(TNode<Uint32T> details) {
|
|
||||||
return DecodeWord32<PropertyDetails::KindField>(details);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetOwnValuesOrEntries(TNode<Context> context, TNode<Object> maybe_object,
|
|
||||||
CollectType collect_type);
|
|
||||||
|
|
||||||
void GotoIfMapHasSlowProperties(TNode<Map> map, Label* if_slow);
|
|
||||||
|
|
||||||
TNode<JSArray> FastGetOwnValuesOrEntries(
|
|
||||||
TNode<Context> context, TNode<JSObject> object,
|
|
||||||
Label* if_call_runtime_with_fast_path, Label* if_no_properties,
|
|
||||||
CollectType collect_type);
|
|
||||||
|
|
||||||
TNode<JSArray> FinalizeValuesOrEntriesJSArray(
|
|
||||||
TNode<Context> context, TNode<FixedArray> values_or_entries,
|
|
||||||
TNode<IntPtrT> size, TNode<Map> array_map, Label* if_empty);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void ObjectBuiltinsAssembler::ReturnToStringFormat(Node* context,
|
void ObjectBuiltinsAssembler::ReturnToStringFormat(Node* context,
|
||||||
@ -139,249 +97,6 @@ Node* ObjectBuiltinsAssembler::ConstructDataDescriptor(Node* context,
|
|||||||
return js_desc;
|
return js_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* ObjectBuiltinsAssembler::IsSpecialReceiverMap(SloppyTNode<Map> map) {
|
|
||||||
CSA_SLOW_ASSERT(this, IsMap(map));
|
|
||||||
Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map));
|
|
||||||
uint32_t mask =
|
|
||||||
Map::HasNamedInterceptorBit::kMask | Map::IsAccessCheckNeededBit::kMask;
|
|
||||||
USE(mask);
|
|
||||||
// Interceptors or access checks imply special receiver.
|
|
||||||
CSA_ASSERT(this,
|
|
||||||
SelectConstant(IsSetWord32(LoadMapBitField(map), mask), is_special,
|
|
||||||
Int32Constant(1), MachineRepresentation::kWord32));
|
|
||||||
return is_special;
|
|
||||||
}
|
|
||||||
|
|
||||||
TNode<Word32T>
|
|
||||||
ObjectEntriesValuesBuiltinsAssembler::IsStringWrapperElementsKind(
|
|
||||||
TNode<Map> map) {
|
|
||||||
Node* kind = LoadMapElementsKind(map);
|
|
||||||
return Word32Or(
|
|
||||||
Word32Equal(kind, Int32Constant(FAST_STRING_WRAPPER_ELEMENTS)),
|
|
||||||
Word32Equal(kind, Int32Constant(SLOW_STRING_WRAPPER_ELEMENTS)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TNode<BoolT> ObjectEntriesValuesBuiltinsAssembler::IsPropertyEnumerable(
|
|
||||||
TNode<Uint32T> details) {
|
|
||||||
TNode<Uint32T> attributes =
|
|
||||||
DecodeWord32<PropertyDetails::AttributesField>(details);
|
|
||||||
return IsNotSetWord32(attributes, PropertyAttributes::DONT_ENUM);
|
|
||||||
}
|
|
||||||
|
|
||||||
TNode<BoolT> ObjectEntriesValuesBuiltinsAssembler::IsPropertyKindAccessor(
|
|
||||||
TNode<Uint32T> kind) {
|
|
||||||
return Word32Equal(kind, Int32Constant(PropertyKind::kAccessor));
|
|
||||||
}
|
|
||||||
|
|
||||||
TNode<BoolT> ObjectEntriesValuesBuiltinsAssembler::IsPropertyKindData(
|
|
||||||
TNode<Uint32T> kind) {
|
|
||||||
return Word32Equal(kind, Int32Constant(PropertyKind::kData));
|
|
||||||
}
|
|
||||||
|
|
||||||
TNode<Uint32T> ObjectEntriesValuesBuiltinsAssembler::HasHiddenPrototype(
|
|
||||||
TNode<Map> map) {
|
|
||||||
TNode<Uint32T> bit_field3 = LoadMapBitField3(map);
|
|
||||||
return DecodeWord32<Map::HasHiddenPrototypeBit>(bit_field3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ObjectEntriesValuesBuiltinsAssembler::GetOwnValuesOrEntries(
|
|
||||||
TNode<Context> context, TNode<Object> maybe_object,
|
|
||||||
CollectType collect_type) {
|
|
||||||
TNode<JSObject> object = TNode<JSObject>::UncheckedCast(
|
|
||||||
CallBuiltin(Builtins::kToObject, context, maybe_object));
|
|
||||||
|
|
||||||
Label if_call_runtime_with_fast_path(this, Label::kDeferred),
|
|
||||||
if_call_runtime(this, Label::kDeferred),
|
|
||||||
if_no_properties(this, Label::kDeferred);
|
|
||||||
|
|
||||||
TNode<Map> map = LoadMap(object);
|
|
||||||
GotoIfNot(IsJSObjectMap(map), &if_call_runtime);
|
|
||||||
GotoIfMapHasSlowProperties(map, &if_call_runtime);
|
|
||||||
|
|
||||||
TNode<FixedArrayBase> elements = LoadElements(object);
|
|
||||||
// If the object has elements, we treat it as slow case.
|
|
||||||
// So, we go to runtime call.
|
|
||||||
GotoIfNot(IsEmptyFixedArray(elements), &if_call_runtime_with_fast_path);
|
|
||||||
|
|
||||||
TNode<JSArray> result = FastGetOwnValuesOrEntries(
|
|
||||||
context, object, &if_call_runtime_with_fast_path, &if_no_properties,
|
|
||||||
collect_type);
|
|
||||||
Return(result);
|
|
||||||
|
|
||||||
BIND(&if_no_properties);
|
|
||||||
{
|
|
||||||
Node* native_context = LoadNativeContext(context);
|
|
||||||
Node* array_map = LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context);
|
|
||||||
Node* empty_array = AllocateJSArray(PACKED_ELEMENTS, array_map,
|
|
||||||
IntPtrConstant(0), SmiConstant(0));
|
|
||||||
Return(empty_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
BIND(&if_call_runtime_with_fast_path);
|
|
||||||
{
|
|
||||||
// In slow case, we simply call runtime.
|
|
||||||
if (collect_type == CollectType::kEntries) {
|
|
||||||
Return(CallRuntime(Runtime::kObjectEntries, context, object));
|
|
||||||
} else {
|
|
||||||
DCHECK(collect_type == CollectType::kValues);
|
|
||||||
Return(CallRuntime(Runtime::kObjectValues, context, object));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BIND(&if_call_runtime);
|
|
||||||
{
|
|
||||||
// In slow case, we simply call runtime.
|
|
||||||
if (collect_type == CollectType::kEntries) {
|
|
||||||
Return(CallRuntime(Runtime::kObjectEntriesSkipFastPath, context, object));
|
|
||||||
} else {
|
|
||||||
DCHECK(collect_type == CollectType::kValues);
|
|
||||||
Return(CallRuntime(Runtime::kObjectValuesSkipFastPath, context, object));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ObjectEntriesValuesBuiltinsAssembler::GotoIfMapHasSlowProperties(
|
|
||||||
TNode<Map> map, Label* if_slow) {
|
|
||||||
GotoIf(IsStringWrapperElementsKind(map), if_slow);
|
|
||||||
GotoIf(IsSpecialReceiverMap(map), if_slow);
|
|
||||||
GotoIf(HasHiddenPrototype(map), if_slow);
|
|
||||||
GotoIf(IsDictionaryMap(map), if_slow);
|
|
||||||
}
|
|
||||||
|
|
||||||
TNode<JSArray> ObjectEntriesValuesBuiltinsAssembler::FastGetOwnValuesOrEntries(
|
|
||||||
TNode<Context> context, TNode<JSObject> object,
|
|
||||||
Label* if_call_runtime_with_fast_path, Label* if_no_properties,
|
|
||||||
CollectType collect_type) {
|
|
||||||
Node* native_context = LoadNativeContext(context);
|
|
||||||
TNode<Map> array_map =
|
|
||||||
LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context);
|
|
||||||
TNode<Map> map = LoadMap(object);
|
|
||||||
TNode<Uint32T> bit_field3 = LoadMapBitField3(map);
|
|
||||||
|
|
||||||
Label if_has_enum_cache(this), if_not_has_enum_cache(this),
|
|
||||||
collect_entries(this);
|
|
||||||
Node* object_enum_length =
|
|
||||||
DecodeWordFromWord32<Map::EnumLengthBits>(bit_field3);
|
|
||||||
Node* has_enum_cache = WordNotEqual(
|
|
||||||
object_enum_length, IntPtrConstant(kInvalidEnumCacheSentinel));
|
|
||||||
|
|
||||||
// In case, we found enum_cache in object,
|
|
||||||
// we use it as array_length becuase it has same size for
|
|
||||||
// Object.(entries/values) result array object length.
|
|
||||||
// So object_enum_length use less memory space than
|
|
||||||
// NumberOfOwnDescriptorsBits value.
|
|
||||||
// And in case, if enum_cache_not_found,
|
|
||||||
// we call runtime and initialize enum_cache for subsequent call of
|
|
||||||
// CSA fast path.
|
|
||||||
Branch(has_enum_cache, &if_has_enum_cache, if_call_runtime_with_fast_path);
|
|
||||||
|
|
||||||
BIND(&if_has_enum_cache);
|
|
||||||
{
|
|
||||||
GotoIf(WordEqual(object_enum_length, IntPtrConstant(0)), if_no_properties);
|
|
||||||
TNode<FixedArray> values_or_entries = TNode<FixedArray>::UncheckedCast(
|
|
||||||
AllocateFixedArray(PACKED_ELEMENTS, object_enum_length,
|
|
||||||
INTPTR_PARAMETERS, kAllowLargeObjectAllocation));
|
|
||||||
|
|
||||||
// If in case we have enum_cache,
|
|
||||||
// we can't detect accessor of object until loop through descritpros.
|
|
||||||
// So if object might have accessor,
|
|
||||||
// we will remain invalid addresses of FixedArray.
|
|
||||||
// Because in that case, we need to jump to runtime call.
|
|
||||||
// So the array filled by the-hole even if enum_cache exists.
|
|
||||||
FillFixedArrayWithValue(PACKED_ELEMENTS, values_or_entries,
|
|
||||||
IntPtrConstant(0), object_enum_length,
|
|
||||||
Heap::kTheHoleValueRootIndex);
|
|
||||||
|
|
||||||
TVARIABLE(IntPtrT, var_result_index, IntPtrConstant(0));
|
|
||||||
TVARIABLE(IntPtrT, var_descriptor_index, IntPtrConstant(0));
|
|
||||||
Variable* vars[] = {&var_descriptor_index, &var_result_index};
|
|
||||||
// Let desc be ? O.[[GetOwnProperty]](key).
|
|
||||||
TNode<DescriptorArray> descriptors = LoadMapDescriptors(map);
|
|
||||||
Label loop(this, 2, vars), after_loop(this), loop_condition(this);
|
|
||||||
Branch(IntPtrEqual(var_descriptor_index, object_enum_length), &after_loop,
|
|
||||||
&loop);
|
|
||||||
|
|
||||||
// We dont use BuildFastLoop.
|
|
||||||
// Instead, we use hand-written loop
|
|
||||||
// because of we need to use 'continue' functionality.
|
|
||||||
BIND(&loop);
|
|
||||||
{
|
|
||||||
// Currently, we will not invoke getters,
|
|
||||||
// so, map will not be changed.
|
|
||||||
CSA_ASSERT(this, WordEqual(map, LoadMap(object)));
|
|
||||||
TNode<Uint32T> descriptor_index = TNode<Uint32T>::UncheckedCast(
|
|
||||||
TruncateWordToWord32(var_descriptor_index));
|
|
||||||
Node* next_key = DescriptorArrayGetKey(descriptors, descriptor_index);
|
|
||||||
|
|
||||||
// Skip Symbols.
|
|
||||||
GotoIf(IsSymbol(next_key), &loop_condition);
|
|
||||||
|
|
||||||
TNode<Uint32T> details = TNode<Uint32T>::UncheckedCast(
|
|
||||||
DescriptorArrayGetDetails(descriptors, descriptor_index));
|
|
||||||
TNode<Uint32T> kind = LoadPropertyKind(details);
|
|
||||||
|
|
||||||
// If property is accessor, we escape fast path and call runtime.
|
|
||||||
GotoIf(IsPropertyKindAccessor(kind), if_call_runtime_with_fast_path);
|
|
||||||
CSA_ASSERT(this, IsPropertyKindData(kind));
|
|
||||||
|
|
||||||
// If desc is not undefined and desc.[[Enumerable]] is true, then
|
|
||||||
GotoIfNot(IsPropertyEnumerable(details), &loop_condition);
|
|
||||||
|
|
||||||
VARIABLE(var_property_value, MachineRepresentation::kTagged,
|
|
||||||
UndefinedConstant());
|
|
||||||
Node* descriptor_name_index = DescriptorNumberToIndex(descriptor_index);
|
|
||||||
|
|
||||||
// Let value be ? Get(O, key).
|
|
||||||
LoadPropertyFromFastObject(object, map, descriptors,
|
|
||||||
descriptor_name_index, details,
|
|
||||||
&var_property_value);
|
|
||||||
|
|
||||||
// If kind is "value", append value to properties.
|
|
||||||
Node* value = var_property_value.value();
|
|
||||||
|
|
||||||
if (collect_type == CollectType::kEntries) {
|
|
||||||
// Let entry be CreateArrayFromList(« key, value »).
|
|
||||||
Node* array = nullptr;
|
|
||||||
Node* elements = nullptr;
|
|
||||||
std::tie(array, elements) = AllocateUninitializedJSArrayWithElements(
|
|
||||||
PACKED_ELEMENTS, array_map, SmiConstant(2), nullptr,
|
|
||||||
IntPtrConstant(2));
|
|
||||||
StoreFixedArrayElement(elements, 0, next_key, SKIP_WRITE_BARRIER);
|
|
||||||
StoreFixedArrayElement(elements, 1, value, SKIP_WRITE_BARRIER);
|
|
||||||
value = array;
|
|
||||||
}
|
|
||||||
|
|
||||||
StoreFixedArrayElement(values_or_entries, var_result_index, value);
|
|
||||||
Increment(&var_result_index, 1);
|
|
||||||
Goto(&loop_condition);
|
|
||||||
|
|
||||||
BIND(&loop_condition);
|
|
||||||
{
|
|
||||||
Increment(&var_descriptor_index, 1);
|
|
||||||
Branch(IntPtrEqual(var_descriptor_index, object_enum_length),
|
|
||||||
&after_loop, &loop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BIND(&after_loop);
|
|
||||||
return FinalizeValuesOrEntriesJSArray(context, values_or_entries,
|
|
||||||
var_result_index, array_map,
|
|
||||||
if_no_properties);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TNode<JSArray>
|
|
||||||
ObjectEntriesValuesBuiltinsAssembler::FinalizeValuesOrEntriesJSArray(
|
|
||||||
TNode<Context> context, TNode<FixedArray> result, TNode<IntPtrT> size,
|
|
||||||
TNode<Map> array_map, Label* if_empty) {
|
|
||||||
CSA_ASSERT(this, IsJSArrayMap(array_map));
|
|
||||||
|
|
||||||
GotoIf(IntPtrEqual(size, IntPtrConstant(0)), if_empty);
|
|
||||||
Node* array = AllocateUninitializedJSArrayWithoutElements(
|
|
||||||
array_map, SmiTag(size), nullptr);
|
|
||||||
StoreObjectField(array, JSArray::kElementsOffset, result);
|
|
||||||
return TNode<JSArray>::UncheckedCast(array);
|
|
||||||
}
|
|
||||||
|
|
||||||
TF_BUILTIN(ObjectPrototypeToLocaleString, CodeStubAssembler) {
|
TF_BUILTIN(ObjectPrototypeToLocaleString, CodeStubAssembler) {
|
||||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
||||||
@ -551,22 +266,6 @@ TF_BUILTIN(ObjectKeys, ObjectBuiltinsAssembler) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TF_BUILTIN(ObjectValues, ObjectEntriesValuesBuiltinsAssembler) {
|
|
||||||
TNode<JSObject> object =
|
|
||||||
TNode<JSObject>::UncheckedCast(Parameter(Descriptor::kObject));
|
|
||||||
TNode<Context> context =
|
|
||||||
TNode<Context>::UncheckedCast(Parameter(Descriptor::kContext));
|
|
||||||
GetOwnValuesOrEntries(context, object, CollectType::kValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
TF_BUILTIN(ObjectEntries, ObjectEntriesValuesBuiltinsAssembler) {
|
|
||||||
TNode<JSObject> object =
|
|
||||||
TNode<JSObject>::UncheckedCast(Parameter(Descriptor::kObject));
|
|
||||||
TNode<Context> context =
|
|
||||||
TNode<Context>::UncheckedCast(Parameter(Descriptor::kContext));
|
|
||||||
GetOwnValuesOrEntries(context, object, CollectType::kEntries);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ES #sec-object.prototype.isprototypeof
|
// ES #sec-object.prototype.isprototypeof
|
||||||
TF_BUILTIN(ObjectPrototypeIsPrototypeOf, ObjectBuiltinsAssembler) {
|
TF_BUILTIN(ObjectPrototypeIsPrototypeOf, ObjectBuiltinsAssembler) {
|
||||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||||
|
25
deps/v8/src/builtins/builtins-object.cc
vendored
25
deps/v8/src/builtins/builtins-object.cc
vendored
@ -395,6 +395,31 @@ BUILTIN(ObjectIsSealed) {
|
|||||||
return isolate->heap()->ToBoolean(result.FromJust());
|
return isolate->heap()->ToBoolean(result.FromJust());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BUILTIN(ObjectValues) {
|
||||||
|
HandleScope scope(isolate);
|
||||||
|
Handle<Object> object = args.atOrUndefined(isolate, 1);
|
||||||
|
Handle<JSReceiver> receiver;
|
||||||
|
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
|
||||||
|
Object::ToObject(isolate, object));
|
||||||
|
Handle<FixedArray> values;
|
||||||
|
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||||
|
isolate, values, JSReceiver::GetOwnValues(receiver, ENUMERABLE_STRINGS));
|
||||||
|
return *isolate->factory()->NewJSArrayWithElements(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
BUILTIN(ObjectEntries) {
|
||||||
|
HandleScope scope(isolate);
|
||||||
|
Handle<Object> object = args.atOrUndefined(isolate, 1);
|
||||||
|
Handle<JSReceiver> receiver;
|
||||||
|
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
|
||||||
|
Object::ToObject(isolate, object));
|
||||||
|
Handle<FixedArray> entries;
|
||||||
|
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||||
|
isolate, entries,
|
||||||
|
JSReceiver::GetOwnEntries(receiver, ENUMERABLE_STRINGS));
|
||||||
|
return *isolate->factory()->NewJSArrayWithElements(entries);
|
||||||
|
}
|
||||||
|
|
||||||
BUILTIN(ObjectGetOwnPropertyDescriptors) {
|
BUILTIN(ObjectGetOwnPropertyDescriptors) {
|
||||||
HandleScope scope(isolate);
|
HandleScope scope(isolate);
|
||||||
Handle<Object> object = args.atOrUndefined(isolate, 1);
|
Handle<Object> object = args.atOrUndefined(isolate, 1);
|
||||||
|
59
deps/v8/src/code-stub-assembler.cc
vendored
59
deps/v8/src/code-stub-assembler.cc
vendored
@ -4019,6 +4019,19 @@ Node* CodeStubAssembler::InstanceTypeEqual(Node* instance_type, int type) {
|
|||||||
return Word32Equal(instance_type, Int32Constant(type));
|
return Word32Equal(instance_type, Int32Constant(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) {
|
||||||
|
CSA_SLOW_ASSERT(this, IsMap(map));
|
||||||
|
Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map));
|
||||||
|
uint32_t mask =
|
||||||
|
Map::HasNamedInterceptorBit::kMask | Map::IsAccessCheckNeededBit::kMask;
|
||||||
|
USE(mask);
|
||||||
|
// Interceptors or access checks imply special receiver.
|
||||||
|
CSA_ASSERT(this,
|
||||||
|
SelectConstant(IsSetWord32(LoadMapBitField(map), mask), is_special,
|
||||||
|
Int32Constant(1), MachineRepresentation::kWord32));
|
||||||
|
return is_special;
|
||||||
|
}
|
||||||
|
|
||||||
TNode<BoolT> CodeStubAssembler::IsDictionaryMap(SloppyTNode<Map> map) {
|
TNode<BoolT> CodeStubAssembler::IsDictionaryMap(SloppyTNode<Map> map) {
|
||||||
CSA_SLOW_ASSERT(this, IsMap(map));
|
CSA_SLOW_ASSERT(this, IsMap(map));
|
||||||
Node* bit_field3 = LoadMapBitField3(map);
|
Node* bit_field3 = LoadMapBitField3(map);
|
||||||
@ -6369,38 +6382,36 @@ Node* CodeStubAssembler::DescriptorArrayNumberOfEntries(Node* descriptors) {
|
|||||||
descriptors, IntPtrConstant(DescriptorArray::kDescriptorLengthIndex));
|
descriptors, IntPtrConstant(DescriptorArray::kDescriptorLengthIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* CodeStubAssembler::DescriptorNumberToIndex(
|
namespace {
|
||||||
SloppyTNode<Uint32T> descriptor_number) {
|
|
||||||
Node* descriptor_size = Int32Constant(DescriptorArray::kEntrySize);
|
Node* DescriptorNumberToIndex(CodeStubAssembler* a, Node* descriptor_number) {
|
||||||
Node* index = Int32Mul(descriptor_number, descriptor_size);
|
Node* descriptor_size = a->Int32Constant(DescriptorArray::kEntrySize);
|
||||||
return ChangeInt32ToIntPtr(index);
|
Node* index = a->Int32Mul(descriptor_number, descriptor_size);
|
||||||
|
return a->ChangeInt32ToIntPtr(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
Node* CodeStubAssembler::DescriptorArrayToKeyIndex(Node* descriptor_number) {
|
Node* CodeStubAssembler::DescriptorArrayToKeyIndex(Node* descriptor_number) {
|
||||||
return IntPtrAdd(IntPtrConstant(DescriptorArray::ToKeyIndex(0)),
|
return IntPtrAdd(IntPtrConstant(DescriptorArray::ToKeyIndex(0)),
|
||||||
DescriptorNumberToIndex(descriptor_number));
|
DescriptorNumberToIndex(this, descriptor_number));
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* CodeStubAssembler::DescriptorArrayGetSortedKeyIndex(
|
Node* CodeStubAssembler::DescriptorArrayGetSortedKeyIndex(
|
||||||
Node* descriptors, Node* descriptor_number) {
|
Node* descriptors, Node* descriptor_number) {
|
||||||
Node* details = DescriptorArrayGetDetails(
|
const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize;
|
||||||
TNode<DescriptorArray>::UncheckedCast(descriptors),
|
Node* details = LoadAndUntagToWord32FixedArrayElement(
|
||||||
TNode<Uint32T>::UncheckedCast(descriptor_number));
|
descriptors, DescriptorNumberToIndex(this, descriptor_number),
|
||||||
|
details_offset);
|
||||||
return DecodeWord32<PropertyDetails::DescriptorPointer>(details);
|
return DecodeWord32<PropertyDetails::DescriptorPointer>(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* CodeStubAssembler::DescriptorArrayGetKey(Node* descriptors,
|
Node* CodeStubAssembler::DescriptorArrayGetKey(Node* descriptors,
|
||||||
Node* descriptor_number) {
|
Node* descriptor_number) {
|
||||||
const int key_offset = DescriptorArray::ToKeyIndex(0) * kPointerSize;
|
const int key_offset = DescriptorArray::ToKeyIndex(0) * kPointerSize;
|
||||||
return LoadFixedArrayElement(
|
return LoadFixedArrayElement(descriptors,
|
||||||
descriptors, DescriptorNumberToIndex(descriptor_number), key_offset);
|
DescriptorNumberToIndex(this, descriptor_number),
|
||||||
}
|
key_offset);
|
||||||
|
|
||||||
TNode<Uint32T> CodeStubAssembler::DescriptorArrayGetDetails(
|
|
||||||
TNode<DescriptorArray> descriptors, TNode<Uint32T> descriptor_number) {
|
|
||||||
const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize;
|
|
||||||
return TNode<Uint32T>::UncheckedCast(LoadAndUntagToWord32FixedArrayElement(
|
|
||||||
descriptors, DescriptorNumberToIndex(descriptor_number), details_offset));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name,
|
void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name,
|
||||||
@ -6599,22 +6610,12 @@ void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
|
|||||||
Variable* var_value) {
|
Variable* var_value) {
|
||||||
DCHECK_EQ(MachineRepresentation::kWord32, var_details->rep());
|
DCHECK_EQ(MachineRepresentation::kWord32, var_details->rep());
|
||||||
DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep());
|
DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep());
|
||||||
|
Comment("[ LoadPropertyFromFastObject");
|
||||||
|
|
||||||
Node* details =
|
Node* details =
|
||||||
LoadDetailsByKeyIndex<DescriptorArray>(descriptors, name_index);
|
LoadDetailsByKeyIndex<DescriptorArray>(descriptors, name_index);
|
||||||
var_details->Bind(details);
|
var_details->Bind(details);
|
||||||
|
|
||||||
LoadPropertyFromFastObject(object, map, descriptors, name_index, details,
|
|
||||||
var_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
|
|
||||||
Node* descriptors,
|
|
||||||
Node* name_index,
|
|
||||||
Node* details,
|
|
||||||
Variable* var_value) {
|
|
||||||
Comment("[ LoadPropertyFromFastObject");
|
|
||||||
|
|
||||||
Node* location = DecodeWord32<PropertyDetails::LocationField>(details);
|
Node* location = DecodeWord32<PropertyDetails::LocationField>(details);
|
||||||
|
|
||||||
Label if_in_field(this), if_in_descriptor(this), done(this);
|
Label if_in_field(this), if_in_descriptor(this), done(this);
|
||||||
|
9
deps/v8/src/code-stub-assembler.h
vendored
9
deps/v8/src/code-stub-assembler.h
vendored
@ -1125,6 +1125,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
|||||||
Node* IsSequentialStringInstanceType(Node* instance_type);
|
Node* IsSequentialStringInstanceType(Node* instance_type);
|
||||||
Node* IsShortExternalStringInstanceType(Node* instance_type);
|
Node* IsShortExternalStringInstanceType(Node* instance_type);
|
||||||
Node* IsSpecialReceiverInstanceType(Node* instance_type);
|
Node* IsSpecialReceiverInstanceType(Node* instance_type);
|
||||||
|
Node* IsSpecialReceiverMap(Node* map);
|
||||||
Node* IsSpeciesProtectorCellInvalid();
|
Node* IsSpeciesProtectorCellInvalid();
|
||||||
Node* IsStringInstanceType(Node* instance_type);
|
Node* IsStringInstanceType(Node* instance_type);
|
||||||
Node* IsString(Node* object);
|
Node* IsString(Node* object);
|
||||||
@ -1583,10 +1584,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
|||||||
Node* name_index, Variable* var_details,
|
Node* name_index, Variable* var_details,
|
||||||
Variable* var_value);
|
Variable* var_value);
|
||||||
|
|
||||||
void LoadPropertyFromFastObject(Node* object, Node* map, Node* descriptors,
|
|
||||||
Node* name_index, Node* details,
|
|
||||||
Variable* var_value);
|
|
||||||
|
|
||||||
void LoadPropertyFromNameDictionary(Node* dictionary, Node* entry,
|
void LoadPropertyFromNameDictionary(Node* dictionary, Node* entry,
|
||||||
Variable* var_details,
|
Variable* var_details,
|
||||||
Variable* var_value);
|
Variable* var_value);
|
||||||
@ -1909,15 +1906,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
|||||||
void DescriptorLookupBinary(Node* unique_name, Node* descriptors, Node* nof,
|
void DescriptorLookupBinary(Node* unique_name, Node* descriptors, Node* nof,
|
||||||
Label* if_found, Variable* var_name_index,
|
Label* if_found, Variable* var_name_index,
|
||||||
Label* if_not_found);
|
Label* if_not_found);
|
||||||
Node* DescriptorNumberToIndex(SloppyTNode<Uint32T> descriptor_number);
|
|
||||||
// Implements DescriptorArray::ToKeyIndex.
|
// Implements DescriptorArray::ToKeyIndex.
|
||||||
// Returns an untagged IntPtr.
|
// Returns an untagged IntPtr.
|
||||||
Node* DescriptorArrayToKeyIndex(Node* descriptor_number);
|
Node* DescriptorArrayToKeyIndex(Node* descriptor_number);
|
||||||
// Implements DescriptorArray::GetKey.
|
// Implements DescriptorArray::GetKey.
|
||||||
Node* DescriptorArrayGetKey(Node* descriptors, Node* descriptor_number);
|
Node* DescriptorArrayGetKey(Node* descriptors, Node* descriptor_number);
|
||||||
// Implements DescriptorArray::GetKey.
|
|
||||||
TNode<Uint32T> DescriptorArrayGetDetails(TNode<DescriptorArray> descriptors,
|
|
||||||
TNode<Uint32T> descriptor_number);
|
|
||||||
|
|
||||||
Node* CallGetterIfAccessor(Node* value, Node* details, Node* context,
|
Node* CallGetterIfAccessor(Node* value, Node* details, Node* context,
|
||||||
Node* receiver, Label* if_bailout,
|
Node* receiver, Label* if_bailout,
|
||||||
|
4
deps/v8/src/debug/debug-evaluate.cc
vendored
4
deps/v8/src/debug/debug-evaluate.cc
vendored
@ -343,11 +343,7 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) {
|
|||||||
V(AllocateSeqOneByteString) \
|
V(AllocateSeqOneByteString) \
|
||||||
V(AllocateSeqTwoByteString) \
|
V(AllocateSeqTwoByteString) \
|
||||||
V(ObjectCreate) \
|
V(ObjectCreate) \
|
||||||
V(ObjectEntries) \
|
|
||||||
V(ObjectEntriesSkipFastPath) \
|
|
||||||
V(ObjectHasOwnProperty) \
|
V(ObjectHasOwnProperty) \
|
||||||
V(ObjectValues) \
|
|
||||||
V(ObjectValuesSkipFastPath) \
|
|
||||||
V(ArrayIndexOf) \
|
V(ArrayIndexOf) \
|
||||||
V(ArrayIncludes_Slow) \
|
V(ArrayIncludes_Slow) \
|
||||||
V(ArrayIsArray) \
|
V(ArrayIsArray) \
|
||||||
|
3
deps/v8/src/field-index.h
vendored
3
deps/v8/src/field-index.h
vendored
@ -123,7 +123,8 @@ class FieldIndex final {
|
|||||||
};
|
};
|
||||||
// Offset of first inobject property from beginning of object.
|
// Offset of first inobject property from beginning of object.
|
||||||
class FirstInobjectPropertyOffsetBits
|
class FirstInobjectPropertyOffsetBits
|
||||||
: public BitField64<int, InObjectPropertyBits::kNext, 7> {};
|
: public BitField64<int, InObjectPropertyBits::kNext,
|
||||||
|
kFirstInobjectPropertyOffsetBitCount> {};
|
||||||
class IsHiddenField
|
class IsHiddenField
|
||||||
: public BitField64<bool, FirstInobjectPropertyOffsetBits::kNext, 1> {};
|
: public BitField64<bool, FirstInobjectPropertyOffsetBits::kNext, 1> {};
|
||||||
STATIC_ASSERT(IsHiddenField::kNext <= 64);
|
STATIC_ASSERT(IsHiddenField::kNext <= 64);
|
||||||
|
1
deps/v8/src/objects-inl.h
vendored
1
deps/v8/src/objects-inl.h
vendored
@ -2431,6 +2431,7 @@ int ObjectTemplateInfo::embedder_field_count() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ObjectTemplateInfo::set_embedder_field_count(int count) {
|
void ObjectTemplateInfo::set_embedder_field_count(int count) {
|
||||||
|
DCHECK_LE(count, JSObject::kMaxEmbedderFields);
|
||||||
return set_data(
|
return set_data(
|
||||||
Smi::FromInt(EmbedderFieldCount::update(Smi::ToInt(data()), count)));
|
Smi::FromInt(EmbedderFieldCount::update(Smi::ToInt(data()), count)));
|
||||||
}
|
}
|
||||||
|
25
deps/v8/src/objects.cc
vendored
25
deps/v8/src/objects.cc
vendored
@ -8791,10 +8791,9 @@ MUST_USE_RESULT Maybe<bool> FastGetOwnValuesOrEntries(
|
|||||||
MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate,
|
MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate,
|
||||||
Handle<JSReceiver> object,
|
Handle<JSReceiver> object,
|
||||||
PropertyFilter filter,
|
PropertyFilter filter,
|
||||||
bool try_fast_path,
|
|
||||||
bool get_entries) {
|
bool get_entries) {
|
||||||
Handle<FixedArray> values_or_entries;
|
Handle<FixedArray> values_or_entries;
|
||||||
if (try_fast_path && filter == ENUMERABLE_STRINGS) {
|
if (filter == ENUMERABLE_STRINGS) {
|
||||||
Maybe<bool> fast_values_or_entries = FastGetOwnValuesOrEntries(
|
Maybe<bool> fast_values_or_entries = FastGetOwnValuesOrEntries(
|
||||||
isolate, object, get_entries, &values_or_entries);
|
isolate, object, get_entries, &values_or_entries);
|
||||||
if (fast_values_or_entries.IsNothing()) return MaybeHandle<FixedArray>();
|
if (fast_values_or_entries.IsNothing()) return MaybeHandle<FixedArray>();
|
||||||
@ -8847,17 +8846,13 @@ MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate,
|
|||||||
}
|
}
|
||||||
|
|
||||||
MaybeHandle<FixedArray> JSReceiver::GetOwnValues(Handle<JSReceiver> object,
|
MaybeHandle<FixedArray> JSReceiver::GetOwnValues(Handle<JSReceiver> object,
|
||||||
PropertyFilter filter,
|
PropertyFilter filter) {
|
||||||
bool try_fast_path) {
|
return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, false);
|
||||||
return GetOwnValuesOrEntries(object->GetIsolate(), object, filter,
|
|
||||||
try_fast_path, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeHandle<FixedArray> JSReceiver::GetOwnEntries(Handle<JSReceiver> object,
|
MaybeHandle<FixedArray> JSReceiver::GetOwnEntries(Handle<JSReceiver> object,
|
||||||
PropertyFilter filter,
|
PropertyFilter filter) {
|
||||||
bool try_fast_path) {
|
return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, true);
|
||||||
return GetOwnValuesOrEntries(object->GetIsolate(), object, filter,
|
|
||||||
try_fast_path, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Map::DictionaryElementsInPrototypeChainOnly() {
|
bool Map::DictionaryElementsInPrototypeChainOnly() {
|
||||||
@ -13783,18 +13778,24 @@ void JSFunction::CalculateInstanceSizeHelper(InstanceType instance_type,
|
|||||||
int requested_in_object_properties,
|
int requested_in_object_properties,
|
||||||
int* instance_size,
|
int* instance_size,
|
||||||
int* in_object_properties) {
|
int* in_object_properties) {
|
||||||
|
DCHECK_LE(static_cast<unsigned>(requested_embedder_fields),
|
||||||
|
JSObject::kMaxEmbedderFields);
|
||||||
int header_size = JSObject::GetHeaderSize(instance_type, has_prototype_slot);
|
int header_size = JSObject::GetHeaderSize(instance_type, has_prototype_slot);
|
||||||
int max_nof_fields =
|
int max_nof_fields =
|
||||||
(JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2;
|
(JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2;
|
||||||
CHECK_LE(max_nof_fields, JSObject::kMaxInObjectProperties);
|
CHECK_LE(max_nof_fields, JSObject::kMaxInObjectProperties);
|
||||||
*in_object_properties = Min(requested_in_object_properties, max_nof_fields);
|
CHECK_LE(static_cast<unsigned>(requested_embedder_fields),
|
||||||
CHECK_LE(requested_embedder_fields, max_nof_fields - *in_object_properties);
|
static_cast<unsigned>(max_nof_fields));
|
||||||
|
*in_object_properties = Min(requested_in_object_properties,
|
||||||
|
max_nof_fields - requested_embedder_fields);
|
||||||
*instance_size =
|
*instance_size =
|
||||||
header_size +
|
header_size +
|
||||||
((requested_embedder_fields + *in_object_properties) << kPointerSizeLog2);
|
((requested_embedder_fields + *in_object_properties) << kPointerSizeLog2);
|
||||||
CHECK_EQ(*in_object_properties,
|
CHECK_EQ(*in_object_properties,
|
||||||
((*instance_size - header_size) >> kPointerSizeLog2) -
|
((*instance_size - header_size) >> kPointerSizeLog2) -
|
||||||
requested_embedder_fields);
|
requested_embedder_fields);
|
||||||
|
CHECK_LE(static_cast<unsigned>(*instance_size),
|
||||||
|
static_cast<unsigned>(JSObject::kMaxInstanceSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
11
deps/v8/src/objects.h
vendored
11
deps/v8/src/objects.h
vendored
@ -2182,12 +2182,10 @@ class JSReceiver: public HeapObject {
|
|||||||
Handle<JSReceiver> object);
|
Handle<JSReceiver> object);
|
||||||
|
|
||||||
MUST_USE_RESULT static MaybeHandle<FixedArray> GetOwnValues(
|
MUST_USE_RESULT static MaybeHandle<FixedArray> GetOwnValues(
|
||||||
Handle<JSReceiver> object, PropertyFilter filter,
|
Handle<JSReceiver> object, PropertyFilter filter);
|
||||||
bool try_fast_path = true);
|
|
||||||
|
|
||||||
MUST_USE_RESULT static MaybeHandle<FixedArray> GetOwnEntries(
|
MUST_USE_RESULT static MaybeHandle<FixedArray> GetOwnEntries(
|
||||||
Handle<JSReceiver> object, PropertyFilter filter,
|
Handle<JSReceiver> object, PropertyFilter filter);
|
||||||
bool try_fast_path = true);
|
|
||||||
|
|
||||||
static const int kHashMask = PropertyArray::HashField::kMask;
|
static const int kHashMask = PropertyArray::HashField::kMask;
|
||||||
|
|
||||||
@ -2673,6 +2671,11 @@ class JSObject: public JSReceiver {
|
|||||||
static const int kMaxInObjectProperties =
|
static const int kMaxInObjectProperties =
|
||||||
(kMaxInstanceSize - kHeaderSize) >> kPointerSizeLog2;
|
(kMaxInstanceSize - kHeaderSize) >> kPointerSizeLog2;
|
||||||
STATIC_ASSERT(kMaxInObjectProperties <= kMaxNumberOfDescriptors);
|
STATIC_ASSERT(kMaxInObjectProperties <= kMaxNumberOfDescriptors);
|
||||||
|
// TODO(cbruni): Revisit calculation of the max supported embedder fields.
|
||||||
|
static const int kMaxEmbedderFields =
|
||||||
|
((1 << kFirstInobjectPropertyOffsetBitCount) - 1 - kHeaderSize) >>
|
||||||
|
kPointerSizeLog2;
|
||||||
|
STATIC_ASSERT(kMaxEmbedderFields <= kMaxInObjectProperties);
|
||||||
|
|
||||||
class BodyDescriptor;
|
class BodyDescriptor;
|
||||||
// No weak fields.
|
// No weak fields.
|
||||||
|
15
deps/v8/src/profiler/cpu-profiler.cc
vendored
15
deps/v8/src/profiler/cpu-profiler.cc
vendored
@ -165,13 +165,16 @@ void ProfilerEventsProcessor::Run() {
|
|||||||
|
|
||||||
if (nextSampleTime > now) {
|
if (nextSampleTime > now) {
|
||||||
#if V8_OS_WIN
|
#if V8_OS_WIN
|
||||||
// Do not use Sleep on Windows as it is very imprecise.
|
if (nextSampleTime - now < base::TimeDelta::FromMilliseconds(100)) {
|
||||||
// Could be up to 16ms jitter, which is unacceptable for the purpose.
|
// Do not use Sleep on Windows as it is very imprecise, with up to 16ms
|
||||||
while (base::TimeTicks::HighResolutionNow() < nextSampleTime) {
|
// jitter, which is unacceptable for short profile intervals.
|
||||||
}
|
while (base::TimeTicks::HighResolutionNow() < nextSampleTime) {
|
||||||
#else
|
}
|
||||||
base::OS::Sleep(nextSampleTime - now);
|
} else // NOLINT
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
base::OS::Sleep(nextSampleTime - now);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule next sample. sampler_ is nullptr in tests.
|
// Schedule next sample. sampler_ is nullptr in tests.
|
||||||
|
1
deps/v8/src/property-details.h
vendored
1
deps/v8/src/property-details.h
vendored
@ -197,6 +197,7 @@ class Representation {
|
|||||||
|
|
||||||
|
|
||||||
static const int kDescriptorIndexBitCount = 10;
|
static const int kDescriptorIndexBitCount = 10;
|
||||||
|
static const int kFirstInobjectPropertyOffsetBitCount = 7;
|
||||||
// The maximum number of descriptors we want in a descriptor array. It should
|
// The maximum number of descriptors we want in a descriptor array. It should
|
||||||
// fit in a page and also the following should hold:
|
// fit in a page and also the following should hold:
|
||||||
// kMaxNumberOfDescriptors + kFieldsAdded <= PropertyArray::kMaxLength.
|
// kMaxNumberOfDescriptors + kFieldsAdded <= PropertyArray::kMaxLength.
|
||||||
|
55
deps/v8/src/runtime/runtime-object.cc
vendored
55
deps/v8/src/runtime/runtime-object.cc
vendored
@ -439,61 +439,6 @@ RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
|
|||||||
return *object;
|
return *object;
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_FUNCTION(Runtime_ObjectValues) {
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
DCHECK_EQ(1, args.length());
|
|
||||||
|
|
||||||
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
|
|
||||||
|
|
||||||
Handle<FixedArray> values;
|
|
||||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
|
||||||
isolate, values,
|
|
||||||
JSReceiver::GetOwnValues(receiver, PropertyFilter::ENUMERABLE_STRINGS,
|
|
||||||
true));
|
|
||||||
return *isolate->factory()->NewJSArrayWithElements(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
RUNTIME_FUNCTION(Runtime_ObjectValuesSkipFastPath) {
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
DCHECK_EQ(1, args.length());
|
|
||||||
|
|
||||||
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
|
|
||||||
|
|
||||||
Handle<FixedArray> value;
|
|
||||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
|
||||||
isolate, value,
|
|
||||||
JSReceiver::GetOwnValues(receiver, PropertyFilter::ENUMERABLE_STRINGS,
|
|
||||||
false));
|
|
||||||
return *isolate->factory()->NewJSArrayWithElements(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
RUNTIME_FUNCTION(Runtime_ObjectEntries) {
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
DCHECK_EQ(1, args.length());
|
|
||||||
|
|
||||||
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
|
|
||||||
|
|
||||||
Handle<FixedArray> entries;
|
|
||||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
|
||||||
isolate, entries,
|
|
||||||
JSReceiver::GetOwnEntries(receiver, PropertyFilter::ENUMERABLE_STRINGS,
|
|
||||||
true));
|
|
||||||
return *isolate->factory()->NewJSArrayWithElements(entries);
|
|
||||||
}
|
|
||||||
|
|
||||||
RUNTIME_FUNCTION(Runtime_ObjectEntriesSkipFastPath) {
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
DCHECK_EQ(1, args.length());
|
|
||||||
|
|
||||||
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
|
|
||||||
|
|
||||||
Handle<FixedArray> entries;
|
|
||||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
|
||||||
isolate, entries,
|
|
||||||
JSReceiver::GetOwnEntries(receiver, PropertyFilter::ENUMERABLE_STRINGS,
|
|
||||||
false));
|
|
||||||
return *isolate->factory()->NewJSArrayWithElements(entries);
|
|
||||||
}
|
|
||||||
|
|
||||||
RUNTIME_FUNCTION(Runtime_GetProperty) {
|
RUNTIME_FUNCTION(Runtime_GetProperty) {
|
||||||
HandleScope scope(isolate);
|
HandleScope scope(isolate);
|
||||||
|
4
deps/v8/src/runtime/runtime.h
vendored
4
deps/v8/src/runtime/runtime.h
vendored
@ -391,10 +391,6 @@ namespace internal {
|
|||||||
F(ObjectCreate, 2, 1) \
|
F(ObjectCreate, 2, 1) \
|
||||||
F(InternalSetPrototype, 2, 1) \
|
F(InternalSetPrototype, 2, 1) \
|
||||||
F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
|
F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
|
||||||
F(ObjectValues, 1, 1) \
|
|
||||||
F(ObjectValuesSkipFastPath, 1, 1) \
|
|
||||||
F(ObjectEntries, 1, 1) \
|
|
||||||
F(ObjectEntriesSkipFastPath, 1, 1) \
|
|
||||||
F(GetProperty, 2, 1) \
|
F(GetProperty, 2, 1) \
|
||||||
F(KeyedGetProperty, 2, 1) \
|
F(KeyedGetProperty, 2, 1) \
|
||||||
F(AddNamedProperty, 4, 1) \
|
F(AddNamedProperty, 4, 1) \
|
||||||
|
40
deps/v8/src/simulator-base.h
vendored
40
deps/v8/src/simulator-base.h
vendored
@ -43,6 +43,26 @@ class SimulatorBase {
|
|||||||
return ConvertReturn<Return>(ret);
|
return ConvertReturn<Return>(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert back integral return types.
|
||||||
|
template <typename T>
|
||||||
|
static typename std::enable_if<std::is_integral<T>::value, T>::type
|
||||||
|
ConvertReturn(intptr_t ret) {
|
||||||
|
static_assert(sizeof(T) <= sizeof(intptr_t), "type bigger than ptrsize");
|
||||||
|
return static_cast<T>(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert back pointer-typed return types.
|
||||||
|
template <typename T>
|
||||||
|
static typename std::enable_if<std::is_pointer<T>::value, T>::type
|
||||||
|
ConvertReturn(intptr_t ret) {
|
||||||
|
return reinterpret_cast<T>(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert back void return type (i.e. no return).
|
||||||
|
template <typename T>
|
||||||
|
static typename std::enable_if<std::is_void<T>::value, T>::type ConvertReturn(
|
||||||
|
intptr_t ret) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Runtime call support. Uses the isolate in a thread-safe way.
|
// Runtime call support. Uses the isolate in a thread-safe way.
|
||||||
static void* RedirectExternalReference(Isolate* isolate,
|
static void* RedirectExternalReference(Isolate* isolate,
|
||||||
@ -69,26 +89,6 @@ class SimulatorBase {
|
|||||||
ConvertArg(T arg) {
|
ConvertArg(T arg) {
|
||||||
return reinterpret_cast<intptr_t>(arg);
|
return reinterpret_cast<intptr_t>(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert back integral return types.
|
|
||||||
template <typename T>
|
|
||||||
static typename std::enable_if<std::is_integral<T>::value, T>::type
|
|
||||||
ConvertReturn(intptr_t ret) {
|
|
||||||
static_assert(sizeof(T) <= sizeof(intptr_t), "type bigger than ptrsize");
|
|
||||||
return static_cast<T>(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert back pointer-typed return types.
|
|
||||||
template <typename T>
|
|
||||||
static typename std::enable_if<std::is_pointer<T>::value, T>::type
|
|
||||||
ConvertReturn(intptr_t ret) {
|
|
||||||
return reinterpret_cast<T>(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert back void return type (i.e. no return).
|
|
||||||
template <typename T>
|
|
||||||
static typename std::enable_if<std::is_void<T>::value, T>::type ConvertReturn(
|
|
||||||
intptr_t ret) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// When the generated code calls an external reference we need to catch that in
|
// When the generated code calls an external reference we need to catch that in
|
||||||
|
104
deps/v8/test/cctest/test-api.cc
vendored
104
deps/v8/test/cctest/test-api.cc
vendored
@ -2699,6 +2699,110 @@ THREADED_TEST(InternalFields) {
|
|||||||
CHECK_EQ(17, obj->GetInternalField(0)->Int32Value(env.local()).FromJust());
|
CHECK_EQ(17, obj->GetInternalField(0)->Int32Value(env.local()).FromJust());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(InternalFieldsSubclassing) {
|
||||||
|
LocalContext env;
|
||||||
|
v8::Isolate* isolate = env->GetIsolate();
|
||||||
|
v8::HandleScope scope(isolate);
|
||||||
|
for (int nof_embedder_fields = 0;
|
||||||
|
nof_embedder_fields < i::JSObject::kMaxEmbedderFields;
|
||||||
|
nof_embedder_fields++) {
|
||||||
|
Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
|
||||||
|
Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate();
|
||||||
|
instance_templ->SetInternalFieldCount(nof_embedder_fields);
|
||||||
|
Local<Function> constructor =
|
||||||
|
templ->GetFunction(env.local()).ToLocalChecked();
|
||||||
|
// Check that instances have the correct NOF properties.
|
||||||
|
Local<v8::Object> obj =
|
||||||
|
constructor->NewInstance(env.local()).ToLocalChecked();
|
||||||
|
|
||||||
|
i::Handle<i::JSObject> i_obj =
|
||||||
|
i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj));
|
||||||
|
CHECK_EQ(nof_embedder_fields, obj->InternalFieldCount());
|
||||||
|
CHECK_EQ(0, i_obj->map()->GetInObjectProperties());
|
||||||
|
// Check writing and reading internal fields.
|
||||||
|
for (int j = 0; j < nof_embedder_fields; j++) {
|
||||||
|
CHECK(obj->GetInternalField(j)->IsUndefined());
|
||||||
|
int value = 17 + j;
|
||||||
|
obj->SetInternalField(j, v8_num(value));
|
||||||
|
}
|
||||||
|
for (int j = 0; j < nof_embedder_fields; j++) {
|
||||||
|
int value = 17 + j;
|
||||||
|
CHECK_EQ(value,
|
||||||
|
obj->GetInternalField(j)->Int32Value(env.local()).FromJust());
|
||||||
|
}
|
||||||
|
CHECK(env->Global()
|
||||||
|
->Set(env.local(), v8_str("BaseClass"), constructor)
|
||||||
|
.FromJust());
|
||||||
|
// Create various levels of subclasses to stress instance size calculation.
|
||||||
|
const int kMaxNofProperties =
|
||||||
|
i::JSObject::kMaxInObjectProperties - nof_embedder_fields;
|
||||||
|
// Select only a few values to speed up the test.
|
||||||
|
int sizes[] = {0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
kMaxNofProperties / 4,
|
||||||
|
kMaxNofProperties / 2,
|
||||||
|
kMaxNofProperties - 2,
|
||||||
|
kMaxNofProperties - 1,
|
||||||
|
kMaxNofProperties + 1,
|
||||||
|
kMaxNofProperties + 2,
|
||||||
|
kMaxNofProperties * 2,
|
||||||
|
kMaxNofProperties * 2};
|
||||||
|
for (size_t i = 0; i < arraysize(sizes); i++) {
|
||||||
|
int nof_properties = sizes[i];
|
||||||
|
bool in_object_only = nof_properties <= kMaxNofProperties;
|
||||||
|
std::ostringstream src;
|
||||||
|
// Assembler source string for a subclass with {nof_properties}
|
||||||
|
// in-object properties.
|
||||||
|
src << "(function() {\n"
|
||||||
|
<< " class SubClass extends BaseClass {\n"
|
||||||
|
<< " constructor() {\n"
|
||||||
|
<< " super();\n";
|
||||||
|
// Set {nof_properties} instance properties in the constructor.
|
||||||
|
for (int j = 0; j < nof_properties; j++) {
|
||||||
|
src << " this.property" << j << " = " << j << ";\n";
|
||||||
|
}
|
||||||
|
src << " }\n"
|
||||||
|
<< " };\n"
|
||||||
|
<< " let instance;\n"
|
||||||
|
<< " for (let i = 0; i < 3; i++) {\n"
|
||||||
|
<< " instance = new SubClass();\n"
|
||||||
|
<< " }"
|
||||||
|
<< " return instance;\n"
|
||||||
|
<< "})();";
|
||||||
|
Local<v8::Object> value = CompileRun(src.str().c_str()).As<v8::Object>();
|
||||||
|
|
||||||
|
i::Handle<i::JSObject> i_value =
|
||||||
|
i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*value));
|
||||||
|
#ifdef VERIFY_HEAP
|
||||||
|
i_value->HeapObjectVerify();
|
||||||
|
i_value->map()->HeapObjectVerify();
|
||||||
|
i_value->map()->FindRootMap()->HeapObjectVerify();
|
||||||
|
#endif
|
||||||
|
CHECK_EQ(nof_embedder_fields, value->InternalFieldCount());
|
||||||
|
if (in_object_only) {
|
||||||
|
CHECK_LE(nof_properties, i_value->map()->GetInObjectProperties());
|
||||||
|
} else {
|
||||||
|
CHECK_LE(kMaxNofProperties, i_value->map()->GetInObjectProperties());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make Sure we get the precise property count.
|
||||||
|
i_value->map()->FindRootMap()->CompleteInobjectSlackTracking();
|
||||||
|
// TODO(cbruni): fix accounting to make this condition true.
|
||||||
|
// CHECK_EQ(0, i_value->map()->UnusedPropertyFields());
|
||||||
|
if (in_object_only) {
|
||||||
|
CHECK_EQ(nof_properties, i_value->map()->GetInObjectProperties());
|
||||||
|
} else {
|
||||||
|
CHECK_LE(kMaxNofProperties, i_value->map()->GetInObjectProperties());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
THREADED_TEST(InternalFieldsOfRegularObjects) {
|
THREADED_TEST(InternalFieldsOfRegularObjects) {
|
||||||
LocalContext env;
|
LocalContext env;
|
||||||
v8::Isolate* isolate = env->GetIsolate();
|
v8::Isolate* isolate = env->GetIsolate();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user