📄 stub-cache.cc.svn-base
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met://// * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following// disclaimer in the documentation and/or other materials provided// with the distribution.// * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived// from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include "v8.h"#include "api.h"#include "arguments.h"#include "ic-inl.h"#include "stub-cache.h"namespace v8 { namespace internal {// -----------------------------------------------------------------------// StubCache implementation.StubCache::Entry StubCache::primary_[StubCache::kPrimaryTableSize];StubCache::Entry StubCache::secondary_[StubCache::kSecondaryTableSize];void StubCache::Initialize(bool create_heap_objects) { ASSERT(IsPowerOf2(kPrimaryTableSize)); ASSERT(IsPowerOf2(kSecondaryTableSize)); if (create_heap_objects) { HandleScope scope; Clear(); }}Code* StubCache::Set(String* name, Map* map, Code* code) { // Get the flags from the code. Code::Flags flags = Code::RemoveTypeFromFlags(code->flags()); // Validate that the name does not move on scavenge, and that we // can use identity checks instead of string equality checks. ASSERT(!Heap::InNewSpace(name)); ASSERT(name->IsSymbol()); // The state bits are not important to the hash function because // the stub cache only contains monomorphic stubs. Make sure that // the bits are the least significant so they will be the ones // masked out. ASSERT(Code::ExtractICStateFromFlags(flags) == MONOMORPHIC); ASSERT(Code::kFlagsICStateShift == 0); // Make sure that the code type is not included in the hash. ASSERT(Code::ExtractTypeFromFlags(flags) == 0); // Compute the primary entry. int primary_offset = PrimaryOffset(name, flags, map); Entry* primary = entry(primary_, primary_offset); Code* hit = primary->value; // If the primary entry has useful data in it, we retire it to the // secondary cache before overwriting it. if (hit != Builtins::builtin(Builtins::Illegal)) { Code::Flags primary_flags = Code::RemoveTypeFromFlags(hit->flags()); int secondary_offset = SecondaryOffset(primary->key, primary_flags, primary_offset); Entry* secondary = entry(secondary_, secondary_offset); *secondary = *primary; } // Update primary cache. primary->key = name; primary->value = code; return code;}Object* StubCache::ComputeLoadField(String* name, JSObject* receiver, JSObject* holder, int field_index) { Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD); Object* code = receiver->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { LoadStubCompiler compiler; code = compiler.CompileLoadField(receiver, holder, field_index); if (code->IsFailure()) return code; LOG(CodeCreateEvent("LoadIC", Code::cast(code), name)); Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return code; } return Set(name, receiver->map(), Code::cast(code));}Object* StubCache::ComputeLoadCallback(String* name, JSObject* receiver, JSObject* holder, AccessorInfo* callback) { ASSERT(v8::ToCData<Address>(callback->getter()) != 0); Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS); Object* code = receiver->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { LoadStubCompiler compiler; code = compiler.CompileLoadCallback(receiver, holder, callback); if (code->IsFailure()) return code; LOG(CodeCreateEvent("LoadIC", Code::cast(code), name)); Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return code; } return Set(name, receiver->map(), Code::cast(code));}Object* StubCache::ComputeLoadConstant(String* name, JSObject* receiver, JSObject* holder, Object* value) { Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION); Object* code = receiver->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { LoadStubCompiler compiler; code = compiler.CompileLoadConstant(receiver, holder, value); if (code->IsFailure()) return code; LOG(CodeCreateEvent("LoadIC", Code::cast(code), name)); Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return code; } return Set(name, receiver->map(), Code::cast(code));}Object* StubCache::ComputeLoadInterceptor(String* name, JSObject* receiver, JSObject* holder) { Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR); Object* code = receiver->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { LoadStubCompiler compiler; code = compiler.CompileLoadInterceptor(receiver, holder, name); if (code->IsFailure()) return code; LOG(CodeCreateEvent("LoadIC", Code::cast(code), name)); Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return code; } return Set(name, receiver->map(), Code::cast(code));}Object* StubCache::ComputeLoadNormal(String* name, JSObject* receiver) { Code* code = Builtins::builtin(Builtins::LoadIC_Normal); return Set(name, receiver->map(), code);}Object* StubCache::ComputeKeyedLoadField(String* name, JSObject* receiver, JSObject* holder, int field_index) { Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD); Object* code = receiver->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { KeyedLoadStubCompiler compiler; code = compiler.CompileLoadField(name, receiver, holder, field_index); if (code->IsFailure()) return code; LOG(CodeCreateEvent("KeyedLoadIC", Code::cast(code), name)); Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return result; } return code;}Object* StubCache::ComputeKeyedLoadConstant(String* name, JSObject* receiver, JSObject* holder, Object* value) { Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION); Object* code = receiver->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { KeyedLoadStubCompiler compiler; code = compiler.CompileLoadConstant(name, receiver, holder, value); if (code->IsFailure()) return code; LOG(CodeCreateEvent("KeyedLoadIC", Code::cast(code), name)); Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return result; } return code;}Object* StubCache::ComputeKeyedLoadInterceptor(String* name, JSObject* receiver, JSObject* holder) { Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR); Object* code = receiver->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { KeyedLoadStubCompiler compiler; code = compiler.CompileLoadInterceptor(receiver, holder, name); if (code->IsFailure()) return code; LOG(CodeCreateEvent("KeyedLoadIC", Code::cast(code), name)); Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return result; } return code;}Object* StubCache::ComputeKeyedLoadCallback(String* name, JSObject* receiver, JSObject* holder, AccessorInfo* callback) { Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); Object* code = receiver->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { KeyedLoadStubCompiler compiler; code = compiler.CompileLoadCallback(name, receiver, holder, callback); if (code->IsFailure()) return code; LOG(CodeCreateEvent("KeyedLoadIC", Code::cast(code), name)); Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return result; } return code;}Object* StubCache::ComputeKeyedLoadArrayLength(String* name, JSArray* receiver) { Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); Object* code = receiver->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { KeyedLoadStubCompiler compiler; code = compiler.CompileLoadArrayLength(name); if (code->IsFailure()) return code; LOG(CodeCreateEvent("KeyedLoadIC", Code::cast(code), name)); Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return result; } return code;}Object* StubCache::ComputeKeyedLoadShortStringLength(String* name, String* receiver) { Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); Object* code = receiver->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { KeyedLoadStubCompiler compiler; code = compiler.CompileLoadShortStringLength(name); if (code->IsFailure()) return code; LOG(CodeCreateEvent("KeyedLoadIC", Code::cast(code), name)); Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return result; } return code;}Object* StubCache::ComputeKeyedLoadMediumStringLength(String* name, String* receiver) { Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); Object* code = receiver->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { KeyedLoadStubCompiler compiler; code = compiler.CompileLoadMediumStringLength(name); if (code->IsFailure()) return code; LOG(CodeCreateEvent("KeyedLoadIC", Code::cast(code), name)); Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return result; } return code;}Object* StubCache::ComputeKeyedLoadLongStringLength(String* name, String* receiver) { Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); Object* code = receiver->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { KeyedLoadStubCompiler compiler; code = compiler.CompileLoadLongStringLength(name); if (code->IsFailure()) return code; LOG(CodeCreateEvent("KeyedLoadIC", Code::cast(code), name)); Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return result; } return code;}Object* StubCache::ComputeKeyedLoadFunctionPrototype(String* name, JSFunction* receiver) { Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -