Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ic/ic.cc')
-rw-r--r--deps/v8/src/ic/ic.cc46
1 files changed, 34 insertions, 12 deletions
diff --git a/deps/v8/src/ic/ic.cc b/deps/v8/src/ic/ic.cc
index b508a20f805..452275d13f2 100644
--- a/deps/v8/src/ic/ic.cc
+++ b/deps/v8/src/ic/ic.cc
@@ -4,7 +4,6 @@
#include "src/ic/ic.h"
-#include "include/v8config.h"
#include "src/api/api-arguments-inl.h"
#include "src/api/api.h"
#include "src/ast/ast.h"
@@ -695,10 +694,6 @@ void IC::SetCache(Handle<Name> name, const MaybeObjectHandle& handler) {
}
}
-#if defined(__clang__) && defined(V8_OS_WIN)
-// Force function alignment to work around CPU bug: https://crbug.com/968683
-__attribute__((__aligned__(32)))
-#endif
void LoadIC::UpdateCaches(LookupIterator* lookup) {
Handle<Object> code;
if (lookup->state() == LookupIterator::ACCESS_CHECK) {
@@ -1428,6 +1423,28 @@ bool StoreIC::LookupForWrite(LookupIterator* it, Handle<Object> value,
}
}
+ // If we are in StoreGlobal then check if we should throw on non-existent
+ // properties.
+ if (IsStoreGlobalIC() &&
+ (GetShouldThrow(it->isolate(), Nothing<ShouldThrow>()) ==
+ ShouldThrow::kThrowOnError)) {
+ // ICs typically does the store in two steps: prepare receiver for the
+ // transition followed by the actual store. For global objects we create a
+ // property cell when preparing for transition and install this cell in the
+ // handler. In strict mode, we throw and never initialize this property
+ // cell. The IC handler assumes that the property cell it is holding is for
+ // a property that is existing. This case violates this assumption. If we
+ // happen to invalidate this property cell later, it leads to incorrect
+ // behaviour. For now just use a slow stub and don't install the property
+ // cell for these cases. Hopefully these cases are not frequent enough to
+ // impact performance.
+ //
+ // TODO(mythria): If we find this to be happening often, we could install a
+ // new kind of handler for non-existent properties. These handlers can then
+ // miss to runtime if the value is not hole (i.e. cell got invalidated) and
+ // handle these stores correctly.
+ return false;
+ }
receiver = it->GetStoreTarget<JSObject>();
if (it->ExtendingNonExtensible(receiver)) return false;
it->PrepareTransitionToDataProperty(receiver, value, NONE, store_origin);
@@ -1918,8 +1935,12 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
Handle<Object> KeyedStoreIC::StoreElementHandler(
Handle<Map> receiver_map, KeyedAccessStoreMode store_mode,
MaybeHandle<Object> prev_validity_cell) {
+ // The only case when could keep using non-slow element store handler for
+ // a fast array with potentially read-only elements is when it's an
+ // initializing store to array literal.
DCHECK_IMPLIES(
- receiver_map->DictionaryElementsInPrototypeChainOnly(isolate()),
+ !receiver_map->has_dictionary_elements() &&
+ receiver_map->MayHaveReadOnlyElementsInPrototypeChain(isolate()),
IsStoreInArrayLiteralICKind(kind()));
if (receiver_map->IsJSProxyMap()) {
@@ -1984,7 +2005,7 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers(
Handle<Map> transition;
if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE ||
- receiver_map->DictionaryElementsInPrototypeChainOnly(isolate())) {
+ receiver_map->MayHaveReadOnlyElementsInPrototypeChain(isolate())) {
// TODO(mvstanton): Consider embedding store_mode in the state of the slow
// keyed store ic for uniformity.
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_SlowStub);
@@ -2147,17 +2168,18 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
} else if (object->IsJSArray() && IsGrowStoreMode(store_mode) &&
JSArray::HasReadOnlyLength(Handle<JSArray>::cast(object))) {
set_slow_stub_reason("array has read only length");
- } else if (object->IsJSArray() && MayHaveTypedArrayInPrototypeChain(
- Handle<JSObject>::cast(object))) {
+ } else if (object->IsJSObject() && MayHaveTypedArrayInPrototypeChain(
+ Handle<JSObject>::cast(object))) {
// Make sure we don't handle this in IC if there's any JSTypedArray in
// the {receiver}'s prototype chain, since that prototype is going to
// swallow all stores that are out-of-bounds for said prototype, and we
// just let the runtime deal with the complexity of this.
- set_slow_stub_reason("typed array in the prototype chain of an Array");
+ set_slow_stub_reason("typed array in the prototype chain");
} else if (key_is_valid_index) {
if (old_receiver_map->is_abandoned_prototype_map()) {
set_slow_stub_reason("receiver with prototype map");
- } else if (!old_receiver_map->DictionaryElementsInPrototypeChainOnly(
+ } else if (old_receiver_map->has_dictionary_elements() ||
+ !old_receiver_map->MayHaveReadOnlyElementsInPrototypeChain(
isolate())) {
// We should go generic if receiver isn't a dictionary, but our
// prototype chain does have dictionary elements. This ensures that
@@ -2167,7 +2189,7 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
UpdateStoreElement(old_receiver_map, store_mode,
handle(receiver->map(), isolate()));
} else {
- set_slow_stub_reason("dictionary or proxy prototype");
+ set_slow_stub_reason("prototype with potentially read-only elements");
}
} else {
set_slow_stub_reason("non-smi-like key");