Merge Store from Keyed and Named store.
Review URL: https://chromiumcodereview.appspot.com/12036017 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13461 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
3ffcbe3319
commit
2c070e2300
213
src/ic.cc
213
src/ic.cc
@ -351,11 +351,9 @@ void IC::Clear(Address address) {
|
|||||||
|
|
||||||
switch (target->kind()) {
|
switch (target->kind()) {
|
||||||
case Code::LOAD_IC: return LoadIC::Clear(address, target);
|
case Code::LOAD_IC: return LoadIC::Clear(address, target);
|
||||||
case Code::KEYED_LOAD_IC:
|
case Code::KEYED_LOAD_IC: return KeyedLoadIC::Clear(address, target);
|
||||||
return KeyedLoadIC::Clear(address, target);
|
|
||||||
case Code::STORE_IC: return StoreIC::Clear(address, target);
|
case Code::STORE_IC: return StoreIC::Clear(address, target);
|
||||||
case Code::KEYED_STORE_IC:
|
case Code::KEYED_STORE_IC: return KeyedStoreIC::Clear(address, target);
|
||||||
return KeyedStoreIC::Clear(address, target);
|
|
||||||
case Code::CALL_IC: return CallIC::Clear(address, target);
|
case Code::CALL_IC: return CallIC::Clear(address, target);
|
||||||
case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target);
|
case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target);
|
||||||
case Code::COMPARE_IC: return CompareIC::Clear(address, target);
|
case Code::COMPARE_IC: return CompareIC::Clear(address, target);
|
||||||
@ -387,13 +385,13 @@ void KeyedLoadIC::Clear(Address address, Code* target) {
|
|||||||
// Make sure to also clear the map used in inline fast cases. If we
|
// Make sure to also clear the map used in inline fast cases. If we
|
||||||
// do not clear these maps, cached code can keep objects alive
|
// do not clear these maps, cached code can keep objects alive
|
||||||
// through the embedded maps.
|
// through the embedded maps.
|
||||||
SetTargetAtAddress(address, initialize_stub());
|
SetTargetAtAddress(address, *initialize_stub());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LoadIC::Clear(Address address, Code* target) {
|
void LoadIC::Clear(Address address, Code* target) {
|
||||||
if (target->ic_state() == UNINITIALIZED) return;
|
if (target->ic_state() == UNINITIALIZED) return;
|
||||||
SetTargetAtAddress(address, initialize_stub());
|
SetTargetAtAddress(address, *initialize_stub());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -401,8 +399,8 @@ void StoreIC::Clear(Address address, Code* target) {
|
|||||||
if (target->ic_state() == UNINITIALIZED) return;
|
if (target->ic_state() == UNINITIALIZED) return;
|
||||||
SetTargetAtAddress(address,
|
SetTargetAtAddress(address,
|
||||||
(Code::GetStrictMode(target->extra_ic_state()) == kStrictMode)
|
(Code::GetStrictMode(target->extra_ic_state()) == kStrictMode)
|
||||||
? initialize_stub_strict()
|
? *initialize_stub_strict()
|
||||||
: initialize_stub());
|
: *initialize_stub());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -410,8 +408,8 @@ void KeyedStoreIC::Clear(Address address, Code* target) {
|
|||||||
if (target->ic_state() == UNINITIALIZED) return;
|
if (target->ic_state() == UNINITIALIZED) return;
|
||||||
SetTargetAtAddress(address,
|
SetTargetAtAddress(address,
|
||||||
(Code::GetStrictMode(target->extra_ic_state()) == kStrictMode)
|
(Code::GetStrictMode(target->extra_ic_state()) == kStrictMode)
|
||||||
? initialize_stub_strict()
|
? *initialize_stub_strict()
|
||||||
: initialize_stub());
|
: *initialize_stub());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1313,34 +1311,34 @@ static bool LookupForWrite(Handle<JSObject> receiver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MaybeObject* StoreIC::Store(State state,
|
MaybeObject* IC::Store(State state,
|
||||||
StrictModeFlag strict_mode,
|
StrictModeFlag strict_mode,
|
||||||
Handle<Object> object,
|
Handle<Object> object,
|
||||||
Handle<String> name,
|
Handle<String> name,
|
||||||
Handle<Object> value) {
|
Handle<Object> value,
|
||||||
if (!object->IsJSObject()) {
|
JSReceiver::StoreFromKeyed store_mode) {
|
||||||
// Handle proxies.
|
// Handle proxies.
|
||||||
if (object->IsJSProxy()) {
|
if (object->IsJSProxy()) {
|
||||||
return JSProxy::cast(*object)->
|
return JSProxy::cast(*object)->
|
||||||
SetProperty(*name, *value, NONE, strict_mode);
|
SetProperty(*name, *value, NONE, strict_mode);
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The length property of string values is read-only. Throw in strict mode.
|
|
||||||
if (strict_mode == kStrictMode && object->IsString() &&
|
|
||||||
name->Equals(isolate()->heap()->length_symbol())) {
|
|
||||||
return TypeError("strict_read_only_property", object, name);
|
|
||||||
}
|
|
||||||
// Ignore other stores where the receiver is not a JSObject.
|
|
||||||
// TODO(1475): Must check prototype chains of object wrappers.
|
|
||||||
return *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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The length property of string values is read-only. Throw in strict mode.
|
||||||
|
if (strict_mode == kStrictMode && object->IsString() &&
|
||||||
|
name->Equals(isolate()->heap()->length_symbol())) {
|
||||||
|
return TypeError("strict_read_only_property", object, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore other stores where the receiver is not a JSObject.
|
||||||
|
// TODO(1475): Must check prototype chains of object wrappers.
|
||||||
|
if (!object->IsJSObject()) return *value;
|
||||||
|
|
||||||
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
||||||
|
|
||||||
// Check if the given name is an array index.
|
// Check if the given name is an array index.
|
||||||
@ -1354,75 +1352,63 @@ MaybeObject* StoreIC::Store(State state,
|
|||||||
|
|
||||||
// Observed objects are always modified through the runtime.
|
// Observed objects are always modified through the runtime.
|
||||||
if (FLAG_harmony_observation && receiver->map()->is_observed()) {
|
if (FLAG_harmony_observation && receiver->map()->is_observed()) {
|
||||||
return receiver->SetProperty(*name, *value, NONE, strict_mode);
|
return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use specialized code for setting the length of arrays with fast
|
// Use specialized code for setting the length of arrays with fast
|
||||||
// properties. Slow properties might indicate redefinition of the
|
// properties. Slow properties might indicate redefinition of the length
|
||||||
// length property.
|
// property.
|
||||||
if (receiver->IsJSArray() &&
|
if (FLAG_use_ic &&
|
||||||
|
receiver->IsJSArray() &&
|
||||||
name->Equals(isolate()->heap()->length_symbol()) &&
|
name->Equals(isolate()->heap()->length_symbol()) &&
|
||||||
Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
|
Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
|
||||||
receiver->HasFastProperties()) {
|
receiver->HasFastProperties() &&
|
||||||
#ifdef DEBUG
|
kind() != Code::KEYED_STORE_IC) {
|
||||||
if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
|
|
||||||
#endif
|
|
||||||
Handle<Code> stub = (strict_mode == kStrictMode)
|
Handle<Code> stub = (strict_mode == kStrictMode)
|
||||||
? isolate()->builtins()->StoreIC_ArrayLength_Strict()
|
? isolate()->builtins()->StoreIC_ArrayLength_Strict()
|
||||||
: isolate()->builtins()->StoreIC_ArrayLength();
|
: isolate()->builtins()->StoreIC_ArrayLength();
|
||||||
set_target(*stub);
|
set_target(*stub);
|
||||||
return receiver->SetProperty(*name, *value, NONE, strict_mode);
|
TRACE_IC("StoreIC", name, state, *stub);
|
||||||
}
|
return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
|
||||||
|
|
||||||
// Lookup the property locally in the receiver.
|
|
||||||
if (!receiver->IsJSGlobalProxy()) {
|
|
||||||
LookupResult lookup(isolate());
|
|
||||||
|
|
||||||
if (LookupForWrite(receiver, name, &lookup)) {
|
|
||||||
if (FLAG_use_ic) { // Generate a stub for this store.
|
|
||||||
UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Strict mode doesn't allow setting non-existent global property
|
|
||||||
// or an assignment to a read only property.
|
|
||||||
if (strict_mode == kStrictMode) {
|
|
||||||
if (lookup.IsProperty() && lookup.IsReadOnly()) {
|
|
||||||
return TypeError("strict_read_only_property", object, name);
|
|
||||||
} else if (IsContextual(object)) {
|
|
||||||
return ReferenceError("not_defined", name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (receiver->IsJSGlobalProxy()) {
|
if (receiver->IsJSGlobalProxy()) {
|
||||||
// TODO(ulan): find out why we patch this site even with --no-use-ic
|
if (FLAG_use_ic && kind() != Code::KEYED_STORE_IC) {
|
||||||
// Generate a generic stub that goes to the runtime when we see a global
|
// Generate a generic stub that goes to the runtime when we see a global
|
||||||
// proxy as receiver.
|
// proxy as receiver.
|
||||||
Handle<Code> stub = (strict_mode == kStrictMode)
|
Handle<Code> stub = (strict_mode == kStrictMode)
|
||||||
? global_proxy_stub_strict()
|
? global_proxy_stub_strict()
|
||||||
: global_proxy_stub();
|
: global_proxy_stub();
|
||||||
if (target() != *stub) {
|
|
||||||
set_target(*stub);
|
set_target(*stub);
|
||||||
TRACE_IC("StoreIC", name, state, target());
|
TRACE_IC("StoreIC", name, state, *stub);
|
||||||
}
|
}
|
||||||
|
return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
LookupResult lookup(isolate());
|
||||||
|
if (LookupForWrite(receiver, name, &lookup)) {
|
||||||
|
if (FLAG_use_ic) {
|
||||||
|
UpdateStoreCaches(&lookup, state, strict_mode, receiver, name, value);
|
||||||
|
}
|
||||||
|
} else if (strict_mode == kStrictMode &&
|
||||||
|
!lookup.IsFound() &&
|
||||||
|
IsContextual(object)) {
|
||||||
|
// Strict mode doesn't allow setting non-existent global property
|
||||||
|
// or an assignment to a read only property.
|
||||||
|
return ReferenceError("not_defined", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the property.
|
// Set the property.
|
||||||
return receiver->SetProperty(*name,
|
return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
|
||||||
*value,
|
|
||||||
NONE,
|
|
||||||
strict_mode,
|
|
||||||
JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void StoreIC::UpdateCaches(LookupResult* lookup,
|
void StoreIC::UpdateStoreCaches(LookupResult* lookup,
|
||||||
State state,
|
State state,
|
||||||
StrictModeFlag strict_mode,
|
StrictModeFlag strict_mode,
|
||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<String> name,
|
Handle<String> name,
|
||||||
Handle<Object> value) {
|
Handle<Object> value) {
|
||||||
ASSERT(!receiver->IsJSGlobalProxy());
|
ASSERT(!receiver->IsJSGlobalProxy());
|
||||||
ASSERT(StoreICableLookup(lookup));
|
ASSERT(StoreICableLookup(lookup));
|
||||||
ASSERT(lookup->IsFound());
|
ASSERT(lookup->IsFound());
|
||||||
@ -1531,7 +1517,7 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
|
|||||||
}
|
}
|
||||||
isolate()->stub_cache()->Set(*name, receiver->map(), *code);
|
isolate()->stub_cache()->Set(*name, receiver->map(), *code);
|
||||||
set_target((strict_mode == kStrictMode)
|
set_target((strict_mode == kStrictMode)
|
||||||
? megamorphic_stub_strict()
|
? *megamorphic_stub_strict()
|
||||||
: *megamorphic_stub());
|
: *megamorphic_stub());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1891,43 +1877,12 @@ MaybeObject* KeyedStoreIC::Store(State state,
|
|||||||
|
|
||||||
if (key->IsSymbol()) {
|
if (key->IsSymbol()) {
|
||||||
Handle<String> name = Handle<String>::cast(key);
|
Handle<String> name = Handle<String>::cast(key);
|
||||||
|
return IC::Store(state,
|
||||||
// Handle proxies.
|
strict_mode,
|
||||||
if (object->IsJSProxy()) {
|
object,
|
||||||
return JSProxy::cast(*object)->SetProperty(
|
name,
|
||||||
*name, *value, NONE, strict_mode);
|
value,
|
||||||
}
|
JSReceiver::MAY_BE_STORE_FROM_KEYED);
|
||||||
|
|
||||||
// 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)) {
|
|
||||||
Handle<Object> result =
|
|
||||||
JSObject::SetElement(receiver, index, value, NONE, strict_mode);
|
|
||||||
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
|
||||||
return *value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update inline cache and stub cache.
|
|
||||||
if (FLAG_use_ic && !receiver->IsJSGlobalProxy() &&
|
|
||||||
!(FLAG_harmony_observation && receiver->map()->is_observed())) {
|
|
||||||
LookupResult lookup(isolate());
|
|
||||||
if (LookupForWrite(receiver, name, &lookup)) {
|
|
||||||
UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the property.
|
|
||||||
return receiver->SetProperty(*name, *value, NONE, strict_mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not use ICs for objects that require access checks (including
|
// Do not use ICs for objects that require access checks (including
|
||||||
@ -1966,12 +1921,12 @@ MaybeObject* KeyedStoreIC::Store(State state,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
|
void KeyedStoreIC::UpdateStoreCaches(LookupResult* lookup,
|
||||||
State state,
|
State state,
|
||||||
StrictModeFlag strict_mode,
|
StrictModeFlag strict_mode,
|
||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<String> name,
|
Handle<String> name,
|
||||||
Handle<Object> value) {
|
Handle<Object> value) {
|
||||||
ASSERT(!receiver->IsJSGlobalProxy());
|
ASSERT(!receiver->IsJSGlobalProxy());
|
||||||
ASSERT(StoreICableLookup(lookup));
|
ASSERT(StoreICableLookup(lookup));
|
||||||
ASSERT(lookup->IsFound());
|
ASSERT(lookup->IsFound());
|
||||||
|
130
src/ic.h
130
src/ic.h
@ -136,6 +136,15 @@ class IC {
|
|||||||
Handle<Object> object,
|
Handle<Object> object,
|
||||||
Handle<String> name);
|
Handle<String> name);
|
||||||
|
|
||||||
|
MUST_USE_RESULT MaybeObject* Store(
|
||||||
|
State state,
|
||||||
|
StrictModeFlag strict_mode,
|
||||||
|
Handle<Object> object,
|
||||||
|
Handle<String> name,
|
||||||
|
Handle<Object> value,
|
||||||
|
JSReceiver::StoreFromKeyed store_mode =
|
||||||
|
JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Handle<Code> pre_monomorphic_stub() {
|
virtual Handle<Code> pre_monomorphic_stub() {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -145,6 +154,10 @@ class IC {
|
|||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return Handle<Code>::null();
|
return Handle<Code>::null();
|
||||||
}
|
}
|
||||||
|
virtual Handle<Code> megamorphic_stub_strict() {
|
||||||
|
UNREACHABLE();
|
||||||
|
return Handle<Code>::null();
|
||||||
|
}
|
||||||
virtual Handle<Code> generic_stub() const {
|
virtual Handle<Code> generic_stub() const {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return Handle<Code>::null();
|
return Handle<Code>::null();
|
||||||
@ -153,12 +166,29 @@ class IC {
|
|||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return Code::STUB;
|
return Code::STUB;
|
||||||
}
|
}
|
||||||
|
virtual Handle<Code> global_proxy_stub() {
|
||||||
|
UNREACHABLE();
|
||||||
|
return Handle<Code>::null();
|
||||||
|
}
|
||||||
|
virtual Handle<Code> global_proxy_stub_strict() {
|
||||||
|
UNREACHABLE();
|
||||||
|
return Handle<Code>::null();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void UpdateLoadCaches(LookupResult* lookup,
|
virtual void UpdateLoadCaches(LookupResult* lookup,
|
||||||
State state,
|
State state,
|
||||||
Handle<Object> object,
|
Handle<Object> object,
|
||||||
Handle<String> name) {
|
Handle<String> name) {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
virtual void UpdateStoreCaches(LookupResult* lookup,
|
||||||
|
State state,
|
||||||
|
StrictModeFlag strict_mode,
|
||||||
|
Handle<JSObject> receiver,
|
||||||
|
Handle<String> name,
|
||||||
|
Handle<Object> value) {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
Address fp() const { return fp_; }
|
Address fp() const { return fp_; }
|
||||||
Address pc() const { return *pc_address_; }
|
Address pc() const { return *pc_address_; }
|
||||||
Isolate* isolate() const { return isolate_; }
|
Isolate* isolate() const { return isolate_; }
|
||||||
@ -378,9 +408,8 @@ class LoadIC: public IC {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Stub accessors.
|
// Stub accessors.
|
||||||
static Code* initialize_stub() {
|
static Handle<Code> initialize_stub() {
|
||||||
return Isolate::Current()->builtins()->builtin(
|
return Isolate::Current()->builtins()->LoadIC_Initialize();
|
||||||
Builtins::kLoadIC_Initialize);
|
|
||||||
}
|
}
|
||||||
virtual Handle<Code> pre_monomorphic_stub() {
|
virtual Handle<Code> pre_monomorphic_stub() {
|
||||||
return isolate()->builtins()->LoadIC_PreMonomorphic();
|
return isolate()->builtins()->LoadIC_PreMonomorphic();
|
||||||
@ -565,9 +594,8 @@ class KeyedLoadIC: public KeyedIC {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Stub accessors.
|
// Stub accessors.
|
||||||
static Code* initialize_stub() {
|
static Handle<Code> initialize_stub() {
|
||||||
return Isolate::Current()->builtins()->builtin(
|
return Isolate::Current()->builtins()->KeyedLoadIC_Initialize();
|
||||||
Builtins::kKeyedLoadIC_Initialize);
|
|
||||||
}
|
}
|
||||||
virtual Handle<Code> pre_monomorphic_stub() {
|
virtual Handle<Code> pre_monomorphic_stub() {
|
||||||
return isolate()->builtins()->KeyedLoadIC_PreMonomorphic();
|
return isolate()->builtins()->KeyedLoadIC_PreMonomorphic();
|
||||||
@ -591,12 +619,6 @@ class StoreIC: public IC {
|
|||||||
ASSERT(target()->is_store_stub());
|
ASSERT(target()->is_store_stub());
|
||||||
}
|
}
|
||||||
|
|
||||||
MUST_USE_RESULT MaybeObject* Store(State state,
|
|
||||||
StrictModeFlag strict_mode,
|
|
||||||
Handle<Object> object,
|
|
||||||
Handle<String> name,
|
|
||||||
Handle<Object> value);
|
|
||||||
|
|
||||||
// Code generators for stub routines. Only called once at startup.
|
// Code generators for stub routines. Only called once at startup.
|
||||||
static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
|
static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
|
||||||
static void GenerateMiss(MacroAssembler* masm);
|
static void GenerateMiss(MacroAssembler* masm);
|
||||||
@ -612,17 +634,28 @@ class StoreIC: public IC {
|
|||||||
virtual Handle<Code> megamorphic_stub() {
|
virtual Handle<Code> megamorphic_stub() {
|
||||||
return isolate()->builtins()->StoreIC_Megamorphic();
|
return isolate()->builtins()->StoreIC_Megamorphic();
|
||||||
}
|
}
|
||||||
|
// Stub accessors.
|
||||||
|
virtual Handle<Code> megamorphic_stub_strict() {
|
||||||
|
return isolate()->builtins()->StoreIC_Megamorphic_Strict();
|
||||||
|
}
|
||||||
|
virtual Handle<Code> global_proxy_stub() {
|
||||||
|
return isolate()->builtins()->StoreIC_GlobalProxy();
|
||||||
|
}
|
||||||
|
virtual Handle<Code> global_proxy_stub_strict() {
|
||||||
|
return isolate()->builtins()->StoreIC_GlobalProxy_Strict();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Update the inline cache and the global stub cache based on the
|
// Update the inline cache and the global stub cache based on the
|
||||||
// lookup result.
|
// lookup result.
|
||||||
void UpdateCaches(LookupResult* lookup,
|
virtual void UpdateStoreCaches(LookupResult* lookup,
|
||||||
State state,
|
State state,
|
||||||
StrictModeFlag strict_mode,
|
StrictModeFlag strict_mode,
|
||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<String> name,
|
Handle<String> name,
|
||||||
Handle<Object> value);
|
Handle<Object> value);
|
||||||
|
|
||||||
|
private:
|
||||||
void set_target(Code* code) {
|
void set_target(Code* code) {
|
||||||
// Strict mode must be preserved across IC patching.
|
// Strict mode must be preserved across IC patching.
|
||||||
ASSERT(Code::GetStrictMode(code->extra_ic_state()) ==
|
ASSERT(Code::GetStrictMode(code->extra_ic_state()) ==
|
||||||
@ -630,26 +663,12 @@ class StoreIC: public IC {
|
|||||||
IC::set_target(code);
|
IC::set_target(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stub accessors.
|
static Handle<Code> initialize_stub() {
|
||||||
Code* megamorphic_stub_strict() {
|
return Isolate::Current()->builtins()->StoreIC_Initialize();
|
||||||
return isolate()->builtins()->builtin(
|
|
||||||
Builtins::kStoreIC_Megamorphic_Strict);
|
|
||||||
}
|
}
|
||||||
static Code* initialize_stub() {
|
static Handle<Code> initialize_stub_strict() {
|
||||||
return Isolate::Current()->builtins()->builtin(
|
return Isolate::Current()->builtins()->StoreIC_Initialize_Strict();
|
||||||
Builtins::kStoreIC_Initialize);
|
|
||||||
}
|
}
|
||||||
static Code* initialize_stub_strict() {
|
|
||||||
return Isolate::Current()->builtins()->builtin(
|
|
||||||
Builtins::kStoreIC_Initialize_Strict);
|
|
||||||
}
|
|
||||||
Handle<Code> global_proxy_stub() {
|
|
||||||
return isolate()->builtins()->StoreIC_GlobalProxy();
|
|
||||||
}
|
|
||||||
Handle<Code> global_proxy_stub_strict() {
|
|
||||||
return isolate()->builtins()->StoreIC_GlobalProxy_Strict();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Clear(Address address, Code* target);
|
static void Clear(Address address, Code* target);
|
||||||
|
|
||||||
friend class IC;
|
friend class IC;
|
||||||
@ -706,15 +725,22 @@ class KeyedStoreIC: public KeyedIC {
|
|||||||
StrictModeFlag strict_mode,
|
StrictModeFlag strict_mode,
|
||||||
KeyedAccessGrowMode grow_mode);
|
KeyedAccessGrowMode grow_mode);
|
||||||
|
|
||||||
private:
|
|
||||||
// Update the inline cache.
|
// Update the inline cache.
|
||||||
void UpdateCaches(LookupResult* lookup,
|
virtual void UpdateStoreCaches(LookupResult* lookup,
|
||||||
State state,
|
State state,
|
||||||
StrictModeFlag strict_mode,
|
StrictModeFlag strict_mode,
|
||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<String> name,
|
Handle<String> name,
|
||||||
Handle<Object> value);
|
Handle<Object> value);
|
||||||
|
|
||||||
|
virtual Handle<Code> megamorphic_stub() {
|
||||||
|
return isolate()->builtins()->KeyedStoreIC_Generic();
|
||||||
|
}
|
||||||
|
virtual Handle<Code> megamorphic_stub_strict() {
|
||||||
|
return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
void set_target(Code* code) {
|
void set_target(Code* code) {
|
||||||
// Strict mode must be preserved across IC patching.
|
// Strict mode must be preserved across IC patching.
|
||||||
ASSERT(Code::GetStrictMode(code->extra_ic_state()) ==
|
ASSERT(Code::GetStrictMode(code->extra_ic_state()) ==
|
||||||
@ -723,19 +749,11 @@ class KeyedStoreIC: public KeyedIC {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stub accessors.
|
// Stub accessors.
|
||||||
static Code* initialize_stub() {
|
static Handle<Code> initialize_stub() {
|
||||||
return Isolate::Current()->builtins()->builtin(
|
return Isolate::Current()->builtins()->KeyedStoreIC_Initialize();
|
||||||
Builtins::kKeyedStoreIC_Initialize);
|
|
||||||
}
|
}
|
||||||
static Code* initialize_stub_strict() {
|
static Handle<Code> initialize_stub_strict() {
|
||||||
return Isolate::Current()->builtins()->builtin(
|
return Isolate::Current()->builtins()->KeyedStoreIC_Initialize_Strict();
|
||||||
Builtins::kKeyedStoreIC_Initialize_Strict);
|
|
||||||
}
|
|
||||||
Handle<Code> megamorphic_stub() {
|
|
||||||
return isolate()->builtins()->KeyedStoreIC_Generic();
|
|
||||||
}
|
|
||||||
Handle<Code> megamorphic_stub_strict() {
|
|
||||||
return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
|
|
||||||
}
|
}
|
||||||
Handle<Code> generic_stub() const {
|
Handle<Code> generic_stub() const {
|
||||||
return isolate()->builtins()->KeyedStoreIC_Generic();
|
return isolate()->builtins()->KeyedStoreIC_Generic();
|
||||||
|
Loading…
Reference in New Issue
Block a user