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

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

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
  // Check that the object isn't a smi.  __ test(receiver_reg, Immediate(kSmiTagMask));  __ j(zero, miss_label, not_taken);  // Check that the map of the object hasn't changed.  __ cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset),         Immediate(Handle<Map>(object->map())));  __ j(not_equal, miss_label, not_taken);  // Perform global security token check if needed.  if (object->IsJSGlobalObject()) {    __ CheckAccessGlobal(receiver_reg, scratch, miss_label);  }  // Stub never generated for non-global objects that require access  // checks.  ASSERT(object->IsJSGlobalObject() || !object->IsAccessCheckNeeded());  // Get the properties array (optimistically).  __ mov(scratch, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));  // Perform map transition for the receiver if necessary.  if (transition != NULL) {    // Update the map of the object; no write barrier updating is    // needed because the map is never in new space.    __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset),           Immediate(Handle<Map>(transition)));  }  // Write to the properties array.  int offset = index * kPointerSize + Array::kHeaderSize;  __ mov(FieldOperand(scratch, offset), eax);  // Update the write barrier for the array address.  // Pass the value being stored in the now unused name_reg.  __ mov(name_reg, Operand(eax));  __ RecordWrite(scratch, offset, name_reg, receiver_reg);  // Return the value (register eax).  __ ret(0);}#undef __#define __ masm()->// TODO(1241006): Avoid having lazy compile stubs specialized by the// number of arguments. It is not needed anymore.Object* StubCompiler::CompileLazyCompile(Code::Flags flags) {  HandleScope scope;  // Enter an internal frame.  __ EnterInternalFrame();  // Push a copy of the function onto the stack.  __ push(edi);  __ push(edi);  // function is also the parameter to the runtime call  __ CallRuntime(Runtime::kLazyCompile, 1);  __ pop(edi);  __ LeaveInternalFrame();  // Do a tail-call of the compiled function.  __ lea(ecx, FieldOperand(eax, Code::kHeaderSize));  __ jmp(Operand(ecx));  return GetCodeWithFlags(flags);}Object* CallStubCompiler::CompileCallField(Object* object,                                           JSObject* holder,                                           int index) {  // ----------- S t a t e -------------  // -----------------------------------  HandleScope scope;  Label miss;  // Get the receiver from the stack.  const int argc = arguments().immediate();  __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));  // Check that the receiver isn't a smi.  __ test(edx, Immediate(kSmiTagMask));  __ j(zero, &miss, not_taken);  // Do the right check and compute the holder register.  Register reg =      __ CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss);  // Get the properties array of the holder and get the function from the field.  int offset = index * kPointerSize + Array::kHeaderSize;  __ mov(edi, FieldOperand(reg, JSObject::kPropertiesOffset));  __ mov(edi, FieldOperand(edi, offset));  // Check that the function really is a function.  __ test(edi, Immediate(kSmiTagMask));  __ j(zero, &miss, not_taken);  __ mov(ebx, FieldOperand(edi, HeapObject::kMapOffset));  // get the map  __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));  __ cmp(ebx, JS_FUNCTION_TYPE);  __ j(not_equal, &miss, not_taken);  // Invoke the function.  __ InvokeFunction(edi, arguments(), JUMP_FUNCTION);  // Handle call cache miss.  __ bind(&miss);  Handle<Code> ic = ComputeCallMiss(arguments().immediate());  __ jmp(ic, RelocInfo::CODE_TARGET);  // Return the generated code.  return GetCode(FIELD);}Object* CallStubCompiler::CompileCallConstant(Object* object,                                              JSObject* holder,                                              JSFunction* function,                                              CheckType check) {  // ----------- S t a t e -------------  // -----------------------------------  HandleScope scope;  Label miss;  // Get the receiver from the stack.  const int argc = arguments().immediate();  __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));  // Check that the receiver isn't a smi.  if (check != NUMBER_CHECK) {    __ test(edx, Immediate(kSmiTagMask));    __ j(zero, &miss, not_taken);  }  switch (check) {    case RECEIVER_MAP_CHECK:      // Check that the maps haven't changed.      __ CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss);      break;    case STRING_CHECK:      // Check that the object is a two-byte string or a symbol.      __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));      __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));      __ cmp(ecx, FIRST_NONSTRING_TYPE);      __ j(above_equal, &miss, not_taken);      // Check that the maps starting from the prototype haven't changed.      GenerateLoadGlobalFunctionPrototype(masm(),                                          Context::STRING_FUNCTION_INDEX,                                          ecx);      __ CheckMaps(JSObject::cast(object->GetPrototype()),                   ecx, holder, ebx, edx, &miss);      break;    case NUMBER_CHECK: {      Label fast;      // Check that the object is a smi or a heap number.      __ test(edx, Immediate(kSmiTagMask));      __ j(zero, &fast, taken);      __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));      __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));      __ cmp(ecx, HEAP_NUMBER_TYPE);      __ j(not_equal, &miss, not_taken);      __ bind(&fast);      // Check that the maps starting from the prototype haven't changed.      GenerateLoadGlobalFunctionPrototype(masm(),                                          Context::NUMBER_FUNCTION_INDEX,                                          ecx);      __ CheckMaps(JSObject::cast(object->GetPrototype()),                   ecx, holder, ebx, edx, &miss);      break;    }    case BOOLEAN_CHECK: {      Label fast;      // Check that the object is a boolean.      __ cmp(edx, Factory::true_value());      __ j(equal, &fast, taken);      __ cmp(edx, Factory::false_value());      __ j(not_equal, &miss, not_taken);      __ bind(&fast);      // Check that the maps starting from the prototype haven't changed.      GenerateLoadGlobalFunctionPrototype(masm(),                                          Context::BOOLEAN_FUNCTION_INDEX,                                          ecx);      __ CheckMaps(JSObject::cast(object->GetPrototype()),                   ecx, holder, ebx, edx, &miss);      break;    }    case JSARRAY_HAS_FAST_ELEMENTS_CHECK:      __ CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss);      // Make sure object->elements()->map() != Heap::dictionary_array_map()      // Get the elements array of the object.      __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));      // Check that the object is in fast mode (not dictionary).      __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),             Immediate(Factory::hash_table_map()));      __ j(equal, &miss, not_taken);      break;    default:      UNREACHABLE();  }  // Get the function and setup the context.  __ mov(Operand(edi), Immediate(Handle<JSFunction>(function)));  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));  // Jump to the cached code (tail call).  Handle<Code> code(function->code());  ParameterCount expected(function->shared()->formal_parameter_count());  __ InvokeCode(code, expected, arguments(),                RelocInfo::CODE_TARGET, JUMP_FUNCTION);  // Handle call cache miss.  __ bind(&miss);  Handle<Code> ic = ComputeCallMiss(arguments().immediate());  __ jmp(ic, RelocInfo::CODE_TARGET);  // Return the generated code.  return GetCode(CONSTANT_FUNCTION);}Object* CallStubCompiler::CompileCallInterceptor(Object* object,                                                 JSObject* holder,                                                 String* name) {  // ----------- S t a t e -------------  // -----------------------------------  HandleScope scope;  Label miss;  // Get the number of arguments.  const int argc = arguments().immediate();  // Get the receiver from the stack.  __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));  // Check that the receiver isn't a smi.  __ test(edx, Immediate(kSmiTagMask));  __ j(zero, &miss, not_taken);  // Check that maps have not changed and compute the holder register.  Register reg =      __ CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss);  // Enter an internal frame.  __ EnterInternalFrame();  // Push arguments on the expression stack.  __ push(edx);  // receiver  __ push(reg);  // holder  __ push(Operand(ebp, (argc + 3) * kPointerSize));  // name  // Perform call.  ExternalReference load_interceptor =      ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));  __ mov(Operand(eax), Immediate(3));  __ mov(Operand(ebx), Immediate(load_interceptor));  CEntryStub stub;  __ CallStub(&stub);  // Move result to edi and restore receiver.  __ mov(Operand(edi), eax);  __ mov(edx, Operand(ebp, (argc + 2) * kPointerSize));  // receiver  // Exit frame.  __ LeaveInternalFrame();  // Check that the function really is a function.  __ test(edi, Immediate(kSmiTagMask));  __ j(zero, &miss, not_taken);  __ mov(ebx, FieldOperand(edi, HeapObject::kMapOffset));  __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));  __ cmp(ebx, JS_FUNCTION_TYPE);  __ j(not_equal, &miss, not_taken);  // Invoke the function.  __ InvokeFunction(edi, arguments(), JUMP_FUNCTION);  // Handle load cache miss.  __ bind(&miss);  Handle<Code> ic = ComputeCallMiss(argc);  __ jmp(ic, RelocInfo::CODE_TARGET);  // Return the generated code.  return GetCode(INTERCEPTOR);}Object* StoreStubCompiler::CompileStoreField(JSObject* object,                                             int index,                                             Map* transition,                                             String* name) {  // ----------- S t a t e -------------  //  -- eax    : value  //  -- ecx    : name  //  -- esp[0] : return address  //  -- esp[4] : receiver  // -----------------------------------  HandleScope scope;  Label miss;  // Get the object from the stack.  __ mov(ebx, Operand(esp, 1 * kPointerSize));  // Generate store field code.  Trashes the name register.  GenerateStoreField(masm(), object, index, transition, ebx, ecx, edx, &miss);  // Handle store cache miss.  __ bind(&miss);  __ mov(Operand(ecx), Immediate(Handle<String>(name)));  // restore name  Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss));  __ jmp(ic, RelocInfo::CODE_TARGET);  // Return the generated code.  return GetCode(transition == NULL ? FIELD : MAP_TRANSITION);}Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,                                                AccessorInfo* callback,                                                String* name) {  // ----------- S t a t e -------------  //  -- eax    : value  //  -- ecx    : name  //  -- esp[0] : return address  //  -- esp[4] : receiver  // -----------------------------------  HandleScope scope;  Label miss;  // Get the object from the stack.  __ mov(ebx, Operand(esp, 1 * kPointerSize));  // Check that the object isn't a smi.  __ test(ebx, Immediate(kSmiTagMask));  __ j(zero, &miss, not_taken);  // Check that the map of the object hasn't changed.  __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),         Immediate(Handle<Map>(object->map())));  __ j(not_equal, &miss, not_taken);  // Perform global security token check if needed.  if (object->IsJSGlobalObject()) {    __ CheckAccessGlobal(ebx, edx, &miss);  }  // Stub never generated for non-global objects that require access  // checks.  ASSERT(object->IsJSGlobalObject() || !object->IsAccessCheckNeeded());  __ pop(ebx);  // remove the return address  __ push(Operand(esp, 0));  // receiver  __ push(Immediate(Handle<AccessorInfo>(callback)));  // callback info  __ push(ecx);  // name  __ push(eax);  // value  __ push(ebx);  // restore return address  // Do tail-call to the runtime system.  ExternalReference store_callback_property =      ExternalReference(IC_Utility(IC::kStoreCallbackProperty));  __ TailCallRuntime(store_callback_property, 4);  // Handle store cache miss.  __ bind(&miss);  __ mov(Operand(ecx), Immediate(Handle<String>(name)));  // restore name  Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss));  __ jmp(ic, RelocInfo::CODE_TARGET);  // Return the generated code.  return GetCode(CALLBACKS);}Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,                                                   String* name) {  // ----------- S t a t e -------------  //  -- eax    : value  //  -- ecx    : name  //  -- esp[0] : return address  //  -- esp[4] : receiver  // -----------------------------------  HandleScope scope;  Label miss;  // Get the object from the stack.  __ mov(ebx, Operand(esp, 1 * kPointerSize));  // Check that the object isn't a smi.  __ test(ebx, Immediate(kSmiTagMask));  __ j(zero, &miss, not_taken);  // Check that the map of the object hasn't changed.  __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),         Immediate(Handle<Map>(receiver->map())));  __ j(not_equal, &miss, not_taken);  // Perform global security token check if needed.  if (receiver->IsJSGlobalObject()) {    __ CheckAccessGlobal(ebx, edx, &miss);  }

⌨️ 快捷键说明

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