⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stub-cache-ia32.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
// 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 "ic-inl.h"#include "codegen-inl.h"#include "stub-cache.h"namespace v8 { namespace internal {#define __ masm->static void ProbeTable(MacroAssembler* masm,                       Code::Flags flags,                       StubCache::Table table,                       Register name,                       Register offset) {  ExternalReference key_offset(SCTableReference::keyReference(table));  ExternalReference value_offset(SCTableReference::valueReference(table));  Label miss;  // Save the offset on the stack.  __ push(offset);  // Check that the key in the entry matches the name.  __ cmp(name, Operand::StaticArray(offset, times_2, key_offset));  __ j(not_equal, &miss, not_taken);  // Get the code entry from the cache.  __ mov(offset, Operand::StaticArray(offset, times_2, value_offset));  // Check that the flags match what we're looking for.  __ mov(offset, FieldOperand(offset, Code::kFlagsOffset));  __ and_(offset, ~Code::kFlagsTypeMask);  __ cmp(offset, flags);  __ j(not_equal, &miss);  // Restore offset and re-load code entry from cache.  __ pop(offset);  __ mov(offset, Operand::StaticArray(offset, times_2, value_offset));  // Jump to the first instruction in the code stub.  __ add(Operand(offset), Immediate(Code::kHeaderSize - kHeapObjectTag));  __ jmp(Operand(offset));  // Miss: Restore offset and fall through.  __ bind(&miss);  __ pop(offset);}void StubCache::GenerateProbe(MacroAssembler* masm,                              Code::Flags flags,                              Register receiver,                              Register name,                              Register scratch) {  Label miss;  // Make sure that code is valid. The shifting code relies on the  // entry size being 8.  ASSERT(sizeof(Entry) == 8);  // Make sure the flags does not name a specific type.  ASSERT(Code::ExtractTypeFromFlags(flags) == 0);  // Make sure that there are no register conflicts.  ASSERT(!scratch.is(receiver));  ASSERT(!scratch.is(name));  // Check that the receiver isn't a smi.  __ test(receiver, Immediate(kSmiTagMask));  __ j(zero, &miss, not_taken);  // Get the map of the receiver and compute the hash.  __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset));  __ add(scratch, FieldOperand(name, String::kLengthOffset));  __ xor_(scratch, flags);  __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize);  // Probe the primary table.  ProbeTable(masm, flags, kPrimary, name, scratch);  // Primary miss: Compute hash for secondary probe.  __ sub(scratch, Operand(name));  __ add(Operand(scratch), Immediate(flags));  __ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize);  // Probe the secondary table.  ProbeTable(masm, flags, kSecondary, name, scratch);  // Cache miss: Fall-through and let caller handle the miss by  // entering the runtime system.  __ bind(&miss);}void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,                                                       int index,                                                       Register prototype) {  // Load the global or builtins object from the current context.  __ mov(prototype, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));  // Load the global context from the global or builtins object.  __ mov(prototype,         FieldOperand(prototype, GlobalObject::kGlobalContextOffset));  // Load the function from the global context.  __ mov(prototype, Operand(prototype, Context::SlotOffset(index)));  // Load the initial map.  The global functions all have initial maps.  __ mov(prototype,         FieldOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset));  // Load the prototype from the initial map.  __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));}void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm,                                           Register receiver,                                           Register scratch,                                           Label* miss_label) {  // Check that the receiver isn't a smi.  __ test(receiver, Immediate(kSmiTagMask));  __ j(zero, miss_label, not_taken);  // Check that the object is a JS array.  __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset));  __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));  __ cmp(scratch, JS_ARRAY_TYPE);  __ j(not_equal, miss_label, not_taken);  // Load length directly from the JS array.  __ mov(eax, FieldOperand(receiver, JSArray::kLengthOffset));  __ ret(0);}void StubCompiler::GenerateLoadShortStringLength(MacroAssembler* masm,                                                 Register receiver,                                                 Register scratch,                                                 Label* miss_label) {  // Check that the receiver isn't a smi.  __ test(receiver, Immediate(kSmiTagMask));  __ j(zero, miss_label, not_taken);  // Check that the object is a short string.  __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset));  __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));  __ and_(scratch, kIsNotStringMask | kStringSizeMask);  __ cmp(scratch, kStringTag | kShortStringTag);  __ j(not_equal, miss_label, not_taken);  // Load length directly from the string.  __ mov(eax, FieldOperand(receiver, String::kLengthOffset));  __ shr(eax, String::kShortLengthShift);  __ shl(eax, kSmiTagSize);  __ ret(0);}void StubCompiler::GenerateLoadMediumStringLength(MacroAssembler* masm,                                                  Register receiver,                                                  Register scratch,                                                  Label* miss_label) {  // Check that the receiver isn't a smi.  __ test(receiver, Immediate(kSmiTagMask));  __ j(zero, miss_label, not_taken);  // Check that the object is a short string.  __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset));  __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));  __ and_(scratch, kIsNotStringMask | kStringSizeMask);  __ cmp(scratch, kStringTag | kMediumStringTag);  __ j(not_equal, miss_label, not_taken);  // Load length directly from the string.  __ mov(eax, FieldOperand(receiver, String::kLengthOffset));  __ shr(eax, String::kMediumLengthShift);  __ shl(eax, kSmiTagSize);  __ ret(0);}void StubCompiler::GenerateLoadLongStringLength(MacroAssembler* masm,                                                Register receiver,                                                Register scratch,                                                Label* miss_label) {  // Check that the receiver isn't a smi.  __ test(receiver, Immediate(kSmiTagMask));  __ j(zero, miss_label, not_taken);  // Check that the object is a short string.  __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset));  __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));  __ and_(scratch, kIsNotStringMask | kStringSizeMask);  __ cmp(scratch, kStringTag | kLongStringTag);  __ j(not_equal, miss_label, not_taken);  // Load length directly from the string.  __ mov(eax, FieldOperand(receiver, String::kLengthOffset));  __ shr(eax, String::kLongLengthShift);  __ shl(eax, kSmiTagSize);  __ ret(0);}void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,                                                 Register receiver,                                                 Register scratch1,                                                 Register scratch2,                                                 Label* miss_label) {  // Check that the receiver isn't a smi.  __ test(receiver, Immediate(kSmiTagMask));  __ j(zero, miss_label, not_taken);  // Check that the receiver is a function.  __ mov(scratch1, FieldOperand(receiver, HeapObject::kMapOffset));  __ movzx_b(scratch2, FieldOperand(scratch1, Map::kInstanceTypeOffset));  __ cmp(scratch2, JS_FUNCTION_TYPE);  __ j(not_equal, miss_label, not_taken);  // Make sure that the function has an instance prototype.  Label non_instance;  __ movzx_b(scratch2, FieldOperand(scratch1, Map::kBitFieldOffset));  __ test(scratch2, Immediate(1 << Map::kHasNonInstancePrototype));  __ j(not_zero, &non_instance, not_taken);  // Get the prototype or initial map from the function.  __ mov(scratch1,         FieldOperand(receiver, JSFunction::kPrototypeOrInitialMapOffset));  // If the prototype or initial map is the hole, don't return it and  // simply miss the cache instead. This will allow us to allocate a  // prototype object on-demand in the runtime system.  __ cmp(Operand(scratch1), Immediate(Factory::the_hole_value()));  __ j(equal, miss_label, not_taken);  __ mov(eax, Operand(scratch1));  // If the function does not have an initial map, we're done.  Label done;  __ mov(scratch1, FieldOperand(eax, HeapObject::kMapOffset));  __ movzx_b(scratch2, FieldOperand(scratch1, Map::kInstanceTypeOffset));  __ cmp(scratch2, MAP_TYPE);  __ j(not_equal, &done);  // Get the prototype from the initial map.  __ mov(eax, FieldOperand(eax, Map::kPrototypeOffset));  // All done: Return the prototype.  __ bind(&done);  __ ret(0);  // Non-instance prototype: Fetch prototype from constructor field  // in initial map.  __ bind(&non_instance);  __ mov(eax, FieldOperand(scratch1, Map::kConstructorOffset));  __ ret(0);}void StubCompiler::GenerateLoadField(MacroAssembler* masm,                                     JSObject* object,                                     JSObject* holder,                                     Register receiver,                                     Register scratch1,                                     Register scratch2,                                     int index,                                     Label* miss_label) {  // Check that the receiver isn't a smi.  __ test(receiver, Immediate(kSmiTagMask));  __ j(zero, miss_label, not_taken);  // Check that the maps haven't changed.  Register reg =      __ CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);  // Get the properties array of the holder.  __ mov(scratch1, FieldOperand(reg, JSObject::kPropertiesOffset));  // Return the value from the properties array.  int offset = index * kPointerSize + Array::kHeaderSize;  __ mov(eax, FieldOperand(scratch1, offset));  __ ret(0);}void StubCompiler::GenerateLoadCallback(MacroAssembler* masm,                                        JSObject* object,                                        JSObject* holder,                                        Register receiver,                                        Register name,                                        Register scratch1,                                        Register scratch2,                                        AccessorInfo* callback,                                        Label* miss_label) {  // Check that the receiver isn't a smi.  __ test(receiver, Immediate(kSmiTagMask));  __ j(zero, miss_label, not_taken);  // Check that the maps haven't changed.  Register reg =      __ CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);  // Push the arguments on the JS stack of the caller.  __ pop(scratch2);  // remove return address  __ push(receiver);  // receiver  __ push(Immediate(Handle<AccessorInfo>(callback)));  // callback data  __ push(name);  // name  __ push(reg);  // holder  __ push(scratch2);  // restore return address  // Do tail-call to the runtime system.  ExternalReference load_callback_property =      ExternalReference(IC_Utility(IC::kLoadCallbackProperty));  __ TailCallRuntime(load_callback_property, 4);}void StubCompiler::GenerateLoadConstant(MacroAssembler* masm,                                        JSObject* object,                                        JSObject* holder,                                        Register receiver,                                        Register scratch1,                                        Register scratch2,                                        Object* value,                                        Label* miss_label) {  // Check that the receiver isn't a smi.  __ test(receiver, Immediate(kSmiTagMask));  __ j(zero, miss_label, not_taken);  // Check that the maps haven't changed.  Register reg =      __ CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);  // Return the constant value.  __ mov(eax, Handle<Object>(value));  __ ret(0);}void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm,                                           JSObject* object,                                           JSObject* holder,                                           Register receiver,                                           Register name,                                           Register scratch1,                                           Register scratch2,                                           Label* miss_label) {  // Check that the receiver isn't a smi.  __ test(receiver, Immediate(kSmiTagMask));  __ j(zero, miss_label, not_taken);  // Check that the maps haven't changed.  Register reg =      __ CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label);  // Push the arguments on the JS stack of the caller.  __ pop(scratch2);  // remove return address  __ push(receiver);  // receiver  __ push(reg);  // holder  __ push(name);  // name  __ push(scratch2);  // restore return address  // Do tail-call to the runtime system.  ExternalReference load_ic_property =      ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));  __ TailCallRuntime(load_ic_property, 3);}void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {  ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);  Code* code = NULL;  if (kind == Code::LOAD_IC) {    code = Builtins::builtin(Builtins::LoadIC_Miss);  } else {    code = Builtins::builtin(Builtins::KeyedLoadIC_Miss);  }  Handle<Code> ic(code);  __ jmp(ic, RelocInfo::CODE_TARGET);}void StubCompiler::GenerateStoreField(MacroAssembler* masm,                                      JSObject* object,                                      int index,                                      Map* transition,                                      Register receiver_reg,                                      Register name_reg,                                      Register scratch,                                      Label* miss_label) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -