summaryrefslogtreecommitdiff
path: root/deps/v8/src/objects.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/objects.cc')
-rw-r--r--deps/v8/src/objects.cc613
1 files changed, 351 insertions, 262 deletions
diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc
index bd876e67d7..f8c55e57a6 100644
--- a/deps/v8/src/objects.cc
+++ b/deps/v8/src/objects.cc
@@ -73,6 +73,7 @@
#include "src/trap-handler/trap-handler.h"
#include "src/unicode-cache-inl.h"
#include "src/utils-inl.h"
+#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-objects.h"
#include "src/zone/zone.h"
@@ -1163,7 +1164,7 @@ MaybeHandle<Object> JSProxy::GetProperty(Isolate* isolate,
Object);
}
// 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
- Handle<JSReceiver> target(proxy->target(), isolate);
+ Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
// 6. Let trap be ? GetMethod(handler, "get").
Handle<Object> trap;
ASSIGN_RETURN_ON_EXCEPTION(
@@ -1536,7 +1537,7 @@ MaybeHandle<Object> JSProxy::GetPrototype(Handle<JSProxy> proxy) {
NewTypeError(MessageTemplate::kProxyRevoked, trap_name),
Object);
}
- Handle<JSReceiver> target(proxy->target(), isolate);
+ Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
// 5. Let trap be ? GetMethod(handler, "getPrototypeOf").
@@ -1605,9 +1606,7 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
Object);
}
- v8::AccessorNameGetterCallback call_fun =
- v8::ToCData<v8::AccessorNameGetterCallback>(info->getter());
- if (call_fun == nullptr) return isolate->factory()->undefined_value();
+ if (!info->has_getter()) return isolate->factory()->undefined_value();
if (info->is_sloppy() && !receiver->IsJSReceiver()) {
ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
@@ -1617,14 +1616,15 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
kDontThrow);
- Handle<Object> result = args.Call(call_fun, name);
+ Handle<Object> result = args.CallAccessorGetter(info, name);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (result.is_null()) return isolate->factory()->undefined_value();
Handle<Object> reboxed_result = handle(*result, isolate);
if (info->replace_on_access() && receiver->IsJSReceiver()) {
- args.Call(reinterpret_cast<GenericNamedPropertySetterCallback>(
- &Accessors::ReconfigureToDataProperty),
- name, result);
+ args.CallNamedSetterCallback(
+ reinterpret_cast<GenericNamedPropertySetterCallback>(
+ &Accessors::ReconfigureToDataProperty),
+ name, result);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
}
return reboxed_result;
@@ -1733,7 +1733,7 @@ Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
should_throw);
- Handle<Object> result = args.Call(call_fun, name, value);
+ Handle<Object> result = args.CallNamedSetterCallback(call_fun, name, value);
// In the case of AccessorNameSetterCallback, we know that the result value
// cannot have been set, so the result of Call will be null. In the case of
// AccessorNameBooleanSetterCallback, the result will either be null
@@ -1853,20 +1853,9 @@ MaybeHandle<Object> GetPropertyWithInterceptorInternal(
*holder, kDontThrow);
if (it->IsElement()) {
- uint32_t index = it->index();
- v8::IndexedPropertyGetterCallback getter =
- v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
- result = args.Call(getter, index);
+ result = args.CallIndexedGetter(interceptor, it->index());
} else {
- Handle<Name> name = it->name();
- DCHECK(!name->IsPrivate());
-
- DCHECK_IMPLIES(name->IsSymbol(), interceptor->can_intercept_symbols());
-
- v8::GenericNamedPropertyGetterCallback getter =
- v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
- interceptor->getter());
- result = args.Call(getter, name);
+ result = args.CallNamedGetter(interceptor, it->name());
}
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
@@ -1898,17 +1887,9 @@ Maybe<PropertyAttributes> GetPropertyAttributesWithInterceptorInternal(
if (!interceptor->query()->IsUndefined(isolate)) {
Handle<Object> result;
if (it->IsElement()) {
- uint32_t index = it->index();
- v8::IndexedPropertyQueryCallback query =
- v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
- result = args.Call(query, index);
+ result = args.CallIndexedQuery(interceptor, it->index());
} else {
- Handle<Name> name = it->name();
- DCHECK(!name->IsPrivate());
- v8::GenericNamedPropertyQueryCallback query =
- v8::ToCData<v8::GenericNamedPropertyQueryCallback>(
- interceptor->query());
- result = args.Call(query, name);
+ result = args.CallNamedQuery(interceptor, it->name());
}
if (!result.is_null()) {
int32_t value;
@@ -1919,17 +1900,9 @@ Maybe<PropertyAttributes> GetPropertyAttributesWithInterceptorInternal(
// TODO(verwaest): Use GetPropertyWithInterceptor?
Handle<Object> result;
if (it->IsElement()) {
- uint32_t index = it->index();
- v8::IndexedPropertyGetterCallback getter =
- v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
- result = args.Call(getter, index);
+ result = args.CallIndexedGetter(interceptor, it->index());
} else {
- Handle<Name> name = it->name();
- DCHECK(!name->IsPrivate());
- v8::GenericNamedPropertyGetterCallback getter =
- v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
- interceptor->getter());
- result = args.Call(getter, name);
+ result = args.CallNamedGetter(interceptor, it->name());
}
if (!result.is_null()) return Just(DONT_ENUM);
}
@@ -1960,22 +1933,11 @@ Maybe<bool> SetPropertyWithInterceptorInternal(
*holder, should_throw);
if (it->IsElement()) {
- uint32_t index = it->index();
- v8::IndexedPropertySetterCallback setter =
- v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter());
// TODO(neis): In the future, we may want to actually return the
// interceptor's result, which then should be a boolean.
- result = !args.Call(setter, index, value).is_null();
+ result = !args.CallIndexedSetter(interceptor, it->index(), value).is_null();
} else {
- Handle<Name> name = it->name();
- DCHECK(!name->IsPrivate());
-
- DCHECK_IMPLIES(name->IsSymbol(), interceptor->can_intercept_symbols());
-
- v8::GenericNamedPropertySetterCallback setter =
- v8::ToCData<v8::GenericNamedPropertySetterCallback>(
- interceptor->setter());
- result = !args.Call(setter, name, value).is_null();
+ result = !args.CallNamedSetter(interceptor, it->name(), value).is_null();
}
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
@@ -2025,20 +1987,11 @@ Maybe<bool> DefinePropertyWithInterceptorInternal(
}
if (it->IsElement()) {
- uint32_t index = it->index();
- v8::IndexedPropertyDefinerCallback definer =
- v8::ToCData<v8::IndexedPropertyDefinerCallback>(interceptor->definer());
- result = !args.Call(definer, index, *descriptor).is_null();
+ result = !args.CallIndexedDefiner(interceptor, it->index(), *descriptor)
+ .is_null();
} else {
- Handle<Name> name = it->name();
- DCHECK(!name->IsPrivate());
-
- DCHECK_IMPLIES(name->IsSymbol(), interceptor->can_intercept_symbols());
-
- v8::GenericNamedPropertyDefinerCallback definer =
- v8::ToCData<v8::GenericNamedPropertyDefinerCallback>(
- interceptor->definer());
- result = !args.Call(definer, name, *descriptor).is_null();
+ result =
+ !args.CallNamedDefiner(interceptor, it->name(), *descriptor).is_null();
}
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
@@ -2163,11 +2116,13 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object,
uint32_t hash = name->Hash();
if (object->IsJSGlobalObject()) {
- Handle<JSGlobalObject> global_obj(JSGlobalObject::cast(*object));
+ Handle<JSGlobalObject> global_obj = Handle<JSGlobalObject>::cast(object);
Handle<GlobalDictionary> dictionary(global_obj->global_dictionary());
int entry = dictionary->FindEntry(isolate, name, hash);
if (entry == GlobalDictionary::kNotFound) {
+ DCHECK_IMPLIES(global_obj->map()->is_prototype_map(),
+ Map::IsPrototypeChainInvalidated(global_obj->map()));
auto cell = isolate->factory()->NewPropertyCell(name);
cell->set_value(*value);
auto cell_type = value->IsUndefined(isolate)
@@ -2187,6 +2142,8 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object,
int entry = dictionary->FindEntry(name);
if (entry == NameDictionary::kNotFound) {
+ DCHECK_IMPLIES(object->map()->is_prototype_map(),
+ Map::IsPrototypeChainInvalidated(object->map()));
dictionary = NameDictionary::Add(dictionary, name, value, details);
object->SetProperties(*dictionary);
} else {
@@ -2613,7 +2570,7 @@ bool Object::IterationHasObservableEffects() {
JSArray* array = JSArray::cast(this);
Isolate* isolate = array->GetIsolate();
-#if defined(DEBUG) || defined(ENABLE_SLOWFAST_SWITCH)
+#ifdef V8_ENABLE_FORCE_SLOW_PATH
if (isolate->force_slow_path()) return true;
#endif
@@ -3280,7 +3237,10 @@ VisitorId Map::GetVisitorId(Map* map) {
if (instance_type == ALLOCATION_SITE_TYPE) {
return kVisitAllocationSite;
}
+ return kVisitStruct;
+ case LOAD_HANDLER_TYPE:
+ case STORE_HANDLER_TYPE:
return kVisitStruct;
default:
@@ -4213,6 +4173,9 @@ void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
// JSGlobalProxy must never be normalized
DCHECK(!object->IsJSGlobalProxy());
+ DCHECK_IMPLIES(new_map->is_prototype_map(),
+ Map::IsPrototypeChainInvalidated(*new_map));
+
Isolate* isolate = object->GetIsolate();
HandleScope scope(isolate);
Handle<Map> map(object->map());
@@ -4474,7 +4437,10 @@ void Map::DeprecateTransitionTree() {
transitions.GetTarget(i)->DeprecateTransitionTree();
}
DCHECK(!constructor_or_backpointer()->IsFunctionTemplateInfo());
- deprecate();
+ set_is_deprecated(true);
+ if (FLAG_trace_maps) {
+ LOG(GetIsolate(), MapEvent("Deprecate", this, nullptr));
+ }
dependent_code()->DeoptimizeDependentCodeGroup(
GetIsolate(), DependentCode::kTransitionGroup);
NotifyLeafMapLayoutChange();
@@ -5547,7 +5513,13 @@ Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
void JSProxy::Revoke(Handle<JSProxy> proxy) {
Isolate* isolate = proxy->GetIsolate();
- if (!proxy->IsRevoked()) proxy->set_handler(isolate->heap()->null_value());
+ // ES#sec-proxy-revocation-functions
+ if (!proxy->IsRevoked()) {
+ // 5. Set p.[[ProxyTarget]] to null.
+ proxy->set_target(isolate->heap()->null_value());
+ // 6. Set p.[[ProxyHandler]] to null.
+ proxy->set_handler(isolate->heap()->null_value());
+ }
DCHECK(proxy->IsRevoked());
}
@@ -5563,7 +5535,7 @@ Maybe<bool> JSProxy::IsArray(Handle<JSProxy> proxy) {
isolate->factory()->NewStringFromAsciiChecked("IsArray")));
return Nothing<bool>();
}
- object = handle(proxy->target(), isolate);
+ object = handle(JSReceiver::cast(proxy->target()), isolate);
if (object->IsJSArray()) return Just(true);
if (!object->IsJSProxy()) return Just(false);
}
@@ -5588,7 +5560,7 @@ Maybe<bool> JSProxy::HasProperty(Isolate* isolate, Handle<JSProxy> proxy,
return Nothing<bool>();
}
// 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
- Handle<JSReceiver> target(proxy->target(), isolate);
+ Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
// 6. Let trap be ? GetMethod(handler, "has").
Handle<Object> trap;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
@@ -5661,7 +5633,7 @@ Maybe<bool> JSProxy::SetProperty(Handle<JSProxy> proxy, Handle<Name> name,
*factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
return Nothing<bool>();
}
- Handle<JSReceiver> target(proxy->target(), isolate);
+ Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
Handle<Object> trap;
@@ -5712,7 +5684,7 @@ Maybe<bool> JSProxy::DeletePropertyOrElement(Handle<JSProxy> proxy,
*factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
return Nothing<bool>();
}
- Handle<JSReceiver> target(proxy->target(), isolate);
+ Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
Handle<Object> trap;
@@ -5986,7 +5958,7 @@ void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
void JSObject::MigrateInstance(Handle<JSObject> object) {
Handle<Map> original_map(object->map());
Handle<Map> map = Map::Update(original_map);
- map->set_migration_target(true);
+ map->set_is_migration_target(true);
MigrateToMap(object, map);
if (FLAG_trace_migration) {
object->PrintInstanceMigration(stdout, *original_map, *map);
@@ -6300,7 +6272,7 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
Handle<Map> new_map = Map::CopyDropDescriptors(old_map);
new_map->set_may_have_interesting_symbols(new_map->has_named_interceptor() ||
new_map->is_access_check_needed());
- new_map->set_dictionary_map(false);
+ new_map->set_is_dictionary_map(false);
NotifyMapChange(old_map, new_map, isolate);
@@ -6626,19 +6598,9 @@ Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it,
*holder, should_throw);
Handle<Object> result;
if (it->IsElement()) {
- uint32_t index = it->index();
- v8::IndexedPropertyDeleterCallback deleter =
- v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter());
- result = args.Call(deleter, index);
+ result = args.CallIndexedDeleter(interceptor, it->index());
} else {
- DCHECK_IMPLIES(it->name()->IsSymbol(),
- interceptor->can_intercept_symbols());
- Handle<Name> name = it->name();
- DCHECK(!name->IsPrivate());
- v8::GenericNamedPropertyDeleterCallback deleter =
- v8::ToCData<v8::GenericNamedPropertyDeleterCallback>(
- interceptor->deleter());
- result = args.Call(deleter, name);
+ result = args.CallNamedDeleter(interceptor, it->name());
}
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
@@ -7526,7 +7488,7 @@ Maybe<bool> JSProxy::DefineOwnProperty(Isolate* isolate, Handle<JSProxy> proxy,
return Nothing<bool>();
}
// 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
- Handle<JSReceiver> target(proxy->target(), isolate);
+ Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
// 6. Let trap be ? GetMethod(handler, "defineProperty").
Handle<Object> trap;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
@@ -7690,19 +7652,9 @@ Maybe<bool> GetPropertyDescriptorWithInterceptor(LookupIterator* it,
PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
*holder, kDontThrow);
if (it->IsElement()) {
- uint32_t index = it->index();
- v8::IndexedPropertyDescriptorCallback descriptorCallback =
- v8::ToCData<v8::IndexedPropertyDescriptorCallback>(
- interceptor->descriptor());
-
- result = args.Call(descriptorCallback, index);
+ result = args.CallIndexedDescriptor(interceptor, it->index());
} else {
- Handle<Name> name = it->name();
- DCHECK(!name->IsPrivate());
- v8::GenericNamedPropertyDescriptorCallback descriptorCallback =
- v8::ToCData<v8::GenericNamedPropertyDescriptorCallback>(
- interceptor->descriptor());
- result = args.Call(descriptorCallback, name);
+ result = args.CallNamedDescriptor(interceptor, it->name());
}
if (!result.is_null()) {
// Request successfully intercepted, try to set the property
@@ -7809,7 +7761,7 @@ Maybe<bool> JSProxy::GetOwnPropertyDescriptor(Isolate* isolate,
return Nothing<bool>();
}
// 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
- Handle<JSReceiver> target(proxy->target(), isolate);
+ Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
// 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor").
Handle<Object> trap;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
@@ -8261,7 +8213,7 @@ Maybe<bool> JSProxy::PreventExtensions(Handle<JSProxy> proxy,
*factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
return Nothing<bool>();
}
- Handle<JSReceiver> target(proxy->target(), isolate);
+ Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
Handle<Object> trap;
@@ -8369,7 +8321,7 @@ Maybe<bool> JSProxy::IsExtensible(Handle<JSProxy> proxy) {
*factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
return Nothing<bool>();
}
- Handle<JSReceiver> target(proxy->target(), isolate);
+ Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
Handle<Object> trap;
@@ -8839,9 +8791,10 @@ MUST_USE_RESULT Maybe<bool> FastGetOwnValuesOrEntries(
MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate,
Handle<JSReceiver> object,
PropertyFilter filter,
+ bool try_fast_path,
bool get_entries) {
Handle<FixedArray> values_or_entries;
- if (filter == ENUMERABLE_STRINGS) {
+ if (try_fast_path && filter == ENUMERABLE_STRINGS) {
Maybe<bool> fast_values_or_entries = FastGetOwnValuesOrEntries(
isolate, object, get_entries, &values_or_entries);
if (fast_values_or_entries.IsNothing()) return MaybeHandle<FixedArray>();
@@ -8894,13 +8847,17 @@ MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate,
}
MaybeHandle<FixedArray> JSReceiver::GetOwnValues(Handle<JSReceiver> object,
- PropertyFilter filter) {
- return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, false);
+ PropertyFilter filter,
+ bool try_fast_path) {
+ return GetOwnValuesOrEntries(object->GetIsolate(), object, filter,
+ try_fast_path, false);
}
MaybeHandle<FixedArray> JSReceiver::GetOwnEntries(Handle<JSReceiver> object,
- PropertyFilter filter) {
- return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, true);
+ PropertyFilter filter,
+ bool try_fast_path) {
+ return GetOwnValuesOrEntries(object->GetIsolate(), object, filter,
+ try_fast_path, true);
}
bool Map::DictionaryElementsInPrototypeChainOnly() {
@@ -9077,13 +9034,13 @@ Handle<Map> Map::RawCopy(Handle<Map> map, int instance_size,
result->set_bit_field(map->bit_field());
result->set_bit_field2(map->bit_field2());
int new_bit_field3 = map->bit_field3();
- new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true);
+ new_bit_field3 = OwnsDescriptorsBit::update(new_bit_field3, true);
new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0);
new_bit_field3 = EnumLengthBits::update(new_bit_field3,
kInvalidEnumCacheSentinel);
- new_bit_field3 = Deprecated::update(new_bit_field3, false);
+ new_bit_field3 = IsDeprecatedBit::update(new_bit_field3, false);
if (!map->is_dictionary_map()) {
- new_bit_field3 = IsUnstable::update(new_bit_field3, false);
+ new_bit_field3 = IsUnstableBit::update(new_bit_field3, false);
}
result->set_bit_field3(new_bit_field3);
return result;
@@ -9164,8 +9121,8 @@ Handle<Map> Map::CopyNormalized(Handle<Map> map,
// Clear the unused_property_fields explicitly as this field should not
// be accessed for normalized maps.
result->SetInObjectUnusedPropertyFields(0);
- result->set_dictionary_map(true);
- result->set_migration_target(false);
+ result->set_is_dictionary_map(true);
+ result->set_is_migration_target(false);
result->set_may_have_interesting_symbols(true);
result->set_construction_counter(kNoSlackTracking);
@@ -9184,7 +9141,7 @@ Handle<Map> Map::CopyNormalized(Handle<Map> map,
// static
Handle<Map> Map::TransitionToImmutableProto(Handle<Map> map) {
Handle<Map> new_map = Map::Copy(map, "ImmutablePrototype");
- new_map->set_immutable_proto(true);
+ new_map->set_is_immutable_proto(true);
return new_map;
}
@@ -9723,8 +9680,8 @@ Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
bool* created_new_map) {
RuntimeCallTimerScope stats_scope(
*map, map->is_prototype_map()
- ? &RuntimeCallStats::PrototypeMap_TransitionToDataProperty
- : &RuntimeCallStats::Map_TransitionToDataProperty);
+ ? RuntimeCallCounterId::kPrototypeMap_TransitionToDataProperty
+ : RuntimeCallCounterId::kMap_TransitionToDataProperty);
DCHECK(name->IsUniqueName());
DCHECK(!map->is_dictionary_map());
@@ -9839,8 +9796,8 @@ Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map,
RuntimeCallTimerScope stats_scope(
isolate,
map->is_prototype_map()
- ? &RuntimeCallStats::PrototypeMap_TransitionToAccessorProperty
- : &RuntimeCallStats::Map_TransitionToAccessorProperty);
+ ? RuntimeCallCounterId::kPrototypeMap_TransitionToAccessorProperty
+ : RuntimeCallCounterId::kMap_TransitionToAccessorProperty);
// At least one of the accessors needs to be a new value.
DCHECK(!getter->IsNull(isolate) || !setter->IsNull(isolate));
@@ -10291,8 +10248,10 @@ Handle<ArrayList> ArrayList::Add(Handle<ArrayList> array, Handle<Object> obj1,
// static
Handle<ArrayList> ArrayList::New(Isolate* isolate, int size) {
- Handle<ArrayList> result = Handle<ArrayList>::cast(
- isolate->factory()->NewFixedArray(size + kFirstIndex));
+ Handle<FixedArray> fixed_array =
+ isolate->factory()->NewFixedArray(size + kFirstIndex);
+ fixed_array->set_map_no_write_barrier(isolate->heap()->array_list_map());
+ Handle<ArrayList> result = Handle<ArrayList>::cast(fixed_array);
result->SetLength(0);
return result;
}
@@ -10331,10 +10290,13 @@ Handle<FixedArray> EnsureSpaceInFixedArray(Handle<FixedArray> array,
// static
Handle<ArrayList> ArrayList::EnsureSpace(Handle<ArrayList> array, int length) {
const bool empty = (array->length() == 0);
- auto ret = Handle<ArrayList>::cast(
- EnsureSpaceInFixedArray(array, kFirstIndex + length));
- if (empty) ret->SetLength(0);
- return ret;
+ auto ret = EnsureSpaceInFixedArray(array, kFirstIndex + length);
+ if (empty) {
+ ret->set_map_no_write_barrier(array->GetHeap()->array_list_map());
+
+ Handle<ArrayList>::cast(ret)->SetLength(0);
+ }
+ return Handle<ArrayList>::cast(ret);
}
Handle<RegExpMatchInfo> RegExpMatchInfo::ReserveCaptures(
@@ -10710,7 +10672,7 @@ Handle<Object> String::ToNumber(Handle<String> subject) {
// whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
// or the 'I' character ('Infinity'). All of that have codes not greater
// than '9' except 'I' and &nbsp;.
- if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
+ if (data[start_pos] != 'I' && data[start_pos] != 0xA0) {
return isolate->factory()->nan_value();
}
} else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
@@ -12551,15 +12513,19 @@ bool JSObject::UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
return true;
}
+namespace {
-static void InvalidatePrototypeChainsInternal(Map* map) {
+// This function must be kept in sync with
+// AccessorAssembler::InvalidateValidityCellIfPrototype() which does pre-checks
+// before jumping here.
+PrototypeInfo* InvalidateOnePrototypeValidityCellInternal(Map* map) {
DCHECK(map->is_prototype_map());
if (FLAG_trace_prototype_users) {
PrintF("Invalidating prototype map %p 's cell\n",
reinterpret_cast<void*>(map));
}
Object* maybe_proto_info = map->prototype_info();
- if (!maybe_proto_info->IsPrototypeInfo()) return;
+ if (!maybe_proto_info->IsPrototypeInfo()) return nullptr;
PrototypeInfo* proto_info = PrototypeInfo::cast(maybe_proto_info);
Object* maybe_cell = proto_info->validity_cell();
if (maybe_cell->IsCell()) {
@@ -12567,6 +12533,12 @@ static void InvalidatePrototypeChainsInternal(Map* map) {
Cell* cell = Cell::cast(maybe_cell);
cell->set_value(Smi::FromInt(Map::kPrototypeChainInvalid));
}
+ return proto_info;
+}
+
+void InvalidatePrototypeChainsInternal(Map* map) {
+ PrototypeInfo* proto_info = InvalidateOnePrototypeValidityCellInternal(map);
+ if (proto_info == nullptr) return;
WeakFixedArray::Iterator iterator(proto_info->prototype_users());
// For now, only maps register themselves as users.
@@ -12577,13 +12549,27 @@ static void InvalidatePrototypeChainsInternal(Map* map) {
}
}
+} // namespace
// static
-void JSObject::InvalidatePrototypeChains(Map* map) {
+Map* JSObject::InvalidatePrototypeChains(Map* map) {
DisallowHeapAllocation no_gc;
InvalidatePrototypeChainsInternal(map);
+ return map;
}
+// We also invalidate global objects validity cell when a new lexical
+// environment variable is added. This is necessary to ensure that
+// Load/StoreGlobalIC handlers that load/store from global object's prototype
+// get properly invalidated.
+// Note, that the normal Load/StoreICs that load/store through the global object
+// in the prototype chain are not affected by appearance of a new lexical
+// variable and therefore we don't propagate invalidation down.
+// static
+void JSObject::InvalidatePrototypeValidityCell(JSGlobalObject* global) {
+ DisallowHeapAllocation no_gc;
+ InvalidateOnePrototypeValidityCellInternal(global->map());
+}
// static
Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<JSObject> prototype,
@@ -12662,6 +12648,21 @@ Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
}
// static
+bool Map::IsPrototypeChainInvalidated(Map* map) {
+ DCHECK(map->is_prototype_map());
+ Object* maybe_proto_info = map->prototype_info();
+ if (maybe_proto_info->IsPrototypeInfo()) {
+ PrototypeInfo* proto_info = PrototypeInfo::cast(maybe_proto_info);
+ Object* maybe_cell = proto_info->validity_cell();
+ if (maybe_cell->IsCell()) {
+ Cell* cell = Cell::cast(maybe_cell);
+ return cell->value() == Smi::FromInt(Map::kPrototypeChainInvalid);
+ }
+ }
+ return true;
+}
+
+// static
Handle<WeakCell> Map::GetOrCreatePrototypeWeakCell(Handle<JSReceiver> prototype,
Isolate* isolate) {
DCHECK(!prototype.is_null());
@@ -12688,7 +12689,8 @@ Handle<WeakCell> Map::GetOrCreatePrototypeWeakCell(Handle<JSReceiver> prototype,
// static
void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype,
bool enable_prototype_setup_mode) {
- RuntimeCallTimerScope stats_scope(*map, &RuntimeCallStats::Map_SetPrototype);
+ RuntimeCallTimerScope stats_scope(*map,
+ RuntimeCallCounterId::kMap_SetPrototype);
bool is_hidden = false;
if (prototype->IsJSObject()) {
@@ -12815,7 +12817,7 @@ void JSFunction::SetPrototype(Handle<JSFunction> function,
JSObject::MigrateToMap(function, new_map);
new_map->SetConstructor(*value);
- new_map->set_non_instance_prototype(true);
+ new_map->set_has_non_instance_prototype(true);
FunctionKind kind = function->shared()->kind();
Handle<Context> native_context(function->context()->native_context());
@@ -12829,7 +12831,7 @@ void JSFunction::SetPrototype(Handle<JSFunction> function,
isolate);
} else {
construct_prototype = Handle<JSReceiver>::cast(value);
- function->map()->set_non_instance_prototype(false);
+ function->map()->set_has_non_instance_prototype(false);
}
SetInstancePrototype(isolate, function, construct_prototype);
@@ -12976,6 +12978,56 @@ void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
map->StartInobjectSlackTracking();
}
+namespace {
+bool FastInitializeDerivedMap(Isolate* isolate, Handle<JSFunction> new_target,
+ Handle<JSFunction> constructor,
+ Handle<Map> constructor_initial_map) {
+ // Check that |function|'s initial map still in sync with the |constructor|,
+ // otherwise we must create a new initial map for |function|.
+ if (new_target->has_initial_map() &&
+ new_target->initial_map()->GetConstructor() == *constructor) {
+ DCHECK(new_target->instance_prototype()->IsJSReceiver());
+ return true;
+ }
+ InstanceType instance_type = constructor_initial_map->instance_type();
+ DCHECK(CanSubclassHaveInobjectProperties(instance_type));
+ // Create a new map with the size and number of in-object properties
+ // suggested by |function|.
+
+ // Link initial map and constructor function if the new.target is actually a
+ // subclass constructor.
+ if (!IsDerivedConstructor(new_target->shared()->kind())) return false;
+
+ int instance_size;
+ int in_object_properties;
+ int embedder_fields =
+ JSObject::GetEmbedderFieldCount(*constructor_initial_map);
+ bool success = JSFunction::CalculateInstanceSizeForDerivedClass(
+ new_target, instance_type, embedder_fields, &instance_size,
+ &in_object_properties);
+
+ Handle<Map> map;
+ if (success) {
+ int pre_allocated = constructor_initial_map->GetInObjectProperties() -
+ constructor_initial_map->UnusedPropertyFields();
+ CHECK_LE(constructor_initial_map->UsedInstanceSize(), instance_size);
+ int unused_property_fields = in_object_properties - pre_allocated;
+ map = Map::CopyInitialMap(constructor_initial_map, instance_size,
+ in_object_properties, unused_property_fields);
+ } else {
+ map = Map::CopyInitialMap(constructor_initial_map);
+ }
+ map->set_new_target_is_base(false);
+ Handle<Object> prototype(new_target->instance_prototype(), isolate);
+ JSFunction::SetInitialMap(new_target, map, prototype);
+ DCHECK(new_target->instance_prototype()->IsJSReceiver());
+ map->SetConstructor(*constructor);
+ map->set_construction_counter(Map::kNoSlackTracking);
+ map->StartInobjectSlackTracking();
+ return true;
+}
+
+} // namespace
// static
MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
@@ -12986,55 +13038,16 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
Handle<Map> constructor_initial_map(constructor->initial_map(), isolate);
if (*new_target == *constructor) return constructor_initial_map;
+ Handle<Map> result_map;
// Fast case, new.target is a subclass of constructor. The map is cacheable
// (and may already have been cached). new.target.prototype is guaranteed to
// be a JSReceiver.
if (new_target->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
-
- // Check that |function|'s initial map still in sync with the |constructor|,
- // otherwise we must create a new initial map for |function|.
- if (function->has_initial_map() &&
- function->initial_map()->GetConstructor() == *constructor) {
+ if (FastInitializeDerivedMap(isolate, function, constructor,
+ constructor_initial_map)) {
return handle(function->initial_map(), isolate);
}
-
- // Create a new map with the size and number of in-object properties
- // suggested by |function|.
-
- // Link initial map and constructor function if the new.target is actually a
- // subclass constructor.
- if (IsDerivedConstructor(function->shared()->kind())) {
- Handle<Object> prototype(function->instance_prototype(), isolate);
- InstanceType instance_type = constructor_initial_map->instance_type();
- DCHECK(CanSubclassHaveInobjectProperties(instance_type));
- int embedder_fields =
- JSObject::GetEmbedderFieldCount(*constructor_initial_map);
- int pre_allocated = constructor_initial_map->GetInObjectProperties() -
- constructor_initial_map->UnusedPropertyFields();
- int instance_size;
- int in_object_properties;
- bool success = CalculateInstanceSizeForDerivedClass(
- function, instance_type, embedder_fields, &instance_size,
- &in_object_properties);
-
- int unused_property_fields = in_object_properties - pre_allocated;
-
- Handle<Map> map;
- if (success) {
- map = Map::CopyInitialMap(constructor_initial_map, instance_size,
- in_object_properties, unused_property_fields);
- } else {
- map = Map::CopyInitialMap(constructor_initial_map);
- }
- map->set_new_target_is_base(false);
-
- JSFunction::SetInitialMap(function, map, prototype);
- map->SetConstructor(*constructor);
- map->set_construction_counter(Map::kNoSlackTracking);
- map->StartInobjectSlackTracking();
- return map;
- }
}
// Slow path, new.target is either a proxy or can't cache the map.
@@ -13076,7 +13089,7 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
Handle<Map> map = Map::CopyInitialMap(constructor_initial_map);
map->set_new_target_is_base(false);
- DCHECK(prototype->IsJSReceiver());
+ CHECK(prototype->IsJSReceiver());
if (map->prototype() != *prototype) Map::SetPrototype(map, prototype);
map->SetConstructor(*constructor);
return map;
@@ -13183,7 +13196,8 @@ Handle<String> JSFunction::ToString(Handle<JSFunction> function) {
}
if (FLAG_harmony_function_tostring) {
- return Handle<String>::cast(shared_info->GetSourceCodeHarmony());
+ return Handle<String>::cast(
+ SharedFunctionInfo::GetSourceCodeHarmony(shared_info));
}
IncrementalStringBuilder builder(isolate);
@@ -13214,7 +13228,22 @@ Handle<String> JSFunction::ToString(Handle<JSFunction> function) {
builder.AppendString(handle(shared_info->name(), isolate));
}
}
- builder.AppendString(Handle<String>::cast(shared_info->GetSourceCode()));
+ if (shared_info->is_wrapped()) {
+ builder.AppendCharacter('(');
+ Handle<FixedArray> args(
+ Script::cast(shared_info->script())->wrapped_arguments());
+ int argc = args->length();
+ for (int i = 0; i < argc; i++) {
+ if (i > 0) builder.AppendCString(", ");
+ builder.AppendString(Handle<String>(String::cast(args->get(i))));
+ }
+ builder.AppendCString(") {\n");
+ }
+ builder.AppendString(
+ Handle<String>::cast(SharedFunctionInfo::GetSourceCode(shared_info)));
+ if (shared_info->is_wrapped()) {
+ builder.AppendCString("\n}");
+ }
return builder.Finish().ToHandleChecked();
}
@@ -13245,10 +13274,10 @@ int Script::GetEvalPosition() {
// Due to laziness, the position may not have been translated from code
// offset yet, which would be encoded as negative integer. In that case,
// translate and set the position.
- if (eval_from_shared()->IsUndefined(GetIsolate())) {
+ if (!has_eval_from_shared()) {
position = 0;
} else {
- SharedFunctionInfo* shared = SharedFunctionInfo::cast(eval_from_shared());
+ SharedFunctionInfo* shared = eval_from_shared();
position = shared->abstract_code()->SourcePosition(-position);
}
DCHECK_GE(position, 0);
@@ -13286,6 +13315,15 @@ bool Script::GetPositionInfo(Handle<Script> script, int position,
bool Script::IsUserJavaScript() { return type() == Script::TYPE_NORMAL; }
+bool Script::ContainsAsmModule() {
+ DisallowHeapAllocation no_gc;
+ SharedFunctionInfo::ScriptIterator iter(Handle<Script>(this));
+ while (SharedFunctionInfo* info = iter.Next()) {
+ if (info->HasAsmWasmData()) return true;
+ }
+ return false;
+}
+
namespace {
bool GetPositionInfoSlow(const Script* script, int position,
Script::PositionInfo* info) {
@@ -13324,8 +13362,8 @@ bool Script::GetPositionInfo(int position, PositionInfo* info,
Handle<WasmCompiledModule> compiled_module(
WasmCompiledModule::cast(wasm_compiled_module()));
DCHECK_LE(0, position);
- return compiled_module->GetPositionInfo(static_cast<uint32_t>(position),
- info);
+ return compiled_module->shared()->GetPositionInfo(
+ static_cast<uint32_t>(position), info);
}
if (line_ends()->IsUndefined(GetIsolate())) {
@@ -13456,8 +13494,12 @@ Handle<JSObject> Script::GetWrapper(Handle<Script> script) {
MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
Isolate* isolate, const FunctionLiteral* fun) {
- DCHECK_NE(fun->function_literal_id(), FunctionLiteral::kIdTypeInvalid);
- DCHECK_LT(fun->function_literal_id(), shared_function_infos()->length());
+ CHECK_NE(fun->function_literal_id(), FunctionLiteral::kIdTypeInvalid);
+ // If this check fails, the problem is most probably the function id
+ // renumbering done by AstFunctionLiteralIdReindexer; in particular, that
+ // AstTraversalVisitor doesn't recurse properly in the construct which
+ // triggers the mismatch.
+ CHECK_LT(fun->function_literal_id(), shared_function_infos()->length());
Object* shared = shared_function_infos()->get(fun->function_literal_id());
if (shared->IsUndefined(isolate) || WeakCell::cast(shared)->cleared()) {
return MaybeHandle<SharedFunctionInfo>();
@@ -13628,14 +13670,14 @@ String* SharedFunctionInfo::DebugName() {
return name();
}
-bool SharedFunctionInfo::HasNoSideEffect() {
- if (!computed_has_no_side_effect()) {
- DisallowHeapAllocation not_handlified;
- Handle<SharedFunctionInfo> info(this);
- set_has_no_side_effect(DebugEvaluate::FunctionHasNoSideEffect(info));
- set_computed_has_no_side_effect(true);
+// static
+bool SharedFunctionInfo::HasNoSideEffect(Handle<SharedFunctionInfo> info) {
+ if (!info->computed_has_no_side_effect()) {
+ bool has_no_side_effect = DebugEvaluate::FunctionHasNoSideEffect(info);
+ info->set_has_no_side_effect(has_no_side_effect);
+ info->set_computed_has_no_side_effect(true);
}
- return has_no_side_effect();
+ return info->has_no_side_effect();
}
// The filter is a pattern that matches function names in this way:
@@ -13680,22 +13722,44 @@ bool SharedFunctionInfo::HasSourceCode() const {
!reinterpret_cast<Script*>(script())->source()->IsUndefined(isolate);
}
-
-Handle<Object> SharedFunctionInfo::GetSourceCode() {
- if (!HasSourceCode()) return GetIsolate()->factory()->undefined_value();
- Handle<String> source(String::cast(Script::cast(script())->source()));
- return GetIsolate()->factory()->NewSubString(
- source, start_position(), end_position());
+// static
+Handle<Object> SharedFunctionInfo::GetSourceCode(
+ Handle<SharedFunctionInfo> shared) {
+ Isolate* isolate = shared->GetIsolate();
+ if (!shared->HasSourceCode()) return isolate->factory()->undefined_value();
+ Handle<String> source(String::cast(Script::cast(shared->script())->source()));
+ return isolate->factory()->NewSubString(source, shared->start_position(),
+ shared->end_position());
}
-Handle<Object> SharedFunctionInfo::GetSourceCodeHarmony() {
- Isolate* isolate = GetIsolate();
- if (!HasSourceCode()) return isolate->factory()->undefined_value();
- Handle<String> script_source(String::cast(Script::cast(script())->source()));
- int start_pos = function_token_position();
- if (start_pos == kNoSourcePosition) start_pos = start_position();
- return isolate->factory()->NewSubString(script_source, start_pos,
- end_position());
+// static
+Handle<Object> SharedFunctionInfo::GetSourceCodeHarmony(
+ Handle<SharedFunctionInfo> shared) {
+ Isolate* isolate = shared->GetIsolate();
+ if (!shared->HasSourceCode()) return isolate->factory()->undefined_value();
+ Handle<String> script_source(
+ String::cast(Script::cast(shared->script())->source()));
+ int start_pos = shared->function_token_position();
+ if (start_pos == kNoSourcePosition) start_pos = shared->start_position();
+ Handle<String> source = isolate->factory()->NewSubString(
+ script_source, start_pos, shared->end_position());
+ if (!shared->is_wrapped()) return source;
+
+ DCHECK(!shared->name_should_print_as_anonymous());
+ IncrementalStringBuilder builder(isolate);
+ builder.AppendCString("function ");
+ builder.AppendString(Handle<String>(shared->name(), isolate));
+ builder.AppendCString("(");
+ Handle<FixedArray> args(Script::cast(shared->script())->wrapped_arguments());
+ int argc = args->length();
+ for (int i = 0; i < argc; i++) {
+ if (i > 0) builder.AppendCString(", ");
+ builder.AppendString(Handle<String>(String::cast(args->get(i))));
+ }
+ builder.AppendCString(") {\n");
+ builder.AppendString(source);
+ builder.AppendCString("\n}");
+ return builder.Finish().ToHandleChecked();
}
bool SharedFunctionInfo::IsInlineable() {
@@ -13720,15 +13784,17 @@ void JSFunction::CalculateInstanceSizeHelper(InstanceType instance_type,
int* instance_size,
int* in_object_properties) {
int header_size = JSObject::GetHeaderSize(instance_type, has_prototype_slot);
- DCHECK_LE(requested_embedder_fields,
- (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2);
+ int max_nof_fields =
+ (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2;
+ CHECK_LE(max_nof_fields, JSObject::kMaxInObjectProperties);
+ *in_object_properties = Min(requested_in_object_properties, max_nof_fields);
+ CHECK_LE(requested_embedder_fields, max_nof_fields - *in_object_properties);
*instance_size =
- Min(header_size +
- ((requested_embedder_fields + requested_in_object_properties)
- << kPointerSizeLog2),
- JSObject::kMaxInstanceSize);
- *in_object_properties = ((*instance_size - header_size) >> kPointerSizeLog2) -
- requested_embedder_fields;
+ header_size +
+ ((requested_embedder_fields + *in_object_properties) << kPointerSizeLog2);
+ CHECK_EQ(*in_object_properties,
+ ((*instance_size - header_size) >> kPointerSizeLog2) -
+ requested_embedder_fields);
}
// static
@@ -13738,7 +13804,6 @@ bool JSFunction::CalculateInstanceSizeForDerivedClass(
int* in_object_properties) {
Isolate* isolate = function->GetIsolate();
int expected_nof_properties = 0;
- bool result = true;
for (PrototypeIterator iter(isolate, function, kStartAtReceiver);
!iter.IsAtEnd(); iter.Advance()) {
Handle<JSReceiver> current =
@@ -13751,21 +13816,24 @@ bool JSFunction::CalculateInstanceSizeForDerivedClass(
if (shared->is_compiled() ||
Compiler::Compile(func, Compiler::CLEAR_EXCEPTION)) {
DCHECK(shared->is_compiled());
- expected_nof_properties += shared->expected_nof_properties();
+ int count = shared->expected_nof_properties();
+ // Check that the estimate is sane.
+ if (expected_nof_properties <= JSObject::kMaxInObjectProperties - count) {
+ expected_nof_properties += count;
+ } else {
+ expected_nof_properties = JSObject::kMaxInObjectProperties;
+ }
} else if (!shared->is_compiled()) {
// In case there was a compilation error for the constructor we will
// throw an error during instantiation. Hence we directly return 0;
- result = false;
- break;
- }
- if (!IsDerivedConstructor(shared->kind())) {
- break;
+ return false;
}
+ if (!IsDerivedConstructor(shared->kind())) break;
}
CalculateInstanceSizeHelper(instance_type, true, requested_embedder_fields,
expected_nof_properties, instance_size,
in_object_properties);
- return result;
+ return true;
}
@@ -13804,7 +13872,7 @@ std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v) {
void SharedFunctionInfo::DisableOptimization(BailoutReason reason) {
- DCHECK_NE(reason, kNoReason);
+ DCHECK_NE(reason, BailoutReason::kNoReason);
set_compiler_hints(
DisabledOptimizationReasonBits::update(compiler_hints(), reason));
@@ -13833,6 +13901,7 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
shared_info->set_inferred_name(*lit->inferred_name());
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_kind(lit->kind());
// FunctionKind must have already been set.
DCHECK(lit->kind() == shared_info->kind());
@@ -13941,7 +14010,7 @@ void Code::InvalidateEmbeddedObjects() {
void Code::Relocate(intptr_t delta) {
- if (trap_handler::UseTrapHandler() && is_wasm_code()) {
+ if (trap_handler::IsTrapHandlerEnabled() && is_wasm_code()) {
const int index = trap_handler_index()->value();
if (index >= 0) {
trap_handler::UpdateHandlerDataCodePointer(index, instruction_start());
@@ -14101,11 +14170,11 @@ void JSFunction::ClearTypeFeedbackInfo() {
}
}
-void Code::PrintDeoptLocation(FILE* out, Address pc) {
+void Code::PrintDeoptLocation(FILE* out, const char* str, Address pc) {
Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(this, pc);
class SourcePosition pos = info.position;
- if (info.deopt_reason != DeoptimizeReason::kNoReason || pos.IsKnown()) {
- PrintF(out, " ;;; deoptimize at ");
+ if (info.deopt_reason != DeoptimizeReason::kUnknown || pos.IsKnown()) {
+ PrintF(out, "%s", str);
OFStream outstr(out);
pos.Print(outstr, this);
PrintF(out, ", %s\n", DeoptimizeReasonToString(info.deopt_reason));
@@ -14291,9 +14360,11 @@ void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) { // NOLINT
DCHECK(Translation::BEGIN == opcode);
int frame_count = iterator.Next();
int jsframe_count = iterator.Next();
+ int update_feedback_count = iterator.Next();
os << " " << Translation::StringFor(opcode)
<< " {frame count=" << frame_count
- << ", js frame count=" << jsframe_count << "}\n";
+ << ", js frame count=" << jsframe_count
+ << ", update_feedback_count=" << update_feedback_count << "}\n";
while (iterator.HasNext() &&
Translation::BEGIN !=
@@ -14450,6 +14521,14 @@ void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) { // NOLINT
os << "{length=" << args_length << "}";
break;
}
+
+ case Translation::UPDATE_FEEDBACK: {
+ int literal_index = iterator.Next();
+ FeedbackSlot slot(iterator.Next());
+ os << "{feedback={vector_index=" << literal_index << ", slot=" << slot
+ << "}}";
+ break;
+ }
}
os << "\n";
}
@@ -14485,8 +14564,7 @@ void HandlerTable::HandlerTableReturnPrint(std::ostream& os) {
}
}
-
-void Code::Disassemble(const char* name, std::ostream& os) { // NOLINT
+void Code::Disassemble(const char* name, std::ostream& os, void* current_pc) {
os << "kind = " << Kind2String(kind()) << "\n";
if (is_stub()) {
const char* n = CodeStub::MajorName(CodeStub::GetMajorKey(this));
@@ -14514,21 +14592,22 @@ void Code::Disassemble(const char* name, std::ostream& os) { // NOLINT
os << "compiler = " << (is_turbofanned() ? "turbofan" : "unknown") << "\n";
os << "address = " << static_cast<const void*>(this) << "\n";
- os << "Instructions (size = " << instruction_size() << ")\n";
+ os << "Body (size = " << instruction_size() << ")\n";
{
Isolate* isolate = GetIsolate();
int size = instruction_size();
int safepoint_offset =
- is_turbofanned() ? static_cast<int>(safepoint_table_offset()) : size;
+ has_safepoint_info() ? safepoint_table_offset() : size;
int constant_pool_offset = FLAG_enable_embedded_constant_pool
? this->constant_pool_offset()
: size;
// Stop before reaching any embedded tables
int code_size = Min(safepoint_offset, constant_pool_offset);
+ os << "Instructions (size = " << code_size << ")\n";
byte* begin = instruction_start();
byte* end = begin + code_size;
- Disassembler::Decode(isolate, &os, begin, end, this);
+ Disassembler::Decode(isolate, &os, begin, end, this, current_pc);
if (constant_pool_offset < size) {
int constant_pool_size = safepoint_offset - constant_pool_offset;
@@ -14562,7 +14641,7 @@ void Code::Disassemble(const char* name, std::ostream& os) { // NOLINT
}
os << "\n";
- if (is_turbofanned()) {
+ if (has_safepoint_info()) {
SafepointTable table(this);
os << "Safepoints (size = " << table.size() << ")\n";
for (unsigned i = 0; i < table.length(); i++) {
@@ -15057,7 +15136,7 @@ Maybe<bool> JSProxy::SetPrototype(Handle<JSProxy> proxy, Handle<Object> value,
return Nothing<bool>();
}
// 5. Let target be the value of the [[ProxyTarget]] internal slot.
- Handle<JSReceiver> target(proxy->target(), isolate);
+ Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
// 6. Let trap be ? GetMethod(handler, "getPrototypeOf").
Handle<Object> trap;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
@@ -15267,13 +15346,10 @@ static bool ShouldConvertToSlowElements(JSObject* object, uint32_t capacity,
bool JSObject::WouldConvertToSlowElements(uint32_t index) {
- if (HasFastElements()) {
- Handle<FixedArrayBase> backing_store(FixedArrayBase::cast(elements()));
- uint32_t capacity = static_cast<uint32_t>(backing_store->length());
- uint32_t new_capacity;
- return ShouldConvertToSlowElements(this, capacity, index, &new_capacity);
- }
- return false;
+ if (!HasFastElements()) return false;
+ uint32_t capacity = static_cast<uint32_t>(elements()->length());
+ uint32_t new_capacity;
+ return ShouldConvertToSlowElements(this, capacity, index, &new_capacity);
}
@@ -16655,26 +16731,18 @@ MaybeHandle<JSTypedArray> JSTypedArray::SpeciesCreate(
// 2. Let defaultConstructor be the intrinsic object listed in column one of
// Table 51 for exemplar.[[TypedArrayName]].
- Handle<JSFunction> default_ctor = isolate->uint8_array_fun();
- switch (exemplar->type()) {
-#define TYPED_ARRAY_CTOR(Type, type, TYPE, ctype, size) \
- case kExternal##Type##Array: { \
- default_ctor = isolate->type##_array_fun(); \
- break; \
- }
-
- TYPED_ARRAYS(TYPED_ARRAY_CTOR)
-#undef TYPED_ARRAY_CTOR
- default:
- UNREACHABLE();
- }
+ Handle<JSFunction> default_ctor =
+ JSTypedArray::DefaultConstructor(isolate, exemplar);
// 3. Let constructor be ? SpeciesConstructor(exemplar, defaultConstructor).
- Handle<Object> ctor;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, ctor,
- Object::SpeciesConstructor(isolate, exemplar, default_ctor),
- JSTypedArray);
+ Handle<Object> ctor = default_ctor;
+ if (!exemplar->HasJSTypedArrayPrototype(isolate) ||
+ !isolate->IsArraySpeciesLookupChainIntact()) {
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, ctor,
+ Object::SpeciesConstructor(isolate, exemplar, default_ctor),
+ JSTypedArray);
+ }
// 4. Return ? TypedArrayCreate(constructor, argumentList).
return Create(isolate, ctor, argc, argv, method_name);
@@ -16682,6 +16750,10 @@ MaybeHandle<JSTypedArray> JSTypedArray::SpeciesCreate(
void JSGlobalObject::InvalidatePropertyCell(Handle<JSGlobalObject> global,
Handle<Name> name) {
+ // Regardless of whether the property is there or not invalidate
+ // Load/StoreGlobalICs that load/store through global object's prototype.
+ JSObject::InvalidatePrototypeValidityCell(*global);
+
DCHECK(!global->HasFastProperties());
auto dictionary = handle(global->global_dictionary());
int entry = dictionary->FindEntry(name);
@@ -17703,6 +17775,8 @@ Handle<FixedArray> BaseNameDictionary<Derived, Shape>::IterationIndices(
array->set(array_size++, Smi::FromInt(i));
}
+ DCHECK_EQ(array_size, length);
+
EnumIndexComparator<Derived> cmp(raw_dictionary);
// Use AtomicElement wrapper to ensure that std::sort uses atomic load and
// store operations that are safe for concurrent marking.
@@ -18924,6 +18998,13 @@ void JSArrayBuffer::FreeBackingStore() {
// static
void JSArrayBuffer::FreeBackingStore(Isolate* isolate, Allocation allocation) {
+ if (allocation.mode == ArrayBuffer::Allocator::AllocationMode::kReservation) {
+ // TODO(eholk): check with WasmAllocationTracker to make sure this is
+ // actually a buffer we are tracking.
+ isolate->wasm_engine()->allocation_tracker()->ReleaseAddressSpace(
+ allocation.length);
+ }
+
isolate->array_buffer_allocator()->Free(allocation.allocation_base,
allocation.length, allocation.mode);
}
@@ -18959,7 +19040,7 @@ void JSArrayBuffer::Setup(Handle<JSArrayBuffer> array_buffer, Isolate* isolate,
// already been promoted.
array_buffer->set_backing_store(data);
- array_buffer->set_allocation_base(data);
+ array_buffer->set_allocation_base(allocation_base);
array_buffer->set_allocation_length(allocation_length);
if (data && !is_external) {
@@ -19179,6 +19260,14 @@ Handle<PropertyCell> PropertyCell::PrepareForValue(
details = details.set_cell_type(new_type);
cell->set_property_details(details);
+ if (new_type == PropertyCellType::kConstant ||
+ new_type == PropertyCellType::kConstantType) {
+ // Store the value now to ensure that the cell contains the constant or
+ // type information. Otherwise subsequent store operation will turn
+ // the cell to mutable.
+ cell->set_value(*value);
+ }
+
// Deopt when transitioning from a constant type.
if (!invalidate && (old_type != new_type ||
original_details.IsReadOnly() != details.IsReadOnly())) {