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

📄 ic.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
      case INTERCEPTOR: {        code = StubCache::ComputeKeyedLoadInterceptor(*name, *receiver,                                                      lookup->holder());        break;      }      default: {        // Always rewrite to the generic case so that we do not        // repeatedly try to rewrite.        code = generic_stub();        break;      }    }  }  // If we're unable to compute the stub (not enough memory left), we  // simply avoid updating the caches.  if (code->IsFailure()) return;  // Patch the call site depending on the state of the cache.  Make  // sure to always rewrite from monomorphic to megamorphic.  ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);  if (state == UNINITIALIZED || state == PREMONOMORPHIC) {    set_target(Code::cast(code));  } else if (state == MONOMORPHIC) {    set_target(megamorphic_stub());  }#ifdef DEBUG  TraceIC("KeyedLoadIC", name, state, target());#endif}Object* StoreIC::Store(State state,                       Handle<Object> object,                       Handle<String> name,                       Handle<Object> value) {  // If the object is undefined or null it's illegal to try to set any  // properties on it; throw a TypeError in that case.  if (object->IsUndefined() || object->IsNull()) {    return TypeError("non_object_property_store", object, name);  }  // Ignore stores where the receiver is not a JSObject.  if (!object->IsJSObject()) return *value;  Handle<JSObject> receiver = Handle<JSObject>::cast(object);  // Check if the given name is an array index.  uint32_t index;  if (name->AsArrayIndex(&index)) {    HandleScope scope;    Handle<Object> result = SetElement(receiver, index, value);    if (result.is_null()) return Failure::Exception();    return *value;  }  // Lookup the property locally in the receiver.  LookupResult lookup;  receiver->LocalLookup(*name, &lookup);  // Update inline cache and stub cache.  if (FLAG_use_ic && lookup.IsLoaded()) {    UpdateCaches(&lookup, state, receiver, name, value);  }  // Set the property.  return receiver->SetProperty(*name, *value, NONE);}void StoreIC::UpdateCaches(LookupResult* lookup,                           State state,                           Handle<JSObject> receiver,                           Handle<String> name,                           Handle<Object> value) {  ASSERT(lookup->IsLoaded());  // Bail out if we didn't find a result.  if (!lookup->IsValid() || !lookup->IsCacheable()) return;  // If the property is read-only, we leave the IC in its current  // state.  if (lookup->IsReadOnly()) return;  // If the property has a non-field type allowing map transitions  // where there is extra room in the object, we leave the IC in its  // current state.  PropertyType type = lookup->type();  // Compute the code stub for this store; used for rewriting to  // monomorphic state and making sure that the code stub is in the  // stub cache.  Object* code = NULL;  switch (type) {    case FIELD: {      code = StubCache::ComputeStoreField(*name, *receiver,                                          lookup->GetFieldIndex());      break;    }    case MAP_TRANSITION: {      if (lookup->GetAttributes() != NONE) return;      if (receiver->map()->unused_property_fields() == 0) return;      HandleScope scope;      ASSERT(type == MAP_TRANSITION &&             (receiver->map()->unused_property_fields() > 0));      Handle<Map> transition(lookup->GetTransitionMap());      int index = transition->PropertyIndexFor(*name);      code = StubCache::ComputeStoreField(*name, *receiver, index, *transition);      break;    }    case CALLBACKS: {      if (!lookup->GetCallbackObject()->IsAccessorInfo()) return;      AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject());      if (v8::ToCData<Address>(callback->setter()) == 0) return;      code = StubCache::ComputeStoreCallback(*name, *receiver, callback);      break;    }    case INTERCEPTOR: {      code = StubCache::ComputeStoreInterceptor(*name, *receiver);      break;    }    default:      return;  }  // If we're unable to compute the stub (not enough memory left), we  // simply avoid updating the caches.  if (code->IsFailure()) return;  // Patch the call site depending on the state of the cache.  if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) {    set_target(Code::cast(code));  } else if (state == MONOMORPHIC) {    set_target(megamorphic_stub());  }#ifdef DEBUG  TraceIC("StoreIC", name, state, target());#endif}Object* KeyedStoreIC::Store(State state,                            Handle<Object> object,                            Handle<Object> key,                            Handle<Object> value) {  if (key->IsSymbol()) {    Handle<String> name = Handle<String>::cast(key);    // If the object is undefined or null it's illegal to try to set any    // properties on it; throw a TypeError in that case.    if (object->IsUndefined() || object->IsNull()) {      return TypeError("non_object_property_store", object, name);    }    // Ignore stores where the receiver is not a JSObject.    if (!object->IsJSObject()) return *value;    Handle<JSObject> receiver = Handle<JSObject>::cast(object);    // Check if the given name is an array index.    uint32_t index;    if (name->AsArrayIndex(&index)) {      HandleScope scope;      Handle<Object> result = SetElement(receiver, index, value);      if (result.is_null()) return Failure::Exception();      return *value;    }    // Lookup the property locally in the receiver.    LookupResult lookup;    receiver->LocalLookup(*name, &lookup);    // Update inline cache and stub cache.    if (FLAG_use_ic && lookup.IsLoaded()) {      UpdateCaches(&lookup, state, receiver, name, value);    }    // Set the property.    return receiver->SetProperty(*name, *value, NONE);  }  // Do not use ICs for objects that require access checks (including  // the global object).  bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();  if (use_ic) set_target(generic_stub());  // Set the property.  return Runtime::SetObjectProperty(object, key, value, NONE);}void KeyedStoreIC::UpdateCaches(LookupResult* lookup,                                State state,                                Handle<JSObject> receiver,                                Handle<String> name,                                Handle<Object> value) {  ASSERT(lookup->IsLoaded());  // Bail out if we didn't find a result.  if (!lookup->IsValid() || !lookup->IsCacheable()) return;  // If the property is read-only, we leave the IC in its current  // state.  if (lookup->IsReadOnly()) return;  // If the property has a non-field type allowing map transitions  // where there is extra room in the object, we leave the IC in its  // current state.  PropertyType type = lookup->type();  // Compute the code stub for this store; used for rewriting to  // monomorphic state and making sure that the code stub is in the  // stub cache.  Object* code = NULL;  switch (type) {    case FIELD: {      code = StubCache::ComputeKeyedStoreField(*name, *receiver,                                               lookup->GetFieldIndex());      break;    }    case MAP_TRANSITION: {      if (lookup->GetAttributes() == NONE) {        if (receiver->map()->unused_property_fields() == 0) return;        HandleScope scope;        ASSERT(type == MAP_TRANSITION &&               (receiver->map()->unused_property_fields() > 0));        Handle<Map> transition(lookup->GetTransitionMap());        int index = transition->PropertyIndexFor(*name);        code = StubCache::ComputeKeyedStoreField(*name, *receiver,                                                 index, *transition);        break;      }      // fall through.    }    default: {      // Always rewrite to the generic case so that we do not      // repeatedly try to rewrite.      code = generic_stub();      break;    }  }  // If we're unable to compute the stub (not enough memory left), we  // simply avoid updating the caches.  if (code->IsFailure()) return;  // Patch the call site depending on the state of the cache.  Make  // sure to always rewrite from monomorphic to megamorphic.  ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);  if (state == UNINITIALIZED || state == PREMONOMORPHIC) {    set_target(Code::cast(code));  } else if (state == MONOMORPHIC) {    set_target(megamorphic_stub());  }#ifdef DEBUG  TraceIC("KeyedStoreIC", name, state, target());#endif}// ----------------------------------------------------------------------------// Static IC stub generators.//// Used from ic_<arch>.cc.Object* CallIC_Miss(Arguments args) {  NoHandleAllocation na;  ASSERT(args.length() == 2);  CallIC ic;  IC::State state = IC::StateFrom(ic.target(), args[0]);  return ic.LoadFunction(state, args.at<Object>(0), args.at<String>(1));}void CallIC::GenerateInitialize(MacroAssembler* masm, int argc) {  Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss)));}void CallIC::GeneratePreMonomorphic(MacroAssembler* masm, int argc) {  Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss)));}void CallIC::GenerateMiss(MacroAssembler* masm, int argc) {  Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss)));}// Used from ic_<arch>.cc.Object* LoadIC_Miss(Arguments args) {  NoHandleAllocation na;  ASSERT(args.length() == 2);  LoadIC ic;  IC::State state = IC::StateFrom(ic.target(), args[0]);  return ic.Load(state, args.at<Object>(0), args.at<String>(1));}void LoadIC::GenerateInitialize(MacroAssembler* masm) {  Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));}void LoadIC::GeneratePreMonomorphic(MacroAssembler* masm) {  Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));}// Used from ic_<arch>.ccObject* KeyedLoadIC_Miss(Arguments args) {  NoHandleAllocation na;  ASSERT(args.length() == 2);  KeyedLoadIC ic;  IC::State state = IC::StateFrom(ic.target(), args[0]);  return ic.Load(state, args.at<Object>(0), args.at<Object>(1));}void KeyedLoadIC::GenerateInitialize(MacroAssembler* masm) {  Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss)));}void KeyedLoadIC::GeneratePreMonomorphic(MacroAssembler* masm) {  Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss)));}// Used from ic_<arch>.cc.Object* StoreIC_Miss(Arguments args) {  NoHandleAllocation na;  ASSERT(args.length() == 3);  StoreIC ic;  IC::State state = IC::StateFrom(ic.target(), args[0]);  return ic.Store(state, args.at<Object>(0), args.at<String>(1),                  args.at<Object>(2));}void StoreIC::GenerateInitialize(MacroAssembler* masm) {  Generate(masm, ExternalReference(IC_Utility(kStoreIC_Miss)));}void StoreIC::GenerateMiss(MacroAssembler* masm) {  Generate(masm, ExternalReference(IC_Utility(kStoreIC_Miss)));}// Used from ic_<arch>.cc.Object* KeyedStoreIC_Miss(Arguments args) {  NoHandleAllocation na;  ASSERT(args.length() == 3);  KeyedStoreIC ic;  IC::State state = IC::StateFrom(ic.target(), args[0]);  return ic.Store(state, args.at<Object>(0), args.at<Object>(1),                  args.at<Object>(2));}void KeyedStoreIC::GenerateInitialize(MacroAssembler* masm) {  Generate(masm, ExternalReference(IC_Utility(kKeyedStoreIC_Miss)));}void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {  Generate(masm, ExternalReference(IC_Utility(kKeyedStoreIC_Miss)));}static Address IC_utilities[] = {#define ADDR(name) FUNCTION_ADDR(name),    IC_UTIL_LIST(ADDR)    NULL#undef ADDR};Address IC::AddressFromUtilityId(IC::UtilityId id) {  return IC_utilities[id];}} }  // namespace v8::internal

⌨️ 快捷键说明

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