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

📄 ic-arm.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
// 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 "codegen-inl.h"#include "ic-inl.h"#include "runtime.h"#include "stub-cache.h"namespace v8 { namespace internal {// ----------------------------------------------------------------------------// Static IC stub generators.//#define __ masm->// Helper function used from LoadIC/CallIC GenerateNormal.static void GenerateDictionaryLoad(MacroAssembler* masm,                                   Label* done_label,                                   Label* miss_label,                                   Register t0,                                   Register t1) {  // Register use:  //  // t0 - used to hold the property dictionary.  //  // t1 - initially the receiver  //    - used for the index into the property dictionary  //    - holds the result on exit.  //  // r3 - used as temporary and to hold the capacity of the property  //      dictionary.  //  // r2 - holds the name of the property and is unchanges.  // Check for the absence of an interceptor.  // Load the map into t0.  __ ldr(t0, FieldMemOperand(t1, JSObject::kMapOffset));  // Test the has_named_interceptor bit in the map.  __ ldr(t0, FieldMemOperand(t1, Map::kInstanceAttributesOffset));  __ tst(t0, Operand(1 << (Map::kHasNamedInterceptor + (3 * 8))));  // Jump to miss if the interceptor bit is set.  __ b(ne, miss_label);  // Check that the properties array is a dictionary.  __ ldr(t0, FieldMemOperand(t1, JSObject::kPropertiesOffset));  __ ldr(r3, FieldMemOperand(t0, HeapObject::kMapOffset));  __ cmp(r3, Operand(Factory::hash_table_map()));  __ b(ne, miss_label);  // Compute the capacity mask.  const int kCapacityOffset =      Array::kHeaderSize + Dictionary::kCapacityIndex * kPointerSize;  __ ldr(r3, FieldMemOperand(t0, kCapacityOffset));  __ mov(r3, Operand(r3, ASR, kSmiTagSize));  // convert smi to int  __ sub(r3, r3, Operand(1));  const int kElementsStartOffset =      Array::kHeaderSize + Dictionary::kElementsStartIndex * kPointerSize;  // Generate an unrolled loop that performs a few probes before  // giving up. Measurements done on Gmail indicate that 2 probes  // cover ~93% of loads from dictionaries.  static const int kProbes = 4;  for (int i = 0; i < kProbes; i++) {    // Compute the masked index: (hash + i + i * i) & mask.    __ ldr(t1, FieldMemOperand(r2, String::kLengthOffset));    if (i > 0) __ add(t1, t1, Operand(Dictionary::GetProbeOffset(i)));    __ and_(t1, t1, Operand(r3));    // Scale the index by multiplying by the element size.    ASSERT(Dictionary::kElementSize == 3);    __ add(t1, t1, Operand(t1, LSL, 1));  // t1 = t1 * 3    // Check if the key is identical to the name.    __ add(t1, t0, Operand(t1, LSL, 2));    __ ldr(ip, FieldMemOperand(t1, kElementsStartOffset));    __ cmp(r2, Operand(ip));    if (i != kProbes - 1) {      __ b(eq, done_label);    } else {      __ b(ne, miss_label);    }  }  // Check that the value is a normal property.  __ bind(done_label);  // t1 == t0 + 4*index  __ ldr(r3, FieldMemOperand(t1, kElementsStartOffset + 2 * kPointerSize));  __ tst(r3, Operand(PropertyDetails::TypeField::mask() << kSmiTagSize));  __ b(ne, miss_label);  // Get the value at the masked, scaled index and return.  __ ldr(t1, FieldMemOperand(t1, kElementsStartOffset + 1 * kPointerSize));}void LoadIC::GenerateArrayLength(MacroAssembler* masm) {  // ----------- S t a t e -------------  //  -- r2    : name  //  -- lr    : return address  //  -- [sp]  : receiver  // -----------------------------------  Label miss;  __ ldr(r0, MemOperand(sp, 0));  // Check that the receiver isn't a smi.  __ tst(r0, Operand(kSmiTagMask));  __ b(eq, &miss);  // Check that the object is a JS array.  __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));  __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset));  __ cmp(r1, Operand(JS_ARRAY_TYPE));  __ b(ne, &miss);  // Load length directly from the JS array.  __ ldr(r0, FieldMemOperand(r0, JSArray::kLengthOffset));  __ Ret();  // Cache miss: Jump to runtime.  __ bind(&miss);  Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Miss));  __ Jump(ic, RelocInfo::CODE_TARGET);}void LoadIC::GenerateShortStringLength(MacroAssembler* masm) {  // ----------- S t a t e -------------  //  -- r2    : name  //  -- lr    : return address  //  -- [sp]  : receiver  // -----------------------------------  Label miss;  __ ldr(r0, MemOperand(sp, 0));  // Check that the receiver isn't a smi.  __ tst(r0, Operand(kSmiTagMask));  __ b(eq, &miss);  // Check that the object is a short string.  __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));  __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset));  __ and_(r1, r1, Operand(kIsNotStringMask | kStringSizeMask));  // The cast is to resolve the overload for the argument of 0x0.  __ cmp(r1, Operand(static_cast<int32_t>(kStringTag | kShortStringTag)));  __ b(ne, &miss);  // Load length directly from the string.  __ ldr(r0, FieldMemOperand(r0, String::kLengthOffset));  __ mov(r0, Operand(r0, LSR, String::kShortLengthShift));  __ mov(r0, Operand(r0, LSL, kSmiTagSize));  __ Ret();  // Cache miss: Jump to runtime.  __ bind(&miss);  Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Miss));  __ Jump(ic, RelocInfo::CODE_TARGET);}void LoadIC::GenerateMediumStringLength(MacroAssembler* masm) {  // ----------- S t a t e -------------  //  -- r2    : name  //  -- lr    : return address  //  -- [sp]  : receiver  // -----------------------------------  Label miss;  __ ldr(r0, MemOperand(sp, 0));  // Check that the receiver isn't a smi.  __ tst(r0, Operand(kSmiTagMask));  __ b(eq, &miss);  // Check that the object is a medium string.  __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));  __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset));  __ and_(r1, r1, Operand(kIsNotStringMask | kStringSizeMask));  __ cmp(r1, Operand(kStringTag | kMediumStringTag));  __ b(ne, &miss);  // Load length directly from the string.  __ ldr(r0, FieldMemOperand(r0, String::kLengthOffset));  __ mov(r0, Operand(r0, LSR, String::kMediumLengthShift));  __ mov(r0, Operand(r0, LSL, kSmiTagSize));  __ Ret();  // Cache miss: Jump to runtime.  __ bind(&miss);  Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Miss));  __ Jump(ic, RelocInfo::CODE_TARGET);}void LoadIC::GenerateLongStringLength(MacroAssembler* masm) {  // ----------- S t a t e -------------  //  -- r2    : name  //  -- lr    : return address  //  -- [sp]  : receiver  // -----------------------------------  Label miss;  __ ldr(r0, MemOperand(sp, 0));  // Check that the receiver isn't a smi.  __ tst(r0, Operand(kSmiTagMask));  __ b(eq, &miss);  // Check that the object is a long string.  __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));  __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset));  __ and_(r1, r1, Operand(kIsNotStringMask | kStringSizeMask));  __ cmp(r1, Operand(kStringTag | kLongStringTag));  __ b(ne, &miss);  // Load length directly from the string.  __ ldr(r0, FieldMemOperand(r0, String::kLengthOffset));  __ mov(r0, Operand(r0, LSR, String::kLongLengthShift));  __ mov(r0, Operand(r0, LSL, kSmiTagSize));  __ Ret();  // Cache miss: Jump to runtime.  __ bind(&miss);  Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Miss));  __ Jump(ic, RelocInfo::CODE_TARGET);}void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {  // ----------- S t a t e -------------  //  -- r2    : name  //  -- lr    : return address  //  -- [sp]  : receiver  // -----------------------------------  // NOTE: Right now, this code always misses on ARM which is  // sub-optimal. We should port the fast case code from IA-32.  Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Miss));  __ Jump(ic, RelocInfo::CODE_TARGET);}// Defined in ic.cc.Object* CallIC_Miss(Arguments args);void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {  // ----------- S t a t e -------------  //  -- lr: return address  // -----------------------------------  Label number, non_number, non_string, boolean, probe, miss;  // Get the receiver of the function from the stack into r1.  __ ldr(r1, MemOperand(sp, argc * kPointerSize));  // Get the name of the function from the stack; 1 ~ receiver.  __ ldr(r2, MemOperand(sp, (argc + 1) * kPointerSize));  // Probe the stub cache.

⌨️ 快捷键说明

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