Upgrade V8 to version 4.9.385.28
https://chromium.googlesource.com/v8/v8/+/4.9.385.28
FPIIM-449
Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/ic/ic-compiler.cc b/src/ic/ic-compiler.cc
index e087acf..ae4b2a5 100644
--- a/src/ic/ic-compiler.cc
+++ b/src/ic/ic-compiler.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "src/v8.h"
+#include "src/ic/ic-compiler.h"
#include "src/ic/handler-compiler.h"
#include "src/ic/ic-inl.h"
-#include "src/ic/ic-compiler.h"
+#include "src/profiler/cpu-profiler.h"
namespace v8 {
@@ -25,92 +25,26 @@
}
-bool PropertyICCompiler::IncludesNumberType(TypeHandleList* types) {
- for (int i = 0; i < types->length(); ++i) {
- if (types->at(i)->Is(HeapType::Number())) return true;
+bool PropertyICCompiler::IncludesNumberMap(MapHandleList* maps) {
+ for (int i = 0; i < maps->length(); ++i) {
+ if (maps->at(i)->instance_type() == HEAP_NUMBER_TYPE) return true;
}
return false;
}
-Handle<Code> PropertyICCompiler::CompileMonomorphic(Handle<HeapType> type,
- Handle<Code> handler,
- Handle<Name> name,
- IcCheckType check) {
- TypeHandleList types(1);
- CodeHandleList handlers(1);
- types.Add(type);
- handlers.Add(handler);
- Code::StubType stub_type = handler->type();
- return CompilePolymorphic(&types, &handlers, name, stub_type, check);
-}
-
-
-Handle<Code> PropertyICCompiler::ComputeMonomorphic(
- Code::Kind kind, Handle<Name> name, Handle<HeapType> type,
- Handle<Code> handler, ExtraICState extra_ic_state) {
- Isolate* isolate = name->GetIsolate();
- if (handler.is_identical_to(isolate->builtins()->LoadIC_Normal()) ||
- handler.is_identical_to(isolate->builtins()->StoreIC_Normal())) {
- name = isolate->factory()->normal_ic_symbol();
- }
-
- CacheHolderFlag flag;
- Handle<Map> stub_holder = IC::GetICCacheHolder(*type, isolate, &flag);
- if (kind == Code::KEYED_STORE_IC) {
- // Always set the "property" bit.
- extra_ic_state =
- KeyedStoreIC::IcCheckTypeField::update(extra_ic_state, PROPERTY);
- DCHECK(STANDARD_STORE ==
- KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state));
- } else if (kind == Code::KEYED_LOAD_IC) {
- extra_ic_state = KeyedLoadIC::IcCheckTypeField::update(extra_ic_state,
- PROPERTY);
- }
-
- Handle<Code> ic;
- // There are multiple string maps that all use the same prototype. That
- // prototype cannot hold multiple handlers, one for each of the string maps,
- // for a single name. Hence, turn off caching of the IC.
- bool can_be_cached = !type->Is(HeapType::String());
- if (can_be_cached) {
- ic = Find(name, stub_holder, kind, extra_ic_state, flag);
- if (!ic.is_null()) return ic;
- }
-
- PropertyICCompiler ic_compiler(isolate, kind, extra_ic_state, flag);
- ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY);
-
- if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic);
- return ic;
-}
-
-
-Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic(
- Handle<Map> receiver_map) {
- Isolate* isolate = receiver_map->GetIsolate();
- DCHECK(KeyedLoadIC::GetKeyType(kNoExtraICState) == ELEMENT);
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
- Handle<Name> name = isolate->factory()->KeyedLoadMonomorphic_string();
-
- Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate);
- if (probe->IsCode()) return Handle<Code>::cast(probe);
-
- Handle<Code> stub = ComputeKeyedLoadMonomorphicHandler(receiver_map);
- PropertyICCompiler compiler(isolate, Code::KEYED_LOAD_IC);
- Handle<Code> code =
- compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate), stub,
- isolate->factory()->empty_string(), ELEMENT);
-
- Map::UpdateCodeCache(receiver_map, name, code);
- return code;
-}
-
-
Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
- Handle<Map> receiver_map) {
+ Handle<Map> receiver_map, ExtraICState extra_ic_state) {
Isolate* isolate = receiver_map->GetIsolate();
+ bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
ElementsKind elements_kind = receiver_map->elements_kind();
+
+ // No need to check for an elements-free prototype chain here, the generated
+ // stub code needs to check that dynamically anyway.
+ bool convert_hole_to_undefined =
+ is_js_array && elements_kind == FAST_HOLEY_ELEMENTS &&
+ *receiver_map == isolate->get_initial_js_array_map(elements_kind) &&
+ !(is_strong(LoadICState::GetLanguageMode(extra_ic_state)));
Handle<Code> stub;
if (receiver_map->has_indexed_interceptor()) {
stub = LoadIndexedInterceptorStub(isolate).GetCode();
@@ -120,43 +54,32 @@
} else if (receiver_map->has_sloppy_arguments_elements()) {
stub = KeyedLoadSloppyArgumentsStub(isolate).GetCode();
} else if (receiver_map->has_fast_elements() ||
- receiver_map->has_external_array_elements() ||
receiver_map->has_fixed_typed_array_elements()) {
- stub = LoadFastElementStub(isolate,
- receiver_map->instance_type() == JS_ARRAY_TYPE,
- elements_kind).GetCode();
+ stub = LoadFastElementStub(isolate, is_js_array, elements_kind,
+ convert_hole_to_undefined).GetCode();
} else {
- stub = LoadDictionaryElementStub(isolate).GetCode();
+ stub = LoadDictionaryElementStub(isolate, LoadICState(extra_ic_state))
+ .GetCode();
}
return stub;
}
-Handle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphic(
- Handle<Map> receiver_map, StrictMode strict_mode,
+Handle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
+ Handle<Map> receiver_map, LanguageMode language_mode,
KeyedAccessStoreMode store_mode) {
Isolate* isolate = receiver_map->GetIsolate();
ExtraICState extra_state =
- KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode);
- Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, extra_state);
+ KeyedStoreIC::ComputeExtraICState(language_mode, store_mode);
DCHECK(store_mode == STANDARD_STORE ||
store_mode == STORE_AND_GROW_NO_TRANSITION ||
store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
store_mode == STORE_NO_TRANSITION_HANDLE_COW);
- Handle<String> name = isolate->factory()->KeyedStoreMonomorphic_string();
- Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate);
- if (probe->IsCode()) return Handle<Code>::cast(probe);
-
PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state);
Handle<Code> code =
- compiler.CompileKeyedStoreMonomorphic(receiver_map, store_mode);
-
- Map::UpdateCodeCache(receiver_map, name, code);
- DCHECK(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) ==
- store_mode);
+ compiler.CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode);
return code;
}
@@ -178,30 +101,7 @@
static void FillCache(Isolate* isolate, Handle<Code> code) {
Handle<UnseededNumberDictionary> dictionary = UnseededNumberDictionary::Set(
isolate->factory()->non_monomorphic_cache(), code->flags(), code);
- isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
-}
-
-
-Handle<Code> PropertyICCompiler::ComputeLoad(Isolate* isolate,
- InlineCacheState ic_state,
- ExtraICState extra_state) {
- Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, ic_state, extra_state);
- Handle<UnseededNumberDictionary> cache =
- isolate->factory()->non_monomorphic_cache();
- int entry = cache->FindEntry(isolate, flags);
- if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
-
- PropertyICCompiler compiler(isolate, Code::LOAD_IC);
- Handle<Code> code;
- if (ic_state == UNINITIALIZED) {
- code = compiler.CompileLoadInitialize(flags);
- } else if (ic_state == PREMONOMORPHIC) {
- code = compiler.CompileLoadPreMonomorphic(flags);
- } else {
- UNREACHABLE();
- }
- FillCache(isolate, code);
- return code;
+ isolate->heap()->SetRootNonMonomorphicCache(*dictionary);
}
@@ -256,69 +156,20 @@
}
-// TODO(verwaest): Change this method so it takes in a TypeHandleList.
-Handle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic(
- MapHandleList* receiver_maps) {
- Isolate* isolate = receiver_maps->at(0)->GetIsolate();
- DCHECK(KeyedLoadIC::GetKeyType(kNoExtraICState) == ELEMENT);
- Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
- Handle<PolymorphicCodeCache> cache =
- isolate->factory()->polymorphic_code_cache();
- Handle<Object> probe = cache->Lookup(receiver_maps, flags);
- if (probe->IsCode()) return Handle<Code>::cast(probe);
-
- TypeHandleList types(receiver_maps->length());
- for (int i = 0; i < receiver_maps->length(); i++) {
- types.Add(HeapType::Class(receiver_maps->at(i), isolate));
- }
- CodeHandleList handlers(receiver_maps->length());
- ElementHandlerCompiler compiler(isolate);
- compiler.CompileElementHandlers(receiver_maps, &handlers);
- PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC);
- Handle<Code> code = ic_compiler.CompilePolymorphic(
- &types, &handlers, isolate->factory()->empty_string(), Code::NORMAL,
- ELEMENT);
-
- isolate->counters()->keyed_load_polymorphic_stubs()->Increment();
-
- PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
- return code;
-}
-
-
-Handle<Code> PropertyICCompiler::ComputePolymorphic(
- Code::Kind kind, TypeHandleList* types, CodeHandleList* handlers,
- int valid_types, Handle<Name> name, ExtraICState extra_ic_state) {
- Handle<Code> handler = handlers->at(0);
- Code::StubType type = valid_types == 1 ? handler->type() : Code::NORMAL;
- DCHECK(kind == Code::LOAD_IC || kind == Code::STORE_IC);
- PropertyICCompiler ic_compiler(name->GetIsolate(), kind, extra_ic_state);
- return ic_compiler.CompilePolymorphic(types, handlers, name, type, PROPERTY);
-}
-
-
-Handle<Code> PropertyICCompiler::ComputeKeyedStorePolymorphic(
- MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode,
- StrictMode strict_mode) {
+void PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers(
+ MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
+ CodeHandleList* handlers, KeyedAccessStoreMode store_mode,
+ LanguageMode language_mode) {
Isolate* isolate = receiver_maps->at(0)->GetIsolate();
DCHECK(store_mode == STANDARD_STORE ||
store_mode == STORE_AND_GROW_NO_TRANSITION ||
store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
store_mode == STORE_NO_TRANSITION_HANDLE_COW);
- Handle<PolymorphicCodeCache> cache =
- isolate->factory()->polymorphic_code_cache();
ExtraICState extra_state =
- KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode);
- Code::Flags flags =
- Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state);
- Handle<Object> probe = cache->Lookup(receiver_maps, flags);
- if (probe->IsCode()) return Handle<Code>::cast(probe);
-
+ KeyedStoreIC::ComputeExtraICState(language_mode, store_mode);
PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state);
- Handle<Code> code =
- compiler.CompileKeyedStorePolymorphic(receiver_maps, store_mode);
- PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
- return code;
+ compiler.CompileKeyedStorePolymorphicHandlers(
+ receiver_maps, transitioned_maps, handlers, store_mode);
}
@@ -330,15 +181,6 @@
}
-Handle<Code> PropertyICCompiler::CompileLoadPreMonomorphic(Code::Flags flags) {
- LoadIC::GeneratePreMonomorphic(masm());
- Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadPreMonomorphic");
- PROFILE(isolate(),
- CodeCreateEvent(Logger::LOAD_PREMONOMORPHIC_TAG, *code, 0));
- return code;
-}
-
-
Handle<Code> PropertyICCompiler::CompileStoreInitialize(Code::Flags flags) {
StoreIC::GenerateInitialize(masm());
Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreInitialize");
@@ -358,8 +200,8 @@
Handle<Code> PropertyICCompiler::CompileStoreGeneric(Code::Flags flags) {
ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
- StrictMode strict_mode = StoreIC::GetStrictMode(extra_state);
- GenerateRuntimeSetProperty(masm(), strict_mode);
+ LanguageMode language_mode = StoreICState::GetLanguageMode(extra_state);
+ GenerateRuntimeSetProperty(masm(), language_mode);
Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreGeneric");
PROFILE(isolate(), CodeCreateEvent(Logger::STORE_GENERIC_TAG, *code, 0));
return code;
@@ -381,20 +223,21 @@
Code::ComputeFlags(kind, state, extra_ic_state_, type, cache_holder());
Handle<Code> code = GetCodeWithFlags(flags, name);
PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
+#ifdef DEBUG
+ code->VerifyEmbeddedObjects();
+#endif
return code;
}
-Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
- MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode) {
- // Collect MONOMORPHIC stubs for all |receiver_maps|.
- CodeHandleList handlers(receiver_maps->length());
- MapHandleList transitioned_maps(receiver_maps->length());
+void PropertyICCompiler::CompileKeyedStorePolymorphicHandlers(
+ MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
+ CodeHandleList* handlers, KeyedAccessStoreMode store_mode) {
for (int i = 0; i < receiver_maps->length(); ++i) {
Handle<Map> receiver_map(receiver_maps->at(i));
Handle<Code> cached_stub;
Handle<Map> transitioned_map =
- receiver_map->FindTransitionedMap(receiver_maps);
+ Map::FindTransitionedMap(receiver_map, receiver_maps);
// TODO(mvstanton): The code below is doing pessimistic elements
// transitions. I would like to stop doing that and rely on Allocation Site
@@ -409,46 +252,54 @@
transitioned_map->elements_kind(),
is_js_array, store_mode).GetCode();
} else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
+ // TODO(mvstanton): Consider embedding store_mode in the state of the slow
+ // keyed store ic for uniformity.
cached_stub = isolate()->builtins()->KeyedStoreIC_Slow();
} else {
- if (receiver_map->has_fast_elements() ||
- receiver_map->has_external_array_elements() ||
- receiver_map->has_fixed_typed_array_elements()) {
+ if (IsSloppyArgumentsElements(elements_kind)) {
+ cached_stub =
+ KeyedStoreSloppyArgumentsStub(isolate(), store_mode).GetCode();
+ } else if (receiver_map->has_fast_elements() ||
+ receiver_map->has_fixed_typed_array_elements()) {
cached_stub = StoreFastElementStub(isolate(), is_js_array,
elements_kind, store_mode).GetCode();
} else {
- cached_stub = StoreElementStub(isolate(), elements_kind).GetCode();
+ cached_stub =
+ StoreElementStub(isolate(), elements_kind, store_mode).GetCode();
}
}
DCHECK(!cached_stub.is_null());
- handlers.Add(cached_stub);
- transitioned_maps.Add(transitioned_map);
+ handlers->Add(cached_stub);
+ transitioned_maps->Add(transitioned_map);
}
-
- Handle<Code> code = CompileKeyedStorePolymorphic(receiver_maps, &handlers,
- &transitioned_maps);
- isolate()->counters()->keyed_store_polymorphic_stubs()->Increment();
- PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, 0));
- return code;
}
#define __ ACCESS_MASM(masm())
-Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic(
+Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphicHandler(
Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
ElementsKind elements_kind = receiver_map->elements_kind();
bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
Handle<Code> stub;
- if (receiver_map->has_fast_elements() ||
- receiver_map->has_external_array_elements() ||
- receiver_map->has_fixed_typed_array_elements()) {
+ if (receiver_map->has_sloppy_arguments_elements()) {
+ stub = KeyedStoreSloppyArgumentsStub(isolate(), store_mode).GetCode();
+ } else if (receiver_map->has_fast_elements() ||
+ receiver_map->has_fixed_typed_array_elements()) {
stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind,
store_mode).GetCode();
} else {
- stub = StoreElementStub(isolate(), elements_kind).GetCode();
+ stub = StoreElementStub(isolate(), elements_kind, store_mode).GetCode();
}
+ return stub;
+}
+
+
+Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic(
+ Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
+ Handle<Code> stub =
+ CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode);
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
@@ -462,5 +313,5 @@
#undef __
-}
-} // namespace v8::internal
+} // namespace internal
+} // namespace v8