📄 stub-cache.cc.svn-base
字号:
Code::Flags flags = Code::ComputeFlags(Code::STUB, UNINITIALIZED, NORMAL, argc); Object* probe = ProbeCache(flags); if (!probe->IsUndefined()) return probe; StubCompiler compiler; Object* result = FillCache(compiler.CompileLazyCompile(flags)); if (result->IsCode()) { Code* code = Code::cast(result); USE(code); LOG(CodeCreateEvent("LazyCompile", code, code->arguments_count())); } return result;}void StubCache::Clear() { for (int i = 0; i < kPrimaryTableSize; i++) { primary_[i].key = Heap::empty_string(); primary_[i].value = Builtins::builtin(Builtins::Illegal); } for (int j = 0; j < kSecondaryTableSize; j++) { secondary_[j].key = Heap::empty_string(); secondary_[j].value = Builtins::builtin(Builtins::Illegal); }}// ------------------------------------------------------------------------// StubCompiler implementation.// Support function for computing call IC miss stubs.Handle<Code> ComputeCallMiss(int argc) { CALL_HEAP_FUNCTION(StubCache::ComputeCallMiss(argc), Code);}Object* LoadCallbackProperty(Arguments args) { Handle<JSObject> recv = args.at<JSObject>(0); AccessorInfo* callback = AccessorInfo::cast(args[1]); v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>( v8::ToCData<Address>(callback->getter())); ASSERT(fun != NULL); Handle<String> name = args.at<String>(2); Handle<JSObject> holder = args.at<JSObject>(3); HandleScope scope; Handle<Object> data(callback->data()); LOG(ApiNamedPropertyAccess("load", *recv, *name)); // NOTE: If we can align the structure of an AccessorInfo with the // locations of the arguments to this function maybe we don't have // to explicitly create the structure but can just pass a pointer // into the stack. v8::AccessorInfo info( v8::Utils::ToLocal(recv), v8::Utils::ToLocal(data), v8::Utils::ToLocal(holder)); v8::Handle<v8::Value> result; { // Leaving JavaScript. VMState state(OTHER); result = fun(v8::Utils::ToLocal(name), info); } RETURN_IF_SCHEDULED_EXCEPTION(); if (result.IsEmpty()) { return Heap::undefined_value(); } else { return *v8::Utils::OpenHandle(*result); }}Object* StoreCallbackProperty(Arguments args) { Handle<JSObject> recv = args.at<JSObject>(0); AccessorInfo* callback = AccessorInfo::cast(args[1]); v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>( v8::ToCData<Address>(callback->setter())); ASSERT(fun != NULL); Handle<String> name = args.at<String>(2); Handle<Object> value = args.at<Object>(3); HandleScope scope; Handle<Object> data(callback->data()); LOG(ApiNamedPropertyAccess("store", *recv, *name)); v8::AccessorInfo info( v8::Utils::ToLocal(recv), v8::Utils::ToLocal(data), v8::Utils::ToLocal(recv)); { // Leaving JavaScript. VMState state(OTHER); fun(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info); } RETURN_IF_SCHEDULED_EXCEPTION(); return *value;}Object* LoadInterceptorProperty(Arguments args) { HandleScope scope; Handle<JSObject> recv = args.at<JSObject>(0); Handle<JSObject> holder = args.at<JSObject>(1); Handle<String> name = args.at<String>(2); ASSERT(holder->HasNamedInterceptor()); PropertyAttributes attr = NONE; Handle<Object> result = GetPropertyWithInterceptor(recv, holder, name, &attr); // GetPropertyWithInterceptor already converts a scheduled exception // to a pending one if any. Don't use RETURN_IF_SCHEDULED_EXCEPTION() here. // Make sure to propagate exceptions. if (result.is_null()) { // Failure::Exception is converted to a null handle in the // handle-based methods such as SetProperty. We therefore need // to convert null handles back to exceptions. ASSERT(Top::has_pending_exception()); return Failure::Exception(); } // If the property is present, return it. if (attr != ABSENT) return *result; // If the top frame is an internal frame, this is really a call // IC. In this case, we simply return the undefined result which // will lead to an exception when trying to invoke the result as a // function. StackFrameIterator it; it.Advance(); // skip exit frame if (it.frame()->is_internal()) return *result; // If the load is non-contextual, just return the undefined result. // Note that both keyed and non-keyed loads may end up here, so we // can't use either LoadIC or KeyedLoadIC constructors. IC ic(IC::NO_EXTRA_FRAME); ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub()); if (!ic.is_contextual()) return *result; // Throw a reference error. Handle<Object> error = Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); return Top::Throw(*error);}Object* StoreInterceptorProperty(Arguments args) { HandleScope scope; Handle<JSObject> recv = args.at<JSObject>(0); Handle<String> name = args.at<String>(1); Handle<Object> value = args.at<Object>(2); ASSERT(recv->HasNamedInterceptor()); PropertyAttributes attr = NONE; Handle<Object> result = SetPropertyWithInterceptor(recv, name, value, attr); // SetPropertyWithInterceptor already converts a scheduled exception // to a pending one if any. Don't use RETURN_IF_SCHEDULED_EXCEPTION() here. // Make sure to propagate exceptions. if (result.is_null()) { // Failure::Exception is converted to a null handle in the // handle-based methods such as SetProperty. We therefore need // to convert null handles back to exceptions. ASSERT(Top::has_pending_exception()); return Failure::Exception(); } return *result;}Object* StubCompiler::CompileCallInitialize(Code::Flags flags) { HandleScope scope; int argc = Code::ExtractArgumentsCountFromFlags(flags); CallIC::GenerateInitialize(masm(), argc); Object* result = GetCodeWithFlags(flags); if (!result->IsFailure()) { Counters::call_initialize_stubs.Increment(); Code* code = Code::cast(result); USE(code); LOG(CodeCreateEvent("CallInitialize", code, code->arguments_count())); } return result;}Object* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { HandleScope scope; int argc = Code::ExtractArgumentsCountFromFlags(flags); CallIC::GenerateInitialize(masm(), argc); Object* result = GetCodeWithFlags(flags); if (!result->IsFailure()) { Counters::call_premonomorphic_stubs.Increment(); Code* code = Code::cast(result); USE(code); LOG(CodeCreateEvent("CallPreMonomorphic", code, code->arguments_count())); } return result;}Object* StubCompiler::CompileCallNormal(Code::Flags flags) { HandleScope scope; int argc = Code::ExtractArgumentsCountFromFlags(flags); CallIC::GenerateNormal(masm(), argc); Object* result = GetCodeWithFlags(flags); if (!result->IsFailure()) { Counters::call_normal_stubs.Increment(); Code* code = Code::cast(result); USE(code); LOG(CodeCreateEvent("CallNormal", code, code->arguments_count())); } return result;}Object* StubCompiler::CompileCallMegamorphic(Code::Flags flags) { HandleScope scope; int argc = Code::ExtractArgumentsCountFromFlags(flags); CallIC::GenerateMegamorphic(masm(), argc); Object* result = GetCodeWithFlags(flags); if (!result->IsFailure()) { Counters::call_megamorphic_stubs.Increment(); Code* code = Code::cast(result); USE(code); LOG(CodeCreateEvent("CallMegamorphic", code, code->arguments_count())); } return result;}Object* StubCompiler::CompileCallMiss(Code::Flags flags) { HandleScope scope; int argc = Code::ExtractArgumentsCountFromFlags(flags); CallIC::GenerateMiss(masm(), argc); Object* result = GetCodeWithFlags(flags); if (!result->IsFailure()) { Counters::call_megamorphic_stubs.Increment(); Code* code = Code::cast(result); USE(code); LOG(CodeCreateEvent("CallMiss", code, code->arguments_count())); } return result;}Object* StubCompiler::CompileCallDebugBreak(Code::Flags flags) { HandleScope scope; Builtins::Generate_CallIC_DebugBreak(masm()); Object* result = GetCodeWithFlags(flags); if (!result->IsFailure()) { Code* code = Code::cast(result); USE(code); LOG(CodeCreateEvent("CallDebugBreak", code, code->arguments_count())); } return result;}Object* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { HandleScope scope; // Use the same code for the the step in preparations as we do for // the miss case. int argc = Code::ExtractArgumentsCountFromFlags(flags); CallIC::GenerateMiss(masm(), argc); Object* result = GetCodeWithFlags(flags); if (!result->IsFailure()) { Code* code = Code::cast(result); USE(code); LOG(CodeCreateEvent("CallDebugPrepareStepIn", code, code->arguments_count())); } return result;}Object* StubCompiler::GetCodeWithFlags(Code::Flags flags) { CodeDesc desc; masm_.GetCode(&desc); Object* result = Heap::CreateCode(desc, NULL, flags);#ifdef DEBUG if (FLAG_print_code_stubs && !result->IsFailure()) { Code::cast(result)->Print(); }#endif return result;}Object* LoadStubCompiler::GetCode(PropertyType type) { return GetCodeWithFlags(Code::ComputeMonomorphicFlags(Code::LOAD_IC, type));}Object* KeyedLoadStubCompiler::GetCode(PropertyType type) { return GetCodeWithFlags(Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, type));}Object* StoreStubCompiler::GetCode(PropertyType type) { return GetCodeWithFlags(Code::ComputeMonomorphicFlags(Code::STORE_IC, type));}Object* KeyedStoreStubCompiler::GetCode(PropertyType type) { return GetCodeWithFlags(Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, type));}Object* CallStubCompiler::GetCode(PropertyType type) { int argc = arguments_.immediate(); Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, type, argc); return GetCodeWithFlags(flags);}} } // namespace v8::internal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -