diff options
Diffstat (limited to 'deps/v8/src/ic.cc')
-rw-r--r-- | deps/v8/src/ic.cc | 119 |
1 files changed, 109 insertions, 10 deletions
diff --git a/deps/v8/src/ic.cc b/deps/v8/src/ic.cc index 78fb29753c..40676abc3d 100644 --- a/deps/v8/src/ic.cc +++ b/deps/v8/src/ic.cc @@ -347,6 +347,7 @@ void IC::Clear(Address address) { case Code::CALL_IC: return CallIC::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_NIL_IC: return CompareNilIC::Clear(address, target); case Code::UNARY_OP_IC: case Code::BINARY_OP_IC: case Code::TO_BOOLEAN_IC: @@ -877,7 +878,7 @@ MaybeObject* LoadIC::Load(State state, if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); #endif } - return Accessors::FunctionGetPrototype(*object, 0); + return *Accessors::FunctionGetPrototype(object); } } @@ -887,7 +888,7 @@ MaybeObject* LoadIC::Load(State state, if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { // Rewrite to the generic keyed load stub. if (FLAG_use_ic) set_target(*generic_stub()); - return Runtime::GetElementOrCharAt(isolate(), object, index); + return Runtime::GetElementOrCharAtOrFail(isolate(), object, index); } // Named lookup in the object. @@ -922,7 +923,7 @@ MaybeObject* LoadIC::Load(State state, } // Get the property. - return object->GetProperty(*object, &lookup, *name, &attr); + return Object::GetPropertyOrFail(object, object, &lookup, name, &attr); } @@ -1260,7 +1261,7 @@ static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) { // non-smi keys of keyed loads/stores to a smi or a string. if (key->IsHeapNumber()) { double value = Handle<HeapNumber>::cast(key)->value(); - if (isnan(value)) { + if (std::isnan(value)) { key = isolate->factory()->nan_string(); } else { int int_value = FastD2I(value); @@ -1476,8 +1477,8 @@ MaybeObject* StoreIC::Store(State state, JSReceiver::StoreFromKeyed store_mode) { // Handle proxies. if (object->IsJSProxy()) { - return JSProxy::cast(*object)-> - SetProperty(*name, *value, NONE, strict_mode); + return JSReceiver::SetPropertyOrFail( + Handle<JSReceiver>::cast(object), name, value, NONE, strict_mode); } // If the object is undefined or null it's illegal to try to set any @@ -1509,7 +1510,8 @@ MaybeObject* StoreIC::Store(State state, // Observed objects are always modified through the runtime. if (FLAG_harmony_observation && receiver->map()->is_observed()) { - return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); + return JSReceiver::SetPropertyOrFail( + receiver, name, value, NONE, strict_mode, store_mode); } // Use specialized code for setting the length of arrays with fast @@ -1524,7 +1526,8 @@ MaybeObject* StoreIC::Store(State state, StoreArrayLengthStub(kind(), strict_mode).GetCode(isolate()); set_target(*stub); TRACE_IC("StoreIC", name, state, *stub); - return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); + return JSReceiver::SetPropertyOrFail( + receiver, name, value, NONE, strict_mode, store_mode); } if (receiver->IsJSGlobalProxy()) { @@ -1537,7 +1540,8 @@ MaybeObject* StoreIC::Store(State state, set_target(*stub); TRACE_IC("StoreIC", name, state, *stub); } - return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); + return JSReceiver::SetPropertyOrFail( + receiver, name, value, NONE, strict_mode, store_mode); } LookupResult lookup(isolate()); @@ -1553,7 +1557,8 @@ MaybeObject* StoreIC::Store(State state, } // Set the property. - return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); + return JSReceiver::SetPropertyOrFail( + receiver, name, value, NONE, strict_mode, store_mode); } @@ -2766,6 +2771,100 @@ RUNTIME_FUNCTION(Code*, CompareIC_Miss) { } +Code* CompareNilIC::GetRawUninitialized(EqualityKind kind, + NilValue nil) { + CompareNilICStub stub(kind, nil); + Code* code = NULL; + CHECK(stub.FindCodeInCache(&code, Isolate::Current())); + return code; +} + + +void CompareNilIC::Clear(Address address, Code* target) { + if (target->ic_state() == UNINITIALIZED) return; + Code::ExtraICState state = target->extended_extra_ic_state(); + + EqualityKind kind = + CompareNilICStub::EqualityKindFromExtraICState(state); + NilValue nil = + CompareNilICStub::NilValueFromExtraICState(state); + + SetTargetAtAddress(address, GetRawUninitialized(kind, nil)); +} + + +MaybeObject* CompareNilIC::DoCompareNilSlow(EqualityKind kind, + NilValue nil, + Handle<Object> object) { + if (kind == kStrictEquality) { + if (nil == kNullValue) { + return Smi::FromInt(object->IsNull()); + } else { + return Smi::FromInt(object->IsUndefined()); + } + } + if (object->IsNull() || object->IsUndefined()) { + return Smi::FromInt(true); + } + return Smi::FromInt(object->IsUndetectableObject()); +} + + +MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { + Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); + + // Extract the current supported types from the patched IC and calculate what + // types must be supported as a result of the miss. + bool already_monomorphic; + CompareNilICStub::Types types = + CompareNilICStub::GetPatchedICFlags(extra_ic_state, + object, &already_monomorphic); + + EqualityKind kind = + CompareNilICStub::EqualityKindFromExtraICState(extra_ic_state); + NilValue nil = + CompareNilICStub::NilValueFromExtraICState(extra_ic_state); + + // Find or create the specialized stub to support the new set of types. + CompareNilICStub stub(kind, nil, types); + Handle<Code> code; + if ((types & CompareNilICStub::kCompareAgainstMonomorphicMap) != 0) { + Handle<Map> monomorphic_map(already_monomorphic + ? target()->FindFirstMap() + : HeapObject::cast(*object)->map()); + code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, + nil, + stub.GetTypes()); + } else { + code = stub.GetCode(isolate()); + } + + patch(*code); + + return DoCompareNilSlow(kind, nil, object); +} + + +void CompareNilIC::patch(Code* code) { + set_target(code); +} + + +RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss) { + HandleScope scope(isolate); + Handle<Object> object = args.at<Object>(0); + CompareNilIC ic(isolate); + return ic.CompareNil(object); +} + + +RUNTIME_FUNCTION(MaybeObject*, Unreachable) { + UNREACHABLE(); + CHECK(false); + return isolate->heap()->undefined_value(); +} + + RUNTIME_FUNCTION(MaybeObject*, ToBoolean_Patch) { ASSERT(args.length() == 3); |