SmallMapList* GetReceiverTypes() OVERRIDE { return &receiver_types_; }
KeyedAccessStoreMode GetStoreMode() const OVERRIDE { return STANDARD_STORE; }
IcCheckType GetKeyType() const OVERRIDE {
- // PROPERTY key types currently aren't implemented for KeyedLoadICs.
- return ELEMENT;
+ return KeyTypeField::decode(bit_field_);
}
bool IsUninitialized() const {
return !is_for_call() && HasNoTypeInformation();
void set_is_string_access(bool b) {
bit_field_ = IsStringAccessField::update(bit_field_, b);
}
+ void set_key_type(IcCheckType key_type) {
+ bit_field_ = KeyTypeField::update(bit_field_, key_type);
+ }
void mark_for_call() {
bit_field_ = IsForCallField::update(bit_field_, true);
}
class IsForCallField : public BitField8<bool, 0, 1> {};
class IsUninitializedField : public BitField8<bool, 1, 1> {};
class IsStringAccessField : public BitField8<bool, 2, 1> {};
+ class KeyTypeField : public BitField8<IcCheckType, 3, 1> {};
uint8_t bit_field_;
FeedbackVectorICSlot property_feedback_slot_;
Expression* obj_;
bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone());
bool force_generic = false;
- if (access_type == STORE && expr->GetKeyType() == PROPERTY) {
+ if (expr->GetKeyType() == PROPERTY) {
// Non-Generic accesses assume that elements are being accessed, and will
// deopt for non-index keys, which the IC knows will occur.
// TODO(jkummerow): Consider adding proper support for property accesses.
KeyedStoreIC::IcCheckTypeField::update(extra_ic_state, PROPERTY);
DCHECK(STANDARD_STORE ==
KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state));
+ } else if (kind == Code::KEYED_LOAD_IC) {
+ extra_ic_state = KeyedLoadIC::IcCheckTypeField::update(extra_ic_state,
+ PROPERTY);
}
Handle<Code> ic;
Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic(
Handle<Map> receiver_map) {
Isolate* isolate = receiver_map->GetIsolate();
+ DCHECK(KeyedLoadIC::GetKeyType(kNoExtraICState) == ELEMENT);
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
Handle<Name> name = isolate->factory()->KeyedLoadMonomorphic_string();
Handle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic(
MapHandleList* receiver_maps) {
Isolate* isolate = receiver_maps->at(0)->GetIsolate();
+ DCHECK(KeyedLoadIC::GetKeyType(kNoExtraICState) == ELEMENT);
Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
Handle<PolymorphicCodeCache> cache =
isolate->factory()->polymorphic_code_cache();
class KeyedLoadIC : public LoadIC {
public:
+ // ExtraICState bits (building on IC)
+ class IcCheckTypeField : public BitField<IcCheckType, 1, 1> {};
+
+ static ExtraICState ComputeExtraICState(ContextualMode contextual_mode,
+ IcCheckType key_type) {
+ return LoadICState(contextual_mode).GetExtraICState() |
+ IcCheckTypeField::encode(key_type);
+ }
+
+ static IcCheckType GetKeyType(ExtraICState extra_state) {
+ return IcCheckTypeField::decode(extra_state);
+ }
+
KeyedLoadIC(FrameDepth depth, Isolate* isolate,
KeyedLoadICNexus* nexus = NULL)
: LoadIC(depth, isolate, nexus) {
}
+void TypeFeedbackOracle::GetLoadKeyType(
+ TypeFeedbackId ast_id, IcCheckType* key_type) {
+ Handle<Object> maybe_code = GetInfo(ast_id);
+ if (maybe_code->IsCode()) {
+ Handle<Code> code = Handle<Code>::cast(maybe_code);
+ if (code->kind() == Code::KEYED_LOAD_IC) {
+ ExtraICState extra_ic_state = code->extra_ic_state();
+ *key_type = KeyedLoadIC::GetKeyType(extra_ic_state);
+ return;
+ }
+ }
+ *key_type = ELEMENT;
+}
+
+
Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(
FeedbackVectorICSlot slot) {
Handle<Object> info = GetInfo(slot);
void TypeFeedbackOracle::KeyedPropertyReceiverTypes(
- TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string) {
+ TypeFeedbackId id,
+ SmallMapList* receiver_types,
+ bool* is_string,
+ IcCheckType* key_type) {
receiver_types->Clear();
CollectReceiverTypes(id, receiver_types);
*is_string = HasOnlyStringMaps(receiver_types);
+ GetLoadKeyType(id, key_type);
}
void GetStoreModeAndKeyType(TypeFeedbackId id,
KeyedAccessStoreMode* store_mode,
IcCheckType* key_type);
+ void GetLoadKeyType(TypeFeedbackId id, IcCheckType* key_type);
void PropertyReceiverTypes(TypeFeedbackId id, Handle<String> name,
SmallMapList* receiver_types);
SmallMapList* receiver_types);
void KeyedPropertyReceiverTypes(TypeFeedbackId id,
SmallMapList* receiver_types,
- bool* is_string);
+ bool* is_string,
+ IcCheckType* key_type);
void KeyedPropertyReceiverTypes(FeedbackVectorICSlot slot,
SmallMapList* receiver_types,
bool* is_string);
}
} else {
bool is_string;
+ IcCheckType key_type;
if (FLAG_vector_ics) {
oracle()->KeyedPropertyReceiverTypes(slot, expr->GetReceiverTypes(),
&is_string);
+ key_type = ELEMENT;
} else {
oracle()->KeyedPropertyReceiverTypes(id, expr->GetReceiverTypes(),
- &is_string);
+ &is_string, &key_type);
}
expr->set_is_string_access(is_string);
+ expr->set_key_type(key_type);
}
}
--- /dev/null
+// Copyright 2014 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.
+
+// Flags: --allow-natives-syntax
+
+
+var o = {
+ "foo": "bar",
+}
+
+function get(obj, key) {
+ return obj[key];
+}
+
+get(o, "foo");
+get(o, "foo");
+get(o, "foo");
+
+%OptimizeFunctionOnNextCall(get);
+get(o, "foo");
+
+assertOptimized(get);