Revision: 13039
Author: [email protected]
Date: Fri Nov 23 02:53:03 2012
Log: Revert r13025 and r13026 (they introduced a bug on arm and
regressed octane crypto).
BUG=
Review URL: https://chromiumcodereview.appspot.com/11316151
http://code.google.com/p/v8/source/detail?r=13039
Modified:
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ic.cc
/branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/test/mjsunit/array-length.js
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Thu Nov 22
06:59:52 2012
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri Nov 23
02:53:03 2012
@@ -4942,12 +4942,11 @@
SmallMapList* map_set = instr->hydrogen()->map_set();
for (int i = 0; i < map_set->length() - 1; i++) {
Handle<Map> map = map_set->at(i);
- __ CompareMap(reg, scratch, map, &success, instr->hydrogen()->mode());
+ __ CompareMap(reg, scratch, map, &success, REQUIRE_EXACT_MAP);
__ b(eq, &success);
}
Handle<Map> map = map_set->last();
- DoCheckMapCommon(reg, scratch, map, instr->hydrogen()->mode(),
- instr->environment());
+ DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP,
instr->environment());
__ bind(&success);
}
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Wed Nov 21 03:49:15
2012
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Fri Nov 23 02:53:03
2012
@@ -2201,8 +2201,7 @@
class HCheckMaps: public HTemplateInstruction<2> {
public:
HCheckMaps(HValue* value, Handle<Map> map, Zone* zone,
- HValue* typecheck = NULL,
- CompareMapMode mode = REQUIRE_EXACT_MAP) : mode_(mode) {
+ HValue* typecheck = NULL) {
SetOperandAt(0, value);
// If callers don't depend on a typecheck, they can pass in NULL. In
that
// case we use a copy of the |value| argument as a dummy value.
@@ -2213,8 +2212,7 @@
SetGVNFlag(kDependsOnElementsKind);
map_set()->Add(map, zone);
}
- HCheckMaps(HValue* value, SmallMapList* maps, Zone* zone,
- CompareMapMode mode = REQUIRE_EXACT_MAP) : mode_(mode) {
+ HCheckMaps(HValue* value, SmallMapList* maps, Zone* zone) {
SetOperandAt(0, value);
SetOperandAt(1, value);
set_representation(Representation::Tagged());
@@ -2259,7 +2257,6 @@
HValue* value() { return OperandAt(0); }
SmallMapList* map_set() { return &map_set_; }
- CompareMapMode mode() { return mode_; }
DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
@@ -2276,7 +2273,6 @@
private:
SmallMapList map_set_;
- CompareMapMode mode_;
};
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Thu Nov 22 02:25:22 2012
+++ /branches/bleeding_edge/src/hydrogen.cc Fri Nov 23 02:53:03 2012
@@ -6591,8 +6591,6 @@
HInstruction* instr = NULL;
if (expr->AsProperty()->IsArrayLength()) {
- // Note that in the monomorphic case IsArrayLength() is false because
we
- // handle that it with a regular property load IC.
HValue* array = Pop();
AddInstruction(new(zone()) HCheckNonSmi(array));
HInstruction* mapcheck =
@@ -6628,74 +6626,23 @@
map = types->first();
if (map->is_dictionary_map()) monomorphic = false;
}
-
- // Try to see if this is an array length access.
- if (name->Equals(isolate()->heap()->length_symbol())) {
- bool is_array = false;
- bool fast_mode = false;
- bool map_mode = false;
- HInstruction* mapcheck = NULL;
-
- if (expr->IsMonomorphic()) {
- // Even if there is more than one map they all must be element
- // transition maps, so checking just one is ok.
- if (map->instance_type() == JS_ARRAY_TYPE) {
- is_array = true;
- map_mode = true;
- fast_mode = IsFastElementsKind(map->elements_kind());
- }
+ if (monomorphic) {
+ Handle<JSFunction> getter;
+ Handle<JSObject> holder;
+ if (LookupGetter(map, name, &getter, &holder)) {
+ AddCheckConstantFunction(holder, Top(), map);
+ if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return;
+ AddInstruction(new(zone()) HPushArgument(Pop()));
+ instr = new(zone()) HCallConstantFunction(getter, 1);
} else {
- // Since we will emit an instance check we have to conservatively
- // assume that some arrays will contain slow elements, so we set
- // fast_mode to false.
- map_mode = false;
- fast_mode = false;
- is_array = true;
- for (int i = 0; i < types->length(); i++) {
- Handle<Map> current_map = types->at(i);
- if (current_map->instance_type() != JS_ARRAY_TYPE) {
- is_array = false;
- break;
- }
- }
+ instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map);
}
-
- // It is an array length access so we produce a HJSArrayLength.
- if (is_array) {
- HValue* array = Pop();
- AddInstruction(new(zone()) HCheckNonSmi(array));
- mapcheck = map_mode ?
- HInstruction::cast(
- new(zone()) HCheckMaps(array, map, zone(), NULL,
- ALLOW_ELEMENT_TRANSITION_MAPS)) :
- HInstruction::cast(
- HCheckInstanceType::NewIsJSArray(array, zone()));
- AddInstruction(mapcheck);
- instr = new(zone()) HJSArrayLength(
- array, mapcheck, fast_mode ? HType::Smi() : HType::Tagged());
- }
+ } else if (types != NULL && types->length() > 1) {
+ return HandlePolymorphicLoadNamedField(expr, Pop(), types, name);
+ } else {
+ instr = BuildLoadNamedGeneric(Pop(), name, expr);
}
- // We cannot know if it was an array length access so we handle it as
- // a regular property access.
- if (instr == NULL) {
- if (monomorphic) {
- Handle<JSFunction> getter;
- Handle<JSObject> holder;
- if (LookupGetter(map, name, &getter, &holder)) {
- AddCheckConstantFunction(holder, Top(), map);
- if (FLAG_inline_accessors && TryInlineGetter(getter, expr))
return;
- AddInstruction(new(zone()) HPushArgument(Pop()));
- instr = new(zone()) HCallConstantFunction(getter, 1);
- } else {
- instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map);
- }
- } else if (types != NULL && types->length() > 1) {
- return HandlePolymorphicLoadNamedField(expr, Pop(), types, name);
- } else {
- instr = BuildLoadNamedGeneric(Pop(), name, expr);
- }
- }
} else {
CHECK_ALIVE(VisitForValue(expr->key()));
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Nov 21
03:49:15 2012
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri Nov 23
02:53:03 2012
@@ -4770,11 +4770,11 @@
SmallMapList* map_set = instr->hydrogen()->map_set();
for (int i = 0; i < map_set->length() - 1; i++) {
Handle<Map> map = map_set->at(i);
- __ CompareMap(reg, map, &success, instr->hydrogen()->mode());
+ __ CompareMap(reg, map, &success, REQUIRE_EXACT_MAP);
__ j(equal, &success);
}
Handle<Map> map = map_set->last();
- DoCheckMapCommon(reg, map, instr->hydrogen()->mode(),
instr->environment());
+ DoCheckMapCommon(reg, map, REQUIRE_EXACT_MAP, instr->environment());
__ bind(&success);
}
=======================================
--- /branches/bleeding_edge/src/ic.cc Wed Nov 21 23:58:59 2012
+++ /branches/bleeding_edge/src/ic.cc Fri Nov 23 02:53:03 2012
@@ -854,6 +854,26 @@
: object;
return Smi::FromInt(String::cast(*string)->length());
}
+
+ // Use specialized code for getting the length of arrays.
+ if (object->IsJSArray() &&
+ name->Equals(isolate()->heap()->length_symbol())) {
+ Handle<Code> stub;
+ if (state == UNINITIALIZED) {
+ stub = pre_monomorphic_stub();
+ } else if (state == PREMONOMORPHIC) {
+ stub = isolate()->builtins()->LoadIC_ArrayLength();
+ } else if (state != MEGAMORPHIC) {
+ stub = megamorphic_stub();
+ }
+ if (!stub.is_null()) {
+ set_target(*stub);
+#ifdef DEBUG
+ if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
+#endif
+ }
+ return JSArray::cast(*object)->length();
+ }
// Use specialized code for getting prototype of functions.
if (object->IsJSFunction() &&
@@ -986,17 +1006,6 @@
if (!holder->HasFastProperties()) return;
code = isolate()->stub_cache()->ComputeLoadViaGetter(
name, receiver, holder, Handle<JSFunction>::cast(getter));
- } else if (holder->IsJSArray() &&
- name->Equals(isolate()->heap()->length_symbol())) {
- ASSERT(callback->IsForeign());
- ASSERT(reinterpret_cast<AccessorDescriptor*>(
- Handle<Foreign>::cast(callback)->foreign_address())
- == &Accessors::ArrayLength);
- // Use a "load field" IC for getting the array length.
- // Note that the resulting code object is marked as "Code::FIELD"
- // and not as "Code::CALLBACKS".
- code = isolate()->stub_cache()->ComputeLoadField(
- name, receiver, holder, JSArray::ArrayLengthIndex());
} else {
ASSERT(callback->IsForeign());
// No IC support for old-style native accessors.
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Wed Nov 21
03:49:15 2012
+++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Fri Nov 23
02:53:03 2012
@@ -4639,11 +4639,10 @@
for (int i = 0; i < map_set->length() - 1; i++) {
Handle<Map> map = map_set->at(i);
__ CompareMapAndBranch(
- reg, scratch, map, &success, eq, &success,
instr->hydrogen()->mode());
+ reg, scratch, map, &success, eq, &success, REQUIRE_EXACT_MAP);
}
Handle<Map> map = map_set->last();
- DoCheckMapCommon(reg, scratch, map, instr->hydrogen()->mode(),
- instr->environment());
+ DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP,
instr->environment());
__ bind(&success);
}
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Wed Nov 21 03:49:15 2012
+++ /branches/bleeding_edge/src/objects-inl.h Fri Nov 23 02:53:03 2012
@@ -4669,11 +4669,6 @@
ACCESSORS(JSArray, length, Object, kLengthOffset)
-PropertyIndex JSArray::ArrayLengthIndex() {
- return PropertyIndex::NewHeaderIndex(kLengthOffset / kPointerSize);
-}
-
-
ACCESSORS(JSRegExp, data, Object, kDataOffset)
=======================================
--- /branches/bleeding_edge/src/objects.h Thu Nov 22 02:25:22 2012
+++ /branches/bleeding_edge/src/objects.h Fri Nov 23 02:53:03 2012
@@ -8323,9 +8323,6 @@
};
-class PropertyIndex;
-
-
// The JSArray describes JavaScript Arrays
// Such an array can be in one of two modes:
// - fast, backing storage is a FixedArray and length <=
elements.length();
@@ -8379,9 +8376,6 @@
static const int kLengthOffset = JSObject::kHeaderSize;
static const int kSize = kLengthOffset + kPointerSize;
- static inline PropertyIndex ArrayLengthIndex();
- STATIC_ASSERT(kLengthOffset % kPointerSize == 0);
-
private:
// Expand the fixed array backing of a fast-case JSArray to at least
// the requested size.
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Nov 21
03:49:15 2012
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Fri Nov 23
02:53:03 2012
@@ -4537,11 +4537,11 @@
SmallMapList* map_set = instr->hydrogen()->map_set();
for (int i = 0; i < map_set->length() - 1; i++) {
Handle<Map> map = map_set->at(i);
- __ CompareMap(reg, map, &success, instr->hydrogen()->mode());
+ __ CompareMap(reg, map, &success, REQUIRE_EXACT_MAP);
__ j(equal, &success);
}
Handle<Map> map = map_set->last();
- DoCheckMapCommon(reg, map, instr->hydrogen()->mode(),
instr->environment());
+ DoCheckMapCommon(reg, map, REQUIRE_EXACT_MAP, instr->environment());
__ bind(&success);
}
=======================================
--- /branches/bleeding_edge/test/mjsunit/array-length.js Wed Nov 21
03:49:15 2012
+++ /branches/bleeding_edge/test/mjsunit/array-length.js Fri Nov 23
02:53:03 2012
@@ -25,8 +25,6 @@
// (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 = [0,1,2,3];
assertEquals(0, a.length = 0);
@@ -121,42 +119,3 @@
t = a.length = 7;
assertEquals(7, t);
}
-
-function TestLengthAccess() {
- var TestGetLength = function(a, l, getLength, getKeyedLength) {
- assertEquals(l, getLength(a));
- assertEquals(l, getKeyedLength(a));
- }
-
- var Test = function(a, l, getLength, getKeyedLength) {
- // Make the ICs reach the state we want.
- TestGetLength(a, l, getLength, getKeyedLength);
- TestGetLength(a, l, getLength, getKeyedLength);
- TestGetLength(a, l, getLength, getKeyedLength);
- // Also test crankshaft.
- %OptimizeFunctionOnNextCall(getLength);
- %OptimizeFunctionOnNextCall(getKeyedLength);
- TestGetLength(a, l, getLength, getKeyedLength);
- }
-
- var getLength = function(a) { return a.length; }
- var getKeyedLength = function(a) { return a['length']; }
- Test(new Array(4), 4, getLength, getKeyedLength);
-
- getLength = function(a) { return a.length; }
- getKeyedLength = function(a) { return a['length']; }
- Test([1, 2, 3, 4], 4, getLength, getKeyedLength);
-
- getLength = function(a) { return a.length; }
- getKeyedLength = function(a) { return a['length']; }
- Test(Object.create(new Array(4)), 4, getLength, getKeyedLength);
-
- getLength = function(a) { return a.length; }
- getKeyedLength = function(a) { return a['length']; }
- // Set the 'length' of the global object.
- length = 4;
- var globalObject = (1,eval)("this");
- Test(globalObject, 4, getLength, getKeyedLength);
-}
-TestLengthAccess();
-
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev