void Map::set_dictionary_map(bool value) {
+ if (value) mark_unstable();
set_bit_field3(DictionaryMap::update(bit_field3(), value));
}
}
+void Map::mark_unstable() {
+ set_bit_field3(IsUnstable::update(bit_field3(), true));
+}
+
+
+bool Map::is_stable() {
+ return !IsUnstable::decode(bit_field3());
+}
+
+
bool Map::has_code_cache() {
return code_cache() != GetIsolate()->heap()->empty_fixed_array();
}
void Map::NotifyLeafMapLayoutChange() {
- dependent_code()->DeoptimizeDependentCodeGroup(
- GetIsolate(),
- DependentCode::kPrototypeCheckGroup);
+ if (is_stable()) {
+ mark_unstable();
+ dependent_code()->DeoptimizeDependentCodeGroup(
+ GetIsolate(),
+ DependentCode::kPrototypeCheckGroup);
+ }
}
bool Map::CanOmitPrototypeChecks() {
- return !HasTransitionArray() && !is_dictionary_map() &&
- FLAG_omit_prototype_checks_for_leaf_maps;
+ return is_stable() && FLAG_omit_prototype_checks_for_leaf_maps;
}
bool Map::CanOmitMapChecks() {
- return !HasTransitionArray() && !is_dictionary_map() &&
- FLAG_omit_map_checks_for_leaf_maps;
+ return is_stable() && FLAG_omit_map_checks_for_leaf_maps;
}
deprecate();
dependent_code()->DeoptimizeDependentCodeGroup(
GetIsolate(), DependentCode::kTransitionGroup);
- dependent_code()->DeoptimizeDependentCodeGroup(
- GetIsolate(), DependentCode::kPrototypeCheckGroup);
+ NotifyLeafMapLayoutChange();
}
new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0);
new_bit_field3 = EnumLengthBits::update(new_bit_field3, kInvalidEnumCache);
new_bit_field3 = Deprecated::update(new_bit_field3, false);
+ new_bit_field3 = IsUnstable::update(new_bit_field3, false);
result->set_bit_field3(new_bit_field3);
return result;
}
class IsObserved: public BitField<bool, 26, 1> {};
class Deprecated: public BitField<bool, 27, 1> {};
class IsFrozen: public BitField<bool, 28, 1> {};
+ class IsUnstable: public BitField<bool, 29, 1> {};
// Tells whether the object in the prototype property will be used
// for instances created from this function. If the prototype
inline void set_is_observed(bool is_observed);
inline void freeze();
inline bool is_frozen();
+ inline void mark_unstable();
+ inline bool is_stable();
inline void deprecate();
inline bool is_deprecated();
inline bool CanBeDeprecated();
--- /dev/null
+// Copyright 2013 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 a = {x:1};
+var a_deprecate = {x:1};
+a_deprecate.x = 1.5;
+function create() {
+ return {__proto__:a, y:1};
+}
+var b1 = create();
+var b2 = create();
+var b3 = create();
+var b4 = create();
+
+function set(b) {
+ b.x = 5;
+ b.z = 10;
+}
+
+set(b1);
+set(b2);
+%OptimizeFunctionOnNextCall(set);
+set(b3);
+var called = false;
+a.x = 1.5;
+Object.defineProperty(a, "z", {set:function(v) { called = true; }});
+set(b4);
+assertTrue(called);
+assertEquals(undefined, b4.z);