info()->MarkAsContextSpecializing();
} else if (FLAG_turbo_type_feedback) {
info()->MarkAsTypeFeedbackEnabled();
+ info()->EnsureFeedbackVector();
}
Timer t(this, &time_taken_to_create_graph_);
void JSGenericLowering::LowerJSLoadNamed(Node* node) {
const LoadNamedParameters& p = LoadNamedParametersOf(node->op());
- Callable callable = CodeFactory::LoadICInOptimizedCode(
- isolate(), p.contextual_mode(), UNINITIALIZED);
+ Callable callable =
+ p.load_ic() == NAMED
+ ? CodeFactory::LoadICInOptimizedCode(isolate(), p.contextual_mode(),
+ UNINITIALIZED)
+ : CodeFactory::KeyedLoadICInOptimizedCode(isolate(), UNINITIALIZED);
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
if (FLAG_vector_ics) {
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
void JSGenericLowering::LowerJSStoreNamed(Node* node) {
const StoreNamedParameters& p = StoreNamedParametersOf(node->op());
- Callable callable = CodeFactory::StoreIC(isolate(), p.language_mode());
+ Callable callable = p.store_ic() == NAMED
+ ? CodeFactory::StoreIC(isolate(), p.language_mode())
+ : CodeFactory::KeyedStoreICInOptimizedCode(
+ isolate(), p.language_mode(), UNINITIALIZED);
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
}
const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name,
const VectorSlotPair& feedback,
- ContextualMode contextual_mode) {
- LoadNamedParameters parameters(name, feedback, contextual_mode);
+ ContextualMode contextual_mode,
+ PropertyICMode load_ic) {
+ LoadNamedParameters parameters(name, feedback, contextual_mode, load_ic);
return new (zone()) Operator1<LoadNamedParameters>( // --
IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode
"JSLoadNamed", // name
const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode,
- const Unique<Name>& name) {
- StoreNamedParameters parameters(language_mode, name);
+ const Unique<Name>& name,
+ PropertyICMode store_ic) {
+ StoreNamedParameters parameters(language_mode, name, store_ic);
return new (zone()) Operator1<StoreNamedParameters>( // --
IrOpcode::kJSStoreNamed, Operator::kNoProperties, // opcode
"JSStoreNamed", // name
bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs);
+// For (Load|Store)Named operators, the mode of the IC that needs
+// to be called. This is needed because (Load|Store)Property nodes can be
+// reduced to named versions, but still need to call the correct original
+// IC mode because of the layout of feedback vectors.
+enum PropertyICMode { NAMED, KEYED };
+
// Defines the property being loaded from an object by a named load. This is
// used as a parameter by JSLoadNamed operators.
class LoadNamedParameters final {
public:
LoadNamedParameters(const Unique<Name>& name, const VectorSlotPair& feedback,
- ContextualMode contextual_mode)
- : name_(name), contextual_mode_(contextual_mode), feedback_(feedback) {}
+ ContextualMode contextual_mode, PropertyICMode load_ic)
+ : name_(name),
+ feedback_(feedback),
+ contextual_mode_(contextual_mode),
+ load_ic_(load_ic) {}
const Unique<Name>& name() const { return name_; }
ContextualMode contextual_mode() const { return contextual_mode_; }
+ PropertyICMode load_ic() const { return load_ic_; }
const VectorSlotPair& feedback() const { return feedback_; }
private:
const Unique<Name> name_;
- const ContextualMode contextual_mode_;
const VectorSlotPair feedback_;
+ const ContextualMode contextual_mode_;
+ const PropertyICMode load_ic_;
};
bool operator==(LoadNamedParameters const&, LoadNamedParameters const&);
// used as a parameter by JSStoreNamed operators.
class StoreNamedParameters final {
public:
- StoreNamedParameters(LanguageMode language_mode, const Unique<Name>& name)
- : language_mode_(language_mode), name_(name) {}
+ StoreNamedParameters(LanguageMode language_mode, const Unique<Name>& name,
+ PropertyICMode store_ic)
+ : language_mode_(language_mode), name_(name), store_ic_(store_ic) {}
LanguageMode language_mode() const { return language_mode_; }
const Unique<Name>& name() const { return name_; }
+ PropertyICMode store_ic() const { return store_ic_; }
private:
const LanguageMode language_mode_;
const Unique<Name> name_;
+ const PropertyICMode store_ic_;
};
bool operator==(StoreNamedParameters const&, StoreNamedParameters const&);
const Operator* LoadProperty(const VectorSlotPair& feedback);
const Operator* LoadNamed(const Unique<Name>& name,
const VectorSlotPair& feedback,
- ContextualMode contextual_mode = NOT_CONTEXTUAL);
+ ContextualMode contextual_mode = NOT_CONTEXTUAL,
+ PropertyICMode load_ic = NAMED);
const Operator* StoreProperty(LanguageMode language_mode);
const Operator* StoreNamed(LanguageMode language_mode,
- const Unique<Name>& name);
+ const Unique<Name>& name,
+ PropertyICMode store_ic = NAMED);
const Operator* DeleteProperty(LanguageMode language_mode);
#include "src/compiler/common-operator.h"
#include "src/compiler/node-aux-data.h"
#include "src/compiler/node-matchers.h"
+#include "src/compiler/operator-properties.h"
#include "src/compiler/simplified-operator.h"
namespace v8 {
Unique<Name> name = match.Value();
const VectorSlotPair& feedback =
LoadPropertyParametersOf(node->op()).feedback();
- node->set_op(jsgraph()->javascript()->LoadNamed(name, feedback));
+ node->set_op(jsgraph()->javascript()->LoadNamed(name, feedback,
+ NOT_CONTEXTUAL, KEYED));
node->RemoveInput(1);
return ReduceJSLoadNamed(node);
}
// StoreProperty(o, "constant", v) => StoreNamed["constant"](o, v).
Unique<Name> name = match.Value();
LanguageMode language_mode = OpParameter<LanguageMode>(node);
- node->set_op(jsgraph()->javascript()->StoreNamed(language_mode, name));
+ if (FLAG_turbo_deoptimization) {
+ // StoreProperty has 2 frame state inputs, but StoreNamed only 1.
+ DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node->op()));
+ node->RemoveInput(NodeProperties::FirstFrameStateIndex(node) + 1);
+ }
+ node->set_op(
+ jsgraph()->javascript()->StoreNamed(language_mode, name, KEYED));
node->RemoveInput(1);
return ReduceJSStoreNamed(node);
}
--- /dev/null
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Foo(a, b) {
+ this.a = a;
+ this.b = b;
+ var bname = "b";
+ this.x = this["a"] + this[bname];
+}
+
+var f1 = new Foo(3, 4);
+assertEquals(7, f1.x);
+
+// SMIs
+for (var i = 0; i < 6; i++) {
+ var f = new Foo(i, i + 2);
+ assertEquals(i + i + 2, f.x);
+}
+
+// derbles
+for (var i = 0.25; i < 6.25; i++) {
+ var f = new Foo(i, i + 2);
+ assertEquals(i + i + 2, f.x);
+}
+
+// stirngs
+for (var i = 0; i < 6; i++) {
+ var f = new Foo(i + "", (i + 2) + "");
+ assertEquals((i + "") + ((i + 2) + ""), f.x);
+}
--- /dev/null
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Foo(a, b) {
+ var bname = "b";
+ this["a"] = a;
+ this[bname] = b;
+ this.x = this.a + this.b;
+}
+
+var f1 = new Foo(3, 4);
+assertEquals(7, f1.x);
+
+// SMIs
+for (var i = 0; i < 6; i++) {
+ var f = new Foo(i, i + 2);
+ assertEquals(i + i + 2, f.x);
+}
+
+// derbles
+for (var i = 0.25; i < 6.25; i++) {
+ var f = new Foo(i, i + 2);
+ assertEquals(i + i + 2, f.x);
+}
+
+// stirngs
+for (var i = 0; i < 6; i++) {
+ var f = new Foo(i + "", (i + 2) + "");
+ assertEquals((i + "") + ((i + 2) + ""), f.x);
+}