| Index: src/ic/ic-compiler.cc
|
| diff --git a/src/stub-cache.cc b/src/ic/ic-compiler.cc
|
| similarity index 73%
|
| rename from src/stub-cache.cc
|
| rename to src/ic/ic-compiler.cc
|
| index 32ff8d1460ecd5da4b129ffe7173de72bdd78f81..05a0a6ee95cdd688d21137342140653ea7b70595 100644
|
| --- a/src/stub-cache.cc
|
| +++ b/src/ic/ic-compiler.cc
|
| @@ -1,112 +1,23 @@
|
| -// Copyright 2012 the V8 project authors. All rights reserved.
|
| +// Copyright 2014 the V8 project authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| #include "src/v8.h"
|
|
|
| -#include "src/api.h"
|
| -#include "src/arguments.h"
|
| -#include "src/ast.h"
|
| -#include "src/code-stubs.h"
|
| -#include "src/cpu-profiler.h"
|
| -#include "src/gdb-jit.h"
|
| -#include "src/ic-inl.h"
|
| -#include "src/stub-cache.h"
|
| -#include "src/type-info.h"
|
| -#include "src/vm-state-inl.h"
|
| +#include "src/ic/ic-inl.h"
|
| +#include "src/ic/ic-compiler.h"
|
| +
|
|
|
| namespace v8 {
|
| namespace internal {
|
|
|
| -// -----------------------------------------------------------------------
|
| -// StubCache implementation.
|
| -
|
| -
|
| -StubCache::StubCache(Isolate* isolate)
|
| - : isolate_(isolate) { }
|
| -
|
| -
|
| -void StubCache::Initialize() {
|
| - DCHECK(IsPowerOf2(kPrimaryTableSize));
|
| - DCHECK(IsPowerOf2(kSecondaryTableSize));
|
| - Clear();
|
| -}
|
| -
|
| -
|
| -static Code::Flags CommonStubCacheChecks(Name* name, Map* map,
|
| - Code::Flags flags) {
|
| - flags = Code::RemoveTypeAndHolderFromFlags(flags);
|
| -
|
| - // Validate that the name does not move on scavenge, and that we
|
| - // can use identity checks instead of structural equality checks.
|
| - DCHECK(!name->GetHeap()->InNewSpace(name));
|
| - DCHECK(name->IsUniqueName());
|
| -
|
| - // The state bits are not important to the hash function because the stub
|
| - // cache only contains handlers. Make sure that the bits are the least
|
| - // significant so they will be the ones masked out.
|
| - DCHECK_EQ(Code::HANDLER, Code::ExtractKindFromFlags(flags));
|
| - STATIC_ASSERT((Code::ICStateField::kMask & 1) == 1);
|
| -
|
| - // Make sure that the code type and cache holder are not included in the hash.
|
| - DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
|
| - DCHECK(Code::ExtractCacheHolderFromFlags(flags) == 0);
|
| -
|
| - return flags;
|
| -}
|
| -
|
| -
|
| -Code* StubCache::Set(Name* name, Map* map, Code* code) {
|
| - Code::Flags flags = CommonStubCacheChecks(name, map, code->flags());
|
| -
|
| - // Compute the primary entry.
|
| - int primary_offset = PrimaryOffset(name, flags, map);
|
| - Entry* primary = entry(primary_, primary_offset);
|
| - Code* old_code = primary->value;
|
| -
|
| - // If the primary entry has useful data in it, we retire it to the
|
| - // secondary cache before overwriting it.
|
| - if (old_code != isolate_->builtins()->builtin(Builtins::kIllegal)) {
|
| - Map* old_map = primary->map;
|
| - Code::Flags old_flags =
|
| - Code::RemoveTypeAndHolderFromFlags(old_code->flags());
|
| - int seed = PrimaryOffset(primary->key, old_flags, old_map);
|
| - int secondary_offset = SecondaryOffset(primary->key, old_flags, seed);
|
| - Entry* secondary = entry(secondary_, secondary_offset);
|
| - *secondary = *primary;
|
| - }
|
| -
|
| - // Update primary cache.
|
| - primary->key = name;
|
| - primary->value = code;
|
| - primary->map = map;
|
| - isolate()->counters()->megamorphic_stub_cache_updates()->Increment();
|
| - return code;
|
| -}
|
| -
|
| -
|
| -Code* StubCache::Get(Name* name, Map* map, Code::Flags flags) {
|
| - flags = CommonStubCacheChecks(name, map, flags);
|
| - int primary_offset = PrimaryOffset(name, flags, map);
|
| - Entry* primary = entry(primary_, primary_offset);
|
| - if (primary->key == name && primary->map == map) {
|
| - return primary->value;
|
| - }
|
| - int secondary_offset = SecondaryOffset(name, flags, primary_offset);
|
| - Entry* secondary = entry(secondary_, secondary_offset);
|
| - if (secondary->key == name && secondary->map == map) {
|
| - return secondary->value;
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
|
|
| Handle<Code> PropertyICCompiler::Find(Handle<Name> name,
|
| Handle<Map> stub_holder, Code::Kind kind,
|
| ExtraICState extra_state,
|
| CacheHolderFlag cache_holder) {
|
| - Code::Flags flags = Code::ComputeMonomorphicFlags(
|
| - kind, extra_state, cache_holder);
|
| + Code::Flags flags =
|
| + Code::ComputeMonomorphicFlags(kind, extra_state, cache_holder);
|
| Object* probe = stub_holder->FindInCodeCache(*name, flags);
|
| if (probe->IsCode()) return handle(Code::cast(probe));
|
| return Handle<Code>::null();
|
| @@ -261,22 +172,14 @@ Handle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphic(
|
| compiler.CompileKeyedStoreMonomorphic(receiver_map, store_mode);
|
|
|
| Map::UpdateCodeCache(receiver_map, name, code);
|
| - DCHECK(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state())
|
| - == store_mode);
|
| + DCHECK(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) ==
|
| + store_mode);
|
| return code;
|
| }
|
|
|
|
|
| #define CALL_LOGGER_TAG(kind, type) (Logger::KEYED_##type)
|
|
|
| -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);
|
| -}
|
| -
|
|
|
| Code* PropertyICCompiler::FindPreMonomorphic(Isolate* isolate, Code::Kind kind,
|
| ExtraICState state) {
|
| @@ -292,6 +195,13 @@ Code* PropertyICCompiler::FindPreMonomorphic(Isolate* isolate, Code::Kind kind,
|
| }
|
|
|
|
|
| +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) {
|
| @@ -417,8 +327,8 @@ Handle<Code> PropertyICCompiler::ComputeKeyedStorePolymorphic(
|
| store_mode == STORE_NO_TRANSITION_HANDLE_COW);
|
| Handle<PolymorphicCodeCache> cache =
|
| isolate->factory()->polymorphic_code_cache();
|
| - ExtraICState extra_state = KeyedStoreIC::ComputeExtraICState(
|
| - strict_mode, store_mode);
|
| + 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);
|
| @@ -432,227 +342,10 @@ Handle<Code> PropertyICCompiler::ComputeKeyedStorePolymorphic(
|
| }
|
|
|
|
|
| -void StubCache::Clear() {
|
| - Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal);
|
| - for (int i = 0; i < kPrimaryTableSize; i++) {
|
| - primary_[i].key = isolate()->heap()->empty_string();
|
| - primary_[i].map = NULL;
|
| - primary_[i].value = empty;
|
| - }
|
| - for (int j = 0; j < kSecondaryTableSize; j++) {
|
| - secondary_[j].key = isolate()->heap()->empty_string();
|
| - secondary_[j].map = NULL;
|
| - secondary_[j].value = empty;
|
| - }
|
| -}
|
| -
|
| -
|
| -void StubCache::CollectMatchingMaps(SmallMapList* types,
|
| - Handle<Name> name,
|
| - Code::Flags flags,
|
| - Handle<Context> native_context,
|
| - Zone* zone) {
|
| - for (int i = 0; i < kPrimaryTableSize; i++) {
|
| - if (primary_[i].key == *name) {
|
| - Map* map = primary_[i].map;
|
| - // Map can be NULL, if the stub is constant function call
|
| - // with a primitive receiver.
|
| - if (map == NULL) continue;
|
| -
|
| - int offset = PrimaryOffset(*name, flags, map);
|
| - if (entry(primary_, offset) == &primary_[i] &&
|
| - !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
|
| - types->AddMapIfMissing(Handle<Map>(map), zone);
|
| - }
|
| - }
|
| - }
|
| -
|
| - for (int i = 0; i < kSecondaryTableSize; i++) {
|
| - if (secondary_[i].key == *name) {
|
| - Map* map = secondary_[i].map;
|
| - // Map can be NULL, if the stub is constant function call
|
| - // with a primitive receiver.
|
| - if (map == NULL) continue;
|
| -
|
| - // Lookup in primary table and skip duplicates.
|
| - int primary_offset = PrimaryOffset(*name, flags, map);
|
| -
|
| - // Lookup in secondary table and add matches.
|
| - int offset = SecondaryOffset(*name, flags, primary_offset);
|
| - if (entry(secondary_, offset) == &secondary_[i] &&
|
| - !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
|
| - types->AddMapIfMissing(Handle<Map>(map), zone);
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -
|
| -// ------------------------------------------------------------------------
|
| -// StubCompiler implementation.
|
| -
|
| -
|
| -RUNTIME_FUNCTION(StoreCallbackProperty) {
|
| - Handle<JSObject> receiver = args.at<JSObject>(0);
|
| - Handle<JSObject> holder = args.at<JSObject>(1);
|
| - Handle<ExecutableAccessorInfo> callback = args.at<ExecutableAccessorInfo>(2);
|
| - Handle<Name> name = args.at<Name>(3);
|
| - Handle<Object> value = args.at<Object>(4);
|
| - HandleScope scope(isolate);
|
| -
|
| - DCHECK(callback->IsCompatibleReceiver(*receiver));
|
| -
|
| - Address setter_address = v8::ToCData<Address>(callback->setter());
|
| - v8::AccessorNameSetterCallback fun =
|
| - FUNCTION_CAST<v8::AccessorNameSetterCallback>(setter_address);
|
| - DCHECK(fun != NULL);
|
| -
|
| - LOG(isolate, ApiNamedPropertyAccess("store", *receiver, *name));
|
| - PropertyCallbackArguments custom_args(isolate, callback->data(), *receiver,
|
| - *holder);
|
| - custom_args.Call(fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value));
|
| - RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
|
| - return *value;
|
| -}
|
| -
|
| -
|
| -/**
|
| - * Attempts to load a property with an interceptor (which must be present),
|
| - * but doesn't search the prototype chain.
|
| - *
|
| - * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't
|
| - * provide any value for the given name.
|
| - */
|
| -RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly) {
|
| - DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength);
|
| - Handle<Name> name_handle =
|
| - args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex);
|
| - Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(
|
| - NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex);
|
| -
|
| - // TODO(rossberg): Support symbols in the API.
|
| - if (name_handle->IsSymbol())
|
| - return isolate->heap()->no_interceptor_result_sentinel();
|
| - Handle<String> name = Handle<String>::cast(name_handle);
|
| -
|
| - Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
|
| - v8::NamedPropertyGetterCallback getter =
|
| - FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address);
|
| - DCHECK(getter != NULL);
|
| -
|
| - Handle<JSObject> receiver =
|
| - args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
|
| - Handle<JSObject> holder =
|
| - args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex);
|
| - PropertyCallbackArguments callback_args(
|
| - isolate, interceptor_info->data(), *receiver, *holder);
|
| - {
|
| - // Use the interceptor getter.
|
| - HandleScope scope(isolate);
|
| - v8::Handle<v8::Value> r =
|
| - callback_args.Call(getter, v8::Utils::ToLocal(name));
|
| - RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
|
| - if (!r.IsEmpty()) {
|
| - Handle<Object> result = v8::Utils::OpenHandle(*r);
|
| - result->VerifyApiCallResultType();
|
| - return *v8::Utils::OpenHandle(*r);
|
| - }
|
| - }
|
| -
|
| - return isolate->heap()->no_interceptor_result_sentinel();
|
| -}
|
| -
|
| -
|
| -static Object* ThrowReferenceError(Isolate* isolate, Name* name) {
|
| - // If the load is non-contextual, just return the undefined result.
|
| - // Note that both keyed and non-keyed loads may end up here.
|
| - HandleScope scope(isolate);
|
| - LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
|
| - if (ic.contextual_mode() != CONTEXTUAL) {
|
| - return isolate->heap()->undefined_value();
|
| - }
|
| -
|
| - // Throw a reference error.
|
| - Handle<Name> name_handle(name);
|
| - Handle<Object> error =
|
| - isolate->factory()->NewReferenceError("not_defined",
|
| - HandleVector(&name_handle, 1));
|
| - return isolate->Throw(*error);
|
| -}
|
| -
|
| -
|
| -/**
|
| - * Loads a property with an interceptor performing post interceptor
|
| - * lookup if interceptor failed.
|
| - */
|
| -RUNTIME_FUNCTION(LoadPropertyWithInterceptor) {
|
| - HandleScope scope(isolate);
|
| - DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength);
|
| - Handle<Name> name =
|
| - args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex);
|
| - Handle<JSObject> receiver =
|
| - args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
|
| - Handle<JSObject> holder =
|
| - args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex);
|
| -
|
| - Handle<Object> result;
|
| - LookupIterator it(receiver, name, holder);
|
| - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
| - isolate, result, JSObject::GetProperty(&it));
|
| -
|
| - if (it.IsFound()) return *result;
|
| -
|
| - return ThrowReferenceError(isolate, Name::cast(args[0]));
|
| -}
|
| -
|
| -
|
| -RUNTIME_FUNCTION(StorePropertyWithInterceptor) {
|
| - HandleScope scope(isolate);
|
| - DCHECK(args.length() == 3);
|
| - StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
|
| - Handle<JSObject> receiver = args.at<JSObject>(0);
|
| - Handle<Name> name = args.at<Name>(1);
|
| - Handle<Object> value = args.at<Object>(2);
|
| -#ifdef DEBUG
|
| - PrototypeIterator iter(isolate, receiver,
|
| - PrototypeIterator::START_AT_RECEIVER);
|
| - bool found = false;
|
| - while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
|
| - Handle<Object> current = PrototypeIterator::GetCurrent(iter);
|
| - if (current->IsJSObject() &&
|
| - Handle<JSObject>::cast(current)->HasNamedInterceptor()) {
|
| - found = true;
|
| - break;
|
| - }
|
| - }
|
| - DCHECK(found);
|
| -#endif
|
| - Handle<Object> result;
|
| - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
| - isolate, result,
|
| - JSObject::SetProperty(receiver, name, value, ic.strict_mode()));
|
| - return *result;
|
| -}
|
| -
|
| -
|
| -RUNTIME_FUNCTION(LoadElementWithInterceptor) {
|
| - HandleScope scope(isolate);
|
| - Handle<JSObject> receiver = args.at<JSObject>(0);
|
| - DCHECK(args.smi_at(1) >= 0);
|
| - uint32_t index = args.smi_at(1);
|
| - Handle<Object> result;
|
| - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
| - isolate, result,
|
| - JSObject::GetElementWithInterceptor(receiver, receiver, index));
|
| - return *result;
|
| -}
|
| -
|
| -
|
| Handle<Code> PropertyICCompiler::CompileLoadInitialize(Code::Flags flags) {
|
| LoadIC::GenerateInitialize(masm());
|
| Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadInitialize");
|
| - PROFILE(isolate(),
|
| - CodeCreateEvent(Logger::LOAD_INITIALIZE_TAG, *code, 0));
|
| + PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_INITIALIZE_TAG, *code, 0));
|
| return code;
|
| }
|
|
|
| @@ -669,8 +362,7 @@ Handle<Code> PropertyICCompiler::CompileLoadPreMonomorphic(Code::Flags flags) {
|
| Handle<Code> PropertyICCompiler::CompileLoadMegamorphic(Code::Flags flags) {
|
| LoadIC::GenerateMegamorphic(masm());
|
| Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadMegamorphic");
|
| - PROFILE(isolate(),
|
| - CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0));
|
| + PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0));
|
| return code;
|
| }
|
|
|
| @@ -678,8 +370,7 @@ Handle<Code> PropertyICCompiler::CompileLoadMegamorphic(Code::Flags flags) {
|
| Handle<Code> PropertyICCompiler::CompileStoreInitialize(Code::Flags flags) {
|
| StoreIC::GenerateInitialize(masm());
|
| Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreInitialize");
|
| - PROFILE(isolate(),
|
| - CodeCreateEvent(Logger::STORE_INITIALIZE_TAG, *code, 0));
|
| + PROFILE(isolate(), CodeCreateEvent(Logger::STORE_INITIALIZE_TAG, *code, 0));
|
| return code;
|
| }
|
|
|
| @@ -698,8 +389,7 @@ Handle<Code> PropertyICCompiler::CompileStoreGeneric(Code::Flags flags) {
|
| StrictMode strict_mode = StoreIC::GetStrictMode(extra_state);
|
| StoreIC::GenerateRuntimeSetProperty(masm(), strict_mode);
|
| Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreGeneric");
|
| - PROFILE(isolate(),
|
| - CodeCreateEvent(Logger::STORE_GENERIC_TAG, *code, 0));
|
| + PROFILE(isolate(), CodeCreateEvent(Logger::STORE_GENERIC_TAG, *code, 0));
|
| return code;
|
| }
|
|
|
| @@ -707,8 +397,7 @@ Handle<Code> PropertyICCompiler::CompileStoreGeneric(Code::Flags flags) {
|
| Handle<Code> PropertyICCompiler::CompileStoreMegamorphic(Code::Flags flags) {
|
| StoreIC::GenerateMegamorphic(masm());
|
| Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic");
|
| - PROFILE(isolate(),
|
| - CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0));
|
| + PROFILE(isolate(), CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0));
|
| return code;
|
| }
|
|
|
| @@ -736,8 +425,9 @@ Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
|
| Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
|
| Handle<Name> name) {
|
| return (FLAG_print_code_stubs && !name.is_null() && name->IsString())
|
| - ? GetCodeWithFlags(flags, Handle<String>::cast(name)->ToCString().get())
|
| - : GetCodeWithFlags(flags, NULL);
|
| + ? GetCodeWithFlags(flags,
|
| + Handle<String>::cast(name)->ToCString().get())
|
| + : GetCodeWithFlags(flags, NULL);
|
| }
|
|
|
|
|
| @@ -762,8 +452,8 @@ Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
|
| }
|
|
|
| if (check_type == CHECK_ALL_MAPS) {
|
| - GenerateDirectLoadGlobalFunctionPrototype(
|
| - masm(), function_index, scratch1(), miss);
|
| + GenerateDirectLoadGlobalFunctionPrototype(masm(), function_index,
|
| + scratch1(), miss);
|
| Object* function = isolate()->native_context()->get(function_index);
|
| Object* prototype = JSFunction::cast(function)->instance_prototype();
|
| set_type_for_object(handle(prototype, isolate()));
|
| @@ -885,9 +575,8 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
|
| DCHECK(call_optimization.is_simple_api_call());
|
| Frontend(receiver(), name);
|
| Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate());
|
| - GenerateFastApiCall(
|
| - masm(), call_optimization, receiver_map,
|
| - receiver(), scratch1(), false, 0, NULL);
|
| + GenerateFastApiCall(masm(), call_optimization, receiver_map, receiver(),
|
| + scratch1(), false, 0, NULL);
|
| return GetCode(kind(), Code::FAST, name);
|
| }
|
|
|
| @@ -1033,10 +722,9 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
|
| Handle<JSObject> object, Handle<Name> name,
|
| const CallOptimization& call_optimization) {
|
| Frontend(receiver(), name);
|
| - Register values[] = { value() };
|
| - GenerateFastApiCall(
|
| - masm(), call_optimization, handle(object->map()),
|
| - receiver(), scratch1(), true, 1, values);
|
| + Register values[] = {value()};
|
| + GenerateFastApiCall(masm(), call_optimization, handle(object->map()),
|
| + receiver(), scratch1(), true, 1, values);
|
| return GetCode(kind(), Code::FAST, name);
|
| }
|
|
|
| @@ -1198,8 +886,7 @@ CallOptimization::CallOptimization(Handle<JSFunction> function) {
|
|
|
|
|
| Handle<JSObject> CallOptimization::LookupHolderOfExpectedType(
|
| - Handle<Map> object_map,
|
| - HolderLookup* holder_lookup) const {
|
| + Handle<Map> object_map, HolderLookup* holder_lookup) const {
|
| DCHECK(is_simple_api_call());
|
| if (!object_map->IsJSObjectMap()) {
|
| *holder_lookup = kHolderNotFound;
|
| @@ -1231,8 +918,7 @@ bool CallOptimization::IsCompatibleReceiver(Handle<Object> receiver,
|
| if (!receiver->IsJSObject()) return false;
|
| Handle<Map> map(JSObject::cast(*receiver)->map());
|
| HolderLookup holder_lookup;
|
| - Handle<JSObject> api_holder =
|
| - LookupHolderOfExpectedType(map, &holder_lookup);
|
| + Handle<JSObject> api_holder = LookupHolderOfExpectedType(map, &holder_lookup);
|
| switch (holder_lookup) {
|
| case kHolderNotFound:
|
| return false;
|
| @@ -1286,14 +972,12 @@ void CallOptimization::AnalyzePossibleApiFunction(Handle<JSFunction> function) {
|
| Handle<SignatureInfo>(SignatureInfo::cast(info->signature()));
|
| if (!signature->args()->IsUndefined()) return;
|
| if (!signature->receiver()->IsUndefined()) {
|
| - expected_receiver_type_ =
|
| - Handle<FunctionTemplateInfo>(
|
| - FunctionTemplateInfo::cast(signature->receiver()));
|
| + expected_receiver_type_ = Handle<FunctionTemplateInfo>(
|
| + FunctionTemplateInfo::cast(signature->receiver()));
|
| }
|
| }
|
|
|
| is_simple_api_call_ = true;
|
| }
|
| -
|
| -
|
| -} } // namespace v8::internal
|
| +}
|
| +} // namespace v8::internal
|
|
|