Revision: 24890
Author: [email protected]
Date: Mon Oct 27 07:54:22 2014 UTC
Log: Version 3.30.19 (based on bleeding_edge revision r24889)
Check string literals with escapes in PreParserTraits::GetSymbol() (issue
3606).
only define ARRAYSIZE_UNSAFE for NaCl builds (Chromium issue 405225).
Performance and stability improvements on all platforms.
https://code.google.com/p/v8/source/detail?r=24890
Added:
/trunk/test/mjsunit/es6/json.js
/trunk/test/mjsunit/es6/math.js
/trunk/test/mjsunit/regress/regress-3643.js
/trunk/test/mjsunit/regress/regress-shift-enumerable.js
Modified:
/trunk/ChangeLog
/trunk/src/arm/full-codegen-arm.cc
/trunk/src/arm/simulator-arm.cc
/trunk/src/arm64/full-codegen-arm64.cc
/trunk/src/array-iterator.js
/trunk/src/array.js
/trunk/src/ast-value-factory.cc
/trunk/src/ast-value-factory.h
/trunk/src/ast.h
/trunk/src/base/bits.cc
/trunk/src/base/bits.h
/trunk/src/base/flags.h
/trunk/src/base/macros.h
/trunk/src/collection-iterator.js
/trunk/src/compiler/arm/instruction-selector-arm.cc
/trunk/src/compiler/arm64/instruction-selector-arm64.cc
/trunk/src/compiler/ast-graph-builder.cc
/trunk/src/compiler/common-operator.h
/trunk/src/compiler/ia32/instruction-selector-ia32.cc
/trunk/src/compiler/instruction-selector-impl.h
/trunk/src/compiler/instruction-selector.cc
/trunk/src/compiler/instruction-selector.h
/trunk/src/compiler/js-generic-lowering.cc
/trunk/src/compiler/js-operator.h
/trunk/src/compiler/linkage.cc
/trunk/src/compiler/machine-operator-reducer.cc
/trunk/src/compiler/machine-operator-reducer.h
/trunk/src/compiler/machine-operator.cc
/trunk/src/compiler/machine-operator.h
/trunk/src/compiler/mips/instruction-selector-mips.cc
/trunk/src/compiler/opcodes.h
/trunk/src/compiler/operator-properties-inl.h
/trunk/src/compiler/pipeline.cc
/trunk/src/compiler/schedule.cc
/trunk/src/compiler/schedule.h
/trunk/src/compiler/scheduler.cc
/trunk/src/compiler/simplified-lowering.cc
/trunk/src/compiler/typer.cc
/trunk/src/compiler/verifier.cc
/trunk/src/compiler/x64/instruction-selector-x64.cc
/trunk/src/compiler.cc
/trunk/src/flag-definitions.h
/trunk/src/heap/heap.cc
/trunk/src/heap/heap.h
/trunk/src/heap-snapshot-generator.cc
/trunk/src/hydrogen-instructions.cc
/trunk/src/ia32/full-codegen-ia32.cc
/trunk/src/ic/ic-compiler.cc
/trunk/src/ic/ic-compiler.h
/trunk/src/json.js
/trunk/src/list-inl.h
/trunk/src/math.js
/trunk/src/mips/full-codegen-mips.cc
/trunk/src/mips64/full-codegen-mips64.cc
/trunk/src/objects-printer.cc
/trunk/src/objects.cc
/trunk/src/objects.h
/trunk/src/preparser.cc
/trunk/src/runtime/runtime-function.cc
/trunk/src/scanner.h
/trunk/src/serialize.cc
/trunk/src/serialize.h
/trunk/src/string-iterator.js
/trunk/src/typedarray.js
/trunk/src/version.cc
/trunk/src/x64/full-codegen-x64.cc
/trunk/src/x87/full-codegen-x87.cc
/trunk/test/cctest/compiler/test-schedule.cc
/trunk/test/cctest/compiler/test-scheduler.cc
/trunk/test/cctest/test-assembler-arm.cc
/trunk/test/cctest/test-parsing.cc
/trunk/test/cctest/test-serialize.cc
/trunk/test/mjsunit/es6/array-iterator.js
/trunk/test/mjsunit/es6/collection-iterator.js
/trunk/test/mjsunit/es6/string-iterator.js
/trunk/test/mjsunit/harmony/proxies.js
/trunk/test/mjsunit/harmony/typedarrays.js
/trunk/test/mjsunit/regress/regress-417709a.js
/trunk/test/unittests/base/bits-unittest.cc
/trunk/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
/trunk/test/unittests/compiler/js-operator-unittest.cc
/trunk/test/unittests/compiler/machine-operator-reducer-unittest.cc
/trunk/test/unittests/compiler/machine-operator-unittest.cc
/trunk/tools/gdbinit
/trunk/tools/whitespace.txt
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/json.js Mon Oct 27 07:54:22 2014 UTC
@@ -0,0 +1,15 @@
+// Copyright 2014 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.
+
+// Flags: --harmony-tostring
+
+function testJSONToString() {
+ assertEquals('[object JSON]', "" + JSON);
+ assertEquals("JSON", JSON[Symbol.toStringTag]);
+ var desc = Object.getOwnPropertyDescriptor(JSON, Symbol.toStringTag);
+ assertTrue(desc.configurable);
+ assertFalse(desc.writable);
+ assertEquals("JSON", desc.value);
+}
+testJSONToString();
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/math.js Mon Oct 27 07:54:22 2014 UTC
@@ -0,0 +1,15 @@
+// Copyright 2014 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.
+
+// Flags: --harmony-tostring
+
+function testMathToString() {
+ assertEquals('[object Math]', "" + Math);
+ assertEquals("Math", Math[Symbol.toStringTag]);
+ var desc = Object.getOwnPropertyDescriptor(Math, Symbol.toStringTag);
+ assertTrue(desc.configurable);
+ assertFalse(desc.writable);
+ assertEquals("Math", desc.value);
+}
+testMathToString();
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-3643.js Mon Oct 27 07:54:22 2014 UTC
@@ -0,0 +1,21 @@
+// Copyright 2014 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.
+
+var a = [1, 2, 3];
+Object.defineProperty(a, '1', {
+ get: function() { delete this[1]; return undefined; },
+ configurable: true
+});
+var s = a.slice(1);
+assertTrue('0' in s);
+
+// Sparse case should hit the same code as above due to presence of the
getter.
+a = [1, 2, 3];
+a[0xffff] = 4;
+Object.defineProperty(a, '1', {
+ get: function() { delete this[1]; return undefined; },
+ configurable: true
+});
+s = a.slice(1);
+assertTrue('0' in s);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-shift-enumerable.js Mon Oct 27
07:54:22 2014 UTC
@@ -0,0 +1,16 @@
+// Copyright 2014 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.
+
+var arr = [1, 2];
+Object.defineProperty(arr, 0xfffe, {
+ value: 3,
+ configurable: true,
+ writable: true,
+ enumerable: false
+});
+arr[0xffff] = 4;
+arr.shift();
+var desc = Object.getOwnPropertyDescriptor(arr, 0xfffe);
+assertEquals(4, desc.value);
+assertFalse(desc.enumerable);
=======================================
--- /trunk/ChangeLog Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/ChangeLog Mon Oct 27 07:54:22 2014 UTC
@@ -1,3 +1,13 @@
+2014-10-27: Version 3.30.19
+
+ Check string literals with escapes in PreParserTraits::GetSymbol()
+ (issue 3606).
+
+ only define ARRAYSIZE_UNSAFE for NaCl builds (Chromium issue
405225).
+
+ Performance and stability improvements on all platforms.
+
+
2014-10-24: Version 3.30.18
Narrow cases where Sparse/Smart versions of Array methods are used
=======================================
--- /trunk/src/arm/full-codegen-arm.cc Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/arm/full-codegen-arm.cc Mon Oct 27 07:54:22 2014 UTC
@@ -1131,6 +1131,7 @@
__ push(r0);
__ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
__ bind(&done_convert);
+ PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
__ push(r0);
// Check for proxies.
@@ -1155,6 +1156,7 @@
__ bind(&call_runtime);
__ push(r0); // Duplicate the enumerable object on the stack.
__ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+ PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
// If we got a map from the runtime call, we can do a fast
// modification check. Otherwise, we got a fixed array, and we have
@@ -1698,6 +1700,7 @@
FastCloneShallowObjectStub stub(isolate(), properties_count);
__ CallStub(&stub);
}
+ PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
// If result_saved is true the result is on top of the stack. If
// result_saved is false the result is in r0.
=======================================
--- /trunk/src/arm/simulator-arm.cc Wed Oct 15 00:05:09 2014 UTC
+++ /trunk/src/arm/simulator-arm.cc Mon Oct 27 07:54:22 2014 UTC
@@ -2741,15 +2741,12 @@
int rs = instr->RsValue();
int32_t rs_val = get_register(rs);
int32_t ret_val = 0;
- DCHECK(rs_val != 0);
// udiv
if (instr->Bit(21) == 0x1) {
- ret_val = static_cast<int32_t>(static_cast<uint32_t>(rm_val)
/
-
static_cast<uint32_t>(rs_val));
- } else if ((rm_val == kMinInt) && (rs_val == -1)) {
- ret_val = kMinInt;
+ ret_val = bit_cast<int32_t>(base::bits::UnsignedDiv32(
+ bit_cast<uint32_t>(rm_val), bit_cast<uint32_t>(rs_val)));
} else {
- ret_val = rm_val / rs_val;
+ ret_val = base::bits::SignedDiv32(rm_val, rs_val);
}
set_register(rn, ret_val);
return;
=======================================
--- /trunk/src/arm64/full-codegen-arm64.cc Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/arm64/full-codegen-arm64.cc Mon Oct 27 07:54:22 2014 UTC
@@ -1124,6 +1124,7 @@
__ Push(x0);
__ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
__ Bind(&done_convert);
+ PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
__ Push(x0);
// Check for proxies.
@@ -1147,6 +1148,7 @@
__ Bind(&call_runtime);
__ Push(x0); // Duplicate the enumerable object on the stack.
__ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+ PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
// If we got a map from the runtime call, we can do a fast
// modification check. Otherwise, we got a fixed array, and we have
@@ -1678,6 +1680,7 @@
FastCloneShallowObjectStub stub(isolate(), properties_count);
__ CallStub(&stub);
}
+ PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
// If result_saved is true the result is on top of the stack. If
// result_saved is false the result is in x0.
=======================================
--- /trunk/src/array-iterator.js Fri Oct 17 20:38:26 2014 UTC
+++ /trunk/src/array-iterator.js Mon Oct 27 07:54:22 2014 UTC
@@ -112,6 +112,8 @@
%FunctionSetName(ArrayIteratorIterator, '[Symbol.iterator]');
%AddNamedProperty(ArrayIterator.prototype, symbolIterator,
ArrayIteratorIterator, DONT_ENUM);
+ %AddNamedProperty(ArrayIterator.prototype, symbolToStringTag,
+ "Array Iterator", READ_ONLY | DONT_ENUM);
}
SetUpArrayIterator();
=======================================
--- /trunk/src/array.js Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/array.js Mon Oct 27 07:54:22 2014 UTC
@@ -284,11 +284,8 @@
function SimpleSlice(array, start_i, del_count, len, deleted_elements) {
for (var i = 0; i < del_count; i++) {
var index = start_i + i;
- // The spec could also be interpreted such that %HasOwnProperty
- // would be the appropriate test. We follow KJS in consulting the
- // prototype.
- var current = array[index];
- if (!IS_UNDEFINED(current) || index in array) {
+ if (index in array) {
+ var current = array[index];
// The spec requires [[DefineOwnProperty]] here, %AddElement is close
// enough (in that it ignores the prototype).
%AddElement(deleted_elements, i, current, NONE);
=======================================
--- /trunk/src/ast-value-factory.cc Fri Oct 3 00:04:58 2014 UTC
+++ /trunk/src/ast-value-factory.cc Mon Oct 27 07:54:22 2014 UTC
@@ -328,15 +328,25 @@
values_.Add(value);
return value;
}
+
+
+#define GENERATE_VALUE_GETTER(value, initializer) \
+ if (!value) { \
+ value = new (zone_) AstValue(initializer); \
+ if (isolate_) { \
+ value->Internalize(isolate_); \
+ } \
+ values_.Add(value); \
+ } \
+ return value;
const AstValue* AstValueFactory::NewBoolean(bool b) {
- AstValue* value = new (zone_) AstValue(b);
- if (isolate_) {
- value->Internalize(isolate_);
+ if (b) {
+ GENERATE_VALUE_GETTER(true_value_, true);
+ } else {
+ GENERATE_VALUE_GETTER(false_value_, false);
}
- values_.Add(value);
- return value;
}
@@ -352,34 +362,21 @@
const AstValue* AstValueFactory::NewNull() {
- AstValue* value = new (zone_) AstValue(AstValue::NULL_TYPE);
- if (isolate_) {
- value->Internalize(isolate_);
- }
- values_.Add(value);
- return value;
+ GENERATE_VALUE_GETTER(null_value_, AstValue::NULL_TYPE);
}
const AstValue* AstValueFactory::NewUndefined() {
- AstValue* value = new (zone_) AstValue(AstValue::UNDEFINED);
- if (isolate_) {
- value->Internalize(isolate_);
- }
- values_.Add(value);
- return value;
+ GENERATE_VALUE_GETTER(undefined_value_, AstValue::UNDEFINED);
}
const AstValue* AstValueFactory::NewTheHole() {
- AstValue* value = new (zone_) AstValue(AstValue::THE_HOLE);
- if (isolate_) {
- value->Internalize(isolate_);
- }
- values_.Add(value);
- return value;
+ GENERATE_VALUE_GETTER(the_hole_value_, AstValue::THE_HOLE);
}
+
+#undef GENERATE_VALUE_GETTER
const AstRawString* AstValueFactory::GetString(
uint32_t hash, bool is_one_byte, Vector<const byte> literal_bytes) {
=======================================
--- /trunk/src/ast-value-factory.h Wed Oct 22 07:27:53 2014 UTC
+++ /trunk/src/ast-value-factory.h Mon Oct 27 07:54:22 2014 UTC
@@ -238,7 +238,7 @@
};
-// For generating string constants.
+// For generating constants.
#define STRING_CONSTANTS(F) \
F(anonymous_function, "(anonymous function)") \
F(arguments, "arguments") \
@@ -268,6 +268,12 @@
F(use_strict, "use strict") \
F(value, "value")
+#define OTHER_CONSTANTS(F) \
+ F(true_value) \
+ F(false_value) \
+ F(null_value) \
+ F(undefined_value) \
+ F(the_hole_value)
class AstValueFactory {
public:
@@ -276,10 +282,12 @@
zone_(zone),
isolate_(NULL),
hash_seed_(hash_seed) {
-#define F(name, str) \
- name##_string_ = NULL;
+#define F(name, str) name##_string_ = NULL;
STRING_CONSTANTS(F)
#undef F
+#define F(name) name##_ = NULL;
+ OTHER_CONSTANTS(F)
+#undef F
}
Zone* zone() const { return zone_; }
@@ -299,15 +307,15 @@
return isolate_ != NULL;
}
-#define F(name, str) \
- const AstRawString* name##_string() { \
- if (name##_string_ == NULL) { \
- const char* data = str; \
- name##_string_ = GetOneByteString( \
+#define F(name, str) \
+ const AstRawString* name##_string() { \
+ if (name##_string_ == NULL) { \
+ const char* data = str; \
+ name##_string_ = GetOneByteString( \
Vector<const uint8_t>(reinterpret_cast<const uint8_t*>(data), \
- static_cast<int>(strlen(data)))); \
- } \
- return name##_string_; \
+ static_cast<int>(strlen(data)))); \
+ } \
+ return name##_string_; \
}
STRING_CONSTANTS(F)
#undef F
@@ -338,10 +346,13 @@
uint32_t hash_seed_;
-#define F(name, str) \
- const AstRawString* name##_string_;
+#define F(name, str) const AstRawString* name##_string_;
STRING_CONSTANTS(F)
#undef F
+
+#define F(name) AstValue* name##_;
+ OTHER_CONSTANTS(F)
+#undef F
};
@@ -351,5 +362,6 @@
} } // namespace v8::internal
#undef STRING_CONSTANTS
+#undef OTHER_CONSTANTS
#endif // V8_AST_VALUE_FACTORY_H_
=======================================
--- /trunk/src/ast.h Wed Oct 22 07:27:53 2014 UTC
+++ /trunk/src/ast.h Mon Oct 27 07:54:22 2014 UTC
@@ -957,9 +957,11 @@
ForInType for_in_type() const { return for_in_type_; }
void set_for_in_type(ForInType type) { for_in_type_ = type; }
- static int num_ids() { return parent_num_ids() + 2; }
+ static int num_ids() { return parent_num_ids() + 4; }
BailoutId BodyId() const { return BailoutId(local_id(0)); }
BailoutId PrepareId() const { return BailoutId(local_id(1)); }
+ BailoutId EnumId() const { return BailoutId(local_id(2)); }
+ BailoutId ToObjectId() const { return BailoutId(local_id(3)); }
virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
virtual BailoutId StackCheckId() const OVERRIDE { return BodyId(); }
@@ -1568,10 +1570,14 @@
};
struct Accessors: public ZoneObject {
- Accessors() : getter(NULL), setter(NULL) { }
+ Accessors() : getter(NULL), setter(NULL) {}
Expression* getter;
Expression* setter;
};
+
+ BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
+
+ static int num_ids() { return parent_num_ids() + 1; }
protected:
ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int
literal_index,
@@ -1582,8 +1588,10 @@
fast_elements_(false),
may_store_doubles_(false),
has_function_(has_function) {}
+ static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
private:
+ int local_id(int n) const { return base_id() + parent_num_ids() + n; }
Handle<FixedArray> constant_properties_;
ZoneList<Property*>* properties_;
int boilerplate_properties_;
=======================================
--- /trunk/src/base/bits.cc Wed Oct 15 00:05:09 2014 UTC
+++ /trunk/src/base/bits.cc Mon Oct 27 07:54:22 2014 UTC
@@ -3,6 +3,9 @@
// found in the LICENSE file.
#include "src/base/bits.h"
+
+#include <limits>
+
#include "src/base/logging.h"
namespace v8 {
@@ -31,6 +34,19 @@
return bit_cast<int32_t>(bit_cast<uint32_t>(acc) +
bit_cast<uint32_t>(SignedMulHigh32(lhs, rhs)));
}
+
+
+int32_t SignedDiv32(int32_t lhs, int32_t rhs) {
+ if (rhs == 0) return 0;
+ if (rhs == -1) return -lhs;
+ return lhs / rhs;
+}
+
+
+int32_t SignedMod32(int32_t lhs, int32_t rhs) {
+ if (rhs == 0 || rhs == -1) return 0;
+ return lhs % rhs;
+}
} // namespace bits
} // namespace base
=======================================
--- /trunk/src/base/bits.h Wed Oct 22 07:27:53 2014 UTC
+++ /trunk/src/base/bits.h Mon Oct 27 07:54:22 2014 UTC
@@ -198,6 +198,32 @@
// |lhs| and |rhs|, extracts the most significant 32 bits of the result,
and
// adds the accumulate value |acc|.
int32_t SignedMulHighAndAdd32(int32_t lhs, int32_t rhs, int32_t acc);
+
+
+// SignedDiv32(lhs, rhs) divides |lhs| by |rhs| and returns the quotient
+// truncated to int32. If |rhs| is zero, then zero is returned. If |lhs|
+// is minint and |rhs| is -1, it returns minint.
+int32_t SignedDiv32(int32_t lhs, int32_t rhs);
+
+
+// SignedMod32(lhs, rhs) divides |lhs| by |rhs| and returns the remainder
+// truncated to int32. If either |rhs| is zero or |lhs| is minint and |rhs|
+// is -1, it returns zero.
+int32_t SignedMod32(int32_t lhs, int32_t rhs);
+
+
+// UnsignedDiv32(lhs, rhs) divides |lhs| by |rhs| and returns the quotient
+// truncated to uint32. If |rhs| is zero, then zero is returned.
+inline uint32_t UnsignedDiv32(uint32_t lhs, uint32_t rhs) {
+ return rhs ? lhs / rhs : 0u;
+}
+
+
+// UnsignedMod32(lhs, rhs) divides |lhs| by |rhs| and returns the remainder
+// truncated to uint32. If |rhs| is zero, then zero is returned.
+inline uint32_t UnsignedMod32(uint32_t lhs, uint32_t rhs) {
+ return rhs ? lhs % rhs : 0u;
+}
} // namespace bits
} // namespace base
=======================================
--- /trunk/src/base/flags.h Thu Oct 2 00:05:29 2014 UTC
+++ /trunk/src/base/flags.h Mon Oct 27 07:54:22 2014 UTC
@@ -26,8 +26,9 @@
typedef S mask_type;
Flags() : mask_(0) {}
- Flags(flag_type flag) : mask_(flag) {} // NOLINT(runtime/explicit)
- explicit Flags(mask_type mask) : mask_(mask) {}
+ Flags(flag_type flag) // NOLINT(runtime/explicit)
+ : mask_(static_cast<S>(flag)) {}
+ explicit Flags(mask_type mask) : mask_(static_cast<S>(mask)) {}
Flags& operator&=(const Flags& flags) {
mask_ &= flags.mask_;
=======================================
--- /trunk/src/base/macros.h Wed Oct 22 07:27:53 2014 UTC
+++ /trunk/src/base/macros.h Mon Oct 27 07:54:22 2014 UTC
@@ -25,6 +25,8 @@
(reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4)
+#if V8_OS_NACL
+
// ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize,
// but can be used on anonymous types or types defined inside
// functions. It's less safe than arraysize as it accepts some
@@ -65,9 +67,6 @@
((sizeof(a) / sizeof(*(a))) / \
static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) // NOLINT
-
-#if V8_OS_NACL
-
// TODO(bmeurer): For some reason, the NaCl toolchain cannot handle the
correct
// definition of arraysize() below, so we have to use the unsafe version
for
// now.
@@ -397,5 +396,23 @@
inline T RoundUp(T x, intptr_t m) {
return RoundDown<T>(static_cast<T>(x + m - 1), m);
}
+
+
+namespace v8 {
+namespace base {
+
+// TODO(yangguo): This is a poor man's replacement for std::is_fundamental,
+// which requires C++11. Switch to std::is_fundamental once possible.
+template <typename T>
+inline bool is_fundamental() {
+ return false;
+}
+
+template <>
+inline bool is_fundamental<uint8_t>() {
+ return true;
+}
+}
+} // namespace v8::base
#endif // V8_BASE_MACROS_H_
=======================================
--- /trunk/src/collection-iterator.js Tue Jul 15 00:04:47 2014 UTC
+++ /trunk/src/collection-iterator.js Mon Oct 27 07:54:22 2014 UTC
@@ -77,6 +77,8 @@
%FunctionSetName(SetIteratorSymbolIterator, '[Symbol.iterator]');
%AddNamedProperty(SetIterator.prototype, symbolIterator,
SetIteratorSymbolIterator, DONT_ENUM);
+ %AddNamedProperty(SetIterator.prototype, symbolToStringTag,
+ "Set Iterator", READ_ONLY | DONT_ENUM);
}
SetUpSetIterator();
@@ -174,6 +176,8 @@
%FunctionSetName(MapIteratorSymbolIterator, '[Symbol.iterator]');
%AddNamedProperty(MapIterator.prototype, symbolIterator,
MapIteratorSymbolIterator, DONT_ENUM);
+ %AddNamedProperty(MapIterator.prototype, symbolToStringTag,
+ "Map Iterator", READ_ONLY | DONT_ENUM);
}
SetUpMapIterator();
=======================================
--- /trunk/src/compiler/arm/instruction-selector-arm.cc Fri Oct 24 14:44:48
2014 UTC
+++ /trunk/src/compiler/arm/instruction-selector-arm.cc Mon Oct 27 07:54:22
2014 UTC
@@ -1135,6 +1135,12 @@
VisitFloat64Compare(this, node, &cont);
}
+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+ return MachineOperatorBuilder::Flag::kNoFlags;
+}
} // namespace compiler
} // namespace internal
} // namespace v8
=======================================
--- /trunk/src/compiler/arm64/instruction-selector-arm64.cc Fri Oct 17
20:38:26 2014 UTC
+++ /trunk/src/compiler/arm64/instruction-selector-arm64.cc Mon Oct 27
07:54:22 2014 UTC
@@ -982,16 +982,16 @@
// Shared routine for multiple word compare operations.
static void VisitWordCompare(InstructionSelector* selector, Node* node,
InstructionCode opcode, FlagsContinuation*
cont,
- bool commutative) {
+ bool commutative, ImmediateMode
immediate_mode) {
Arm64OperandGenerator g(selector);
Node* left = node->InputAt(0);
Node* right = node->InputAt(1);
// Match immediates on left or right side of comparison.
- if (g.CanBeImmediate(right, kArithmeticImm)) {
+ if (g.CanBeImmediate(right, immediate_mode)) {
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseImmediate(right),
cont);
- } else if (g.CanBeImmediate(left, kArithmeticImm)) {
+ } else if (g.CanBeImmediate(left, immediate_mode)) {
if (!commutative) cont->Commute();
VisitCompare(selector, opcode, g.UseRegister(right),
g.UseImmediate(left),
cont);
@@ -1004,7 +1004,7 @@
static void VisitWord32Compare(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
- VisitWordCompare(selector, node, kArm64Cmp32, cont, false);
+ VisitWordCompare(selector, node, kArm64Cmp32, cont, false,
kArithmeticImm);
}
@@ -1098,16 +1098,20 @@
return VisitWord32Compare(this, value, &cont);
case IrOpcode::kWord64Equal:
cont.OverwriteAndNegateIfEqual(kEqual);
- return VisitWordCompare(this, value, kArm64Cmp, &cont, false);
+ return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+ kArithmeticImm);
case IrOpcode::kInt64LessThan:
cont.OverwriteAndNegateIfEqual(kSignedLessThan);
- return VisitWordCompare(this, value, kArm64Cmp, &cont, false);
+ return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+ kArithmeticImm);
case IrOpcode::kInt64LessThanOrEqual:
cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
- return VisitWordCompare(this, value, kArm64Cmp, &cont, false);
+ return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+ kArithmeticImm);
case IrOpcode::kUint64LessThan:
cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
- return VisitWordCompare(this, value, kArm64Cmp, &cont, false);
+ return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+ kArithmeticImm);
case IrOpcode::kFloat64Equal:
cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
return VisitFloat64Compare(this, value, &cont);
@@ -1145,11 +1149,14 @@
}
break;
case IrOpcode::kInt32Add:
- return VisitWordCompare(this, value, kArm64Cmn32, &cont, true);
+ return VisitWordCompare(this, value, kArm64Cmn32, &cont, true,
+ kArithmeticImm);
case IrOpcode::kInt32Sub:
- return VisitWordCompare(this, value, kArm64Cmp32, &cont, false);
+ return VisitWordCompare(this, value, kArm64Cmp32, &cont, false,
+ kArithmeticImm);
case IrOpcode::kWord32And:
- return VisitWordCompare(this, value, kArm64Tst32, &cont, true);
+ return VisitWordCompare(this, value, kArm64Tst32, &cont, true,
+ kLogical32Imm);
default:
break;
}
@@ -1169,11 +1176,14 @@
if (CanCover(user, value)) {
switch (value->opcode()) {
case IrOpcode::kInt32Add:
- return VisitWordCompare(this, value, kArm64Cmn32, &cont, true);
+ return VisitWordCompare(this, value, kArm64Cmn32, &cont, true,
+ kArithmeticImm);
case IrOpcode::kInt32Sub:
- return VisitWordCompare(this, value, kArm64Cmp32, &cont, false);
+ return VisitWordCompare(this, value, kArm64Cmp32, &cont, false,
+ kArithmeticImm);
case IrOpcode::kWord32And:
- return VisitWordCompare(this, value, kArm64Tst32, &cont, true);
+ return VisitWordCompare(this, value, kArm64Tst32, &cont, true,
+ kLogical32Imm);
default:
break;
}
@@ -1217,14 +1227,15 @@
if (CanCover(user, value)) {
switch (value->opcode()) {
case IrOpcode::kWord64And:
- return VisitWordCompare(this, value, kArm64Tst, &cont, true);
+ return VisitWordCompare(this, value, kArm64Tst, &cont, true,
+ kLogical64Imm);
default:
break;
}
return VisitWord64Test(this, value, &cont);
}
}
- VisitWordCompare(this, node, kArm64Cmp, &cont, false);
+ VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
}
@@ -1252,19 +1263,19 @@
void InstructionSelector::VisitInt64LessThan(Node* node) {
FlagsContinuation cont(kSignedLessThan, node);
- VisitWordCompare(this, node, kArm64Cmp, &cont, false);
+ VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
}
void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
FlagsContinuation cont(kSignedLessThanOrEqual, node);
- VisitWordCompare(this, node, kArm64Cmp, &cont, false);
+ VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
}
void InstructionSelector::VisitUint64LessThan(Node* node) {
FlagsContinuation cont(kUnsignedLessThan, node);
- VisitWordCompare(this, node, kArm64Cmp, &cont, false);
+ VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
}
@@ -1285,6 +1296,12 @@
VisitFloat64Compare(this, node, &cont);
}
+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+ return MachineOperatorBuilder::Flag::kNoFlags;
+}
} // namespace compiler
} // namespace internal
} // namespace v8
=======================================
--- /trunk/src/compiler/ast-graph-builder.cc Thu Oct 23 08:44:45 2014 UTC
+++ /trunk/src/compiler/ast-graph-builder.cc Mon Oct 27 07:54:22 2014 UTC
@@ -642,11 +642,14 @@
// Convert object to jsobject.
// PrepareForBailoutForId(stmt->PrepareId(), TOS_REG);
obj = NewNode(javascript()->ToObject(), obj);
+ PrepareFrameState(obj, stmt->ToObjectId(),
OutputFrameStateCombine::Push());
environment()->Push(obj);
// TODO(dcarney): should do a fast enum cache check here to skip
runtime.
environment()->Push(obj);
Node* cache_type = ProcessArguments(
javascript()->CallRuntime(Runtime::kGetPropertyNamesFast, 1), 1);
+ PrepareFrameState(cache_type, stmt->EnumId(),
+ OutputFrameStateCombine::Push());
// TODO(dcarney): these next runtime calls should be removed in favour
of
// a few simplified instructions.
environment()->Push(obj);
@@ -882,6 +885,8 @@
const Operator* op =
javascript()->CallRuntime(Runtime::kCreateObjectLiteral, 4);
Node* literal = NewNode(op, literals_array, literal_index, constants,
flags);
+ PrepareFrameState(literal, expr->CreateLiteralId(),
+ OutputFrameStateCombine::Push());
// The object is expected on the operand stack during computation of the
// property values and is the value of the entire expression.
@@ -943,7 +948,10 @@
if (property->emit_store()) {
const Operator* op =
javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
- NewNode(op, receiver, value);
+ Node* set_prototype = NewNode(op, receiver, value);
+ // SetPrototype should not lazy deopt on an object
+ // literal.
+ PrepareFrameState(set_prototype, BailoutId::None());
}
break;
}
@@ -970,7 +978,8 @@
const Operator* op =
javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
Node* call = NewNode(op, literal, name, getter, setter, attr);
- PrepareFrameState(call, it->first->id());
+ // This should not lazy deopt on a new literal.
+ PrepareFrameState(call, BailoutId::None());
}
// Transform literals that contain functions to fast properties.
@@ -1237,7 +1246,7 @@
receiver_value = NewNode(common()->Projection(1), pair);
PrepareFrameState(pair, expr->EvalOrLookupId(),
- OutputFrameStateCombine::Push());
+ OutputFrameStateCombine::Push(2));
break;
}
case Call::PROPERTY_CALL: {
=======================================
--- /trunk/src/compiler/common-operator.h Thu Oct 23 08:44:45 2014 UTC
+++ /trunk/src/compiler/common-operator.h Mon Oct 27 07:54:22 2014 UTC
@@ -66,6 +66,10 @@
bool IsOutputIgnored() const {
return kind_ == kPushOutput && parameter_ == 0;
}
+
+ size_t ConsumedOutputCount() const {
+ return kind_ == kPushOutput ? GetPushCount() : 1;
+ }
bool operator==(OutputFrameStateCombine const& other) const {
return kind_ == other.kind_ && parameter_ == other.parameter_;
=======================================
--- /trunk/src/compiler/ia32/instruction-selector-ia32.cc Fri Oct 24
14:44:48 2014 UTC
+++ /trunk/src/compiler/ia32/instruction-selector-ia32.cc Mon Oct 27
07:54:22 2014 UTC
@@ -877,6 +877,12 @@
VisitFloat64Compare(this, node, &cont);
}
+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+ return MachineOperatorBuilder::Flag::kNoFlags;
+}
} // namespace compiler
} // namespace internal
} // namespace v8
=======================================
--- /trunk/src/compiler/instruction-selector-impl.h Wed Oct 15 00:05:09
2014 UTC
+++ /trunk/src/compiler/instruction-selector-impl.h Mon Oct 27 07:54:22
2014 UTC
@@ -127,6 +127,12 @@
int index = sequence()->AddImmediate(Constant(imm));
return ImmediateOperand::Create(index, zone());
}
+
+ InstructionOperand* TempLocation(LinkageLocation location, MachineType
type) {
+ UnallocatedOperand* op = ToUnallocatedOperand(location, type);
+ op->set_virtual_register(sequence()->NextVirtualRegister());
+ return op;
+ }
InstructionOperand* Label(BasicBlock* block) {
// TODO(bmeurer): We misuse ImmediateOperand here.
=======================================
--- /trunk/src/compiler/instruction-selector.cc Thu Oct 23 08:44:45 2014 UTC
+++ /trunk/src/compiler/instruction-selector.cc Mon Oct 27 07:54:22 2014 UTC
@@ -217,6 +217,23 @@
DCHECK(!IsDouble(node));
sequence()->MarkAsReference(sequence()->GetVirtualRegister(node));
}
+
+
+void InstructionSelector::MarkAsRepresentation(MachineType rep,
+ InstructionOperand* op) {
+ UnallocatedOperand* unalloc = UnallocatedOperand::cast(op);
+ switch (RepresentationOf(rep)) {
+ case kRepFloat32:
+ case kRepFloat64:
+ sequence()->MarkAsDouble(unalloc->virtual_register());
+ break;
+ case kRepTagged:
+ sequence()->MarkAsReference(unalloc->virtual_register());
+ break;
+ default:
+ break;
+ }
+}
void InstructionSelector::MarkAsRepresentation(MachineType rep, Node*
node) {
@@ -274,15 +291,27 @@
}
// Filter out the outputs that aren't live because no projection uses
them.
+ size_t outputs_needed_by_framestate =
+ buffer->frame_state_descriptor == NULL
+ ? 0
+ : buffer->frame_state_descriptor->state_combine()
+ .ConsumedOutputCount();
for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
- if (buffer->output_nodes[i] != NULL) {
- Node* output = buffer->output_nodes[i];
+ bool output_is_live =
+ buffer->output_nodes[i] != NULL || i <
outputs_needed_by_framestate;
+ if (output_is_live) {
MachineType type =
buffer->descriptor->GetReturnType(static_cast<int>(i));
LinkageLocation location =
buffer->descriptor->GetReturnLocation(static_cast<int>(i));
- MarkAsRepresentation(type, output);
- buffer->outputs.push_back(g.DefineAsLocation(output, location,
type));
+
+ Node* output = buffer->output_nodes[i];
+ InstructionOperand* op =
+ output == NULL ? g.TempLocation(location, type)
+ : g.DefineAsLocation(output, location, type);
+ MarkAsRepresentation(type, op);
+
+ buffer->outputs.push_back(op);
}
}
}
=======================================
--- /trunk/src/compiler/instruction-selector.h Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/compiler/instruction-selector.h Mon Oct 27 07:54:22 2014 UTC
@@ -84,6 +84,9 @@
static Features SupportedFeatures() {
return Features(CpuFeatures::SupportedFeatures());
}
+
+ // TODO(sigurds) This should take a CpuFeatures argument.
+ static MachineOperatorBuilder::Flags SupportedMachineOperatorFlags();
//
===========================================================================
// ============ Architecture-independent graph covering methods.
=============
@@ -136,6 +139,10 @@
// by {node}.
void MarkAsRepresentation(MachineType rep, Node* node);
+ // Inform the register allocation of the representation of the
unallocated
+ // operand {op}.
+ void MarkAsRepresentation(MachineType rep, InstructionOperand* op);
+
// Initialize the call buffer with the InstructionOperands, nodes, etc,
// corresponding
// to the inputs and outputs of the call.
=======================================
--- /trunk/src/compiler/js-generic-lowering.cc Mon Oct 13 00:05:20 2014 UTC
+++ /trunk/src/compiler/js-generic-lowering.cc Mon Oct 27 07:54:22 2014 UTC
@@ -275,8 +275,7 @@
const LoadPropertyParameters& p = LoadPropertyParametersOf(node->op());
Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(isolate());
if (FLAG_vector_ics) {
- PatchInsertInput(node, 2,
- jsgraph()->SmiConstant(p.feedback().slot().ToInt()));
+ PatchInsertInput(node, 2,
jsgraph()->SmiConstant(p.feedback().index()));
PatchInsertInput(node, 3,
jsgraph()->HeapConstant(p.feedback().vector()));
}
ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
@@ -289,8 +288,7 @@
CodeFactory::LoadICInOptimizedCode(isolate(), p.contextual_mode());
PatchInsertInput(node, 1, jsgraph()->HeapConstant(p.name()));
if (FLAG_vector_ics) {
- PatchInsertInput(node, 2,
- jsgraph()->SmiConstant(p.feedback().slot().ToInt()));
+ PatchInsertInput(node, 2,
jsgraph()->SmiConstant(p.feedback().index()));
PatchInsertInput(node, 3,
jsgraph()->HeapConstant(p.feedback().vector()));
}
ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
=======================================
--- /trunk/src/compiler/js-operator.h Tue Oct 21 12:48:28 2014 UTC
+++ /trunk/src/compiler/js-operator.h Mon Oct 27 07:54:22 2014 UTC
@@ -103,6 +103,8 @@
Handle<TypeFeedbackVector> vector() const { return vector_; }
FeedbackVectorICSlot slot() const { return slot_; }
+
+ int index() const { return vector_->GetIndex(slot_); }
private:
const Handle<TypeFeedbackVector> vector_;
=======================================
--- /trunk/src/compiler/linkage.cc Tue Oct 21 12:48:28 2014 UTC
+++ /trunk/src/compiler/linkage.cc Mon Oct 27 07:54:22 2014 UTC
@@ -125,6 +125,7 @@
case Runtime::kCompileLazy:
case Runtime::kCompileOptimized:
case Runtime::kCompileString:
+ case Runtime::kCreateObjectLiteral:
case Runtime::kDebugBreak:
case Runtime::kDataViewSetInt8:
case Runtime::kDataViewSetUint8:
@@ -143,23 +144,38 @@
case Runtime::kDataViewGetFloat32:
case Runtime::kDataViewGetFloat64:
case Runtime::kDebugEvaluate:
+ case Runtime::kDebugEvaluateGlobal:
case Runtime::kDebugGetLoadedScripts:
case Runtime::kDebugGetPropertyDetails:
case Runtime::kDebugPromiseEvent:
+ case Runtime::kDefineAccessorPropertyUnchecked:
+ case Runtime::kDefineDataPropertyUnchecked:
case Runtime::kDeleteProperty:
case Runtime::kDeoptimizeFunction:
case Runtime::kFunctionBindArguments:
+ case Runtime::kGetDefaultReceiver:
case Runtime::kGetFrameCount:
case Runtime::kGetOwnProperty:
+ case Runtime::kGetOwnPropertyNames:
+ case Runtime::kGetPropertyNamesFast:
+ case Runtime::kGetPrototype:
+ case Runtime::kInlineArguments:
case Runtime::kInlineCallFunction:
case Runtime::kInlineDateField:
case Runtime::kInlineRegExpExec:
+ case Runtime::kInternalSetPrototype:
+ case Runtime::kInterrupt:
+ case Runtime::kIsPropertyEnumerable:
+ case Runtime::kIsSloppyModeFunction:
case Runtime::kLiveEditGatherCompileInfo:
case Runtime::kLoadLookupSlot:
case Runtime::kLoadLookupSlotNoReferenceError:
case Runtime::kMaterializeRegExpLiteral:
+ case Runtime::kNewObject:
case Runtime::kNewObjectFromBound:
+ case Runtime::kNewObjectWithAllocationSite:
case Runtime::kObjectFreeze:
+ case Runtime::kOwnKeys:
case Runtime::kParseJson:
case Runtime::kPrepareStep:
case Runtime::kPreventExtensions:
@@ -168,22 +184,28 @@
case Runtime::kRegExpCompile:
case Runtime::kRegExpExecMultiple:
case Runtime::kResolvePossiblyDirectEval:
- // case Runtime::kSetPrototype:
+ case Runtime::kSetPrototype:
case Runtime::kSetScriptBreakPoint:
+ case Runtime::kSparseJoinWithSeparator:
case Runtime::kStackGuard:
+ case Runtime::kStoreKeyedToSuper_Sloppy:
+ case Runtime::kStoreKeyedToSuper_Strict:
+ case Runtime::kStoreToSuper_Sloppy:
+ case Runtime::kStoreToSuper_Strict:
case Runtime::kStoreLookupSlot:
case Runtime::kStringBuilderConcat:
+ case Runtime::kStringBuilderJoin:
case Runtime::kStringReplaceGlobalRegExpWithString:
+ case Runtime::kThrowNonMethodError:
+ case Runtime::kThrowNotDateError:
case Runtime::kThrowReferenceError:
+ case Runtime::kThrowUnsupportedSuperError:
case Runtime::kThrow:
case Runtime::kTypedArraySetFastCases:
case Runtime::kTypedArrayInitializeFromArrayLike:
- case Runtime::kDebugEvaluateGlobal:
- case Runtime::kOwnKeys:
- case Runtime::kGetOwnPropertyNames:
- case Runtime::kIsPropertyEnumerable:
- case Runtime::kGetPrototype:
- case Runtime::kSparseJoinWithSeparator:
+#ifdef V8_I18N_SUPPORT
+ case Runtime::kGetImplFromInitializedIntlObject:
+#endif
return true;
default:
return false;
=======================================
--- /trunk/src/compiler/machine-operator-reducer.cc Fri Oct 24 14:44:48
2014 UTC
+++ /trunk/src/compiler/machine-operator-reducer.cc Mon Oct 27 07:54:22
2014 UTC
@@ -56,6 +56,11 @@
Node* MachineOperatorReducer::Word32Shr(Node* lhs, uint32_t rhs) {
return graph()->NewNode(machine()->Word32Shr(), lhs,
Uint32Constant(rhs));
}
+
+
+Node* MachineOperatorReducer::Word32Equal(Node* lhs, Node* rhs) {
+ return graph()->NewNode(machine()->Word32Equal(), lhs, rhs);
+}
Node* MachineOperatorReducer::Int32Add(Node* lhs, Node* rhs) {
@@ -299,40 +304,12 @@
}
case IrOpcode::kInt32Div:
return ReduceInt32Div(node);
- case IrOpcode::kUint32Div: {
- Uint32BinopMatcher m(node);
- if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x
- // TODO(turbofan): if (m.left().Is(0))
- // TODO(turbofan): if (m.right().Is(0))
- // TODO(turbofan): if (m.LeftEqualsRight())
- if (m.IsFoldable() && !m.right().Is(0)) { // K / K => K
- return ReplaceInt32(m.left().Value() / m.right().Value());
- }
- if (m.right().IsPowerOf2()) { // x / 2^n => x >> n
- node->set_op(machine()->Word32Shr());
- node->ReplaceInput(1,
Int32Constant(WhichPowerOf2(m.right().Value())));
- return Changed(node);
- }
- break;
- }
+ case IrOpcode::kUint32Div:
+ return ReduceUint32Div(node);
case IrOpcode::kInt32Mod:
return ReduceInt32Mod(node);
- case IrOpcode::kUint32Mod: {
- Uint32BinopMatcher m(node);
- if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0
- // TODO(turbofan): if (m.left().Is(0))
- // TODO(turbofan): if (m.right().Is(0))
- // TODO(turbofan): if (m.LeftEqualsRight())
- if (m.IsFoldable() && !m.right().Is(0)) { // K % K => K
- return ReplaceInt32(m.left().Value() % m.right().Value());
- }
- if (m.right().IsPowerOf2()) { // x % 2^n => x & 2^n-1
- node->set_op(machine()->Word32And());
- node->ReplaceInput(1, Int32Constant(m.right().Value() - 1));
- return Changed(node);
- }
- break;
- }
+ case IrOpcode::kUint32Mod:
+ return ReduceUint32Mod(node);
case IrOpcode::kInt32LessThan: {
Int32BinopMatcher m(node);
if (m.IsFoldable()) { // K < K => K
@@ -554,13 +531,16 @@
Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) {
Int32BinopMatcher m(node);
+ if (m.left().Is(0)) return Replace(m.left().node()); // 0 / x => 0
if (m.right().Is(0)) return Replace(m.right().node()); // x / 0 => 0
if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x
- // TODO(turbofan): if (m.left().Is(0))
- // TODO(turbofan): if (m.LeftEqualsRight())
- if (m.IsFoldable() && !m.right().Is(0)) { // K / K => K
- if (m.right().Is(-1)) return ReplaceInt32(-m.left().Value());
- return ReplaceInt32(m.left().Value() / m.right().Value());
+ if (m.IsFoldable()) { // K / K => K
+ return ReplaceInt32(
+ base::bits::SignedDiv32(m.left().Value(), m.right().Value()));
+ }
+ if (m.LeftEqualsRight()) { // x / x => x != 0
+ Node* const zero = Int32Constant(0);
+ return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero));
}
if (m.right().Is(-1)) { // x / -1 => 0 - x
node->set_op(machine()->Int32Sub());
@@ -593,17 +573,40 @@
}
return NoChange();
}
+
+
+Reduction MachineOperatorReducer::ReduceUint32Div(Node* node) {
+ Uint32BinopMatcher m(node);
+ if (m.left().Is(0)) return Replace(m.left().node()); // 0 / x => 0
+ if (m.right().Is(0)) return Replace(m.right().node()); // x / 0 => 0
+ if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x
+ if (m.IsFoldable()) { // K / K => K
+ return ReplaceUint32(
+ base::bits::UnsignedDiv32(m.left().Value(), m.right().Value()));
+ }
+ if (m.LeftEqualsRight()) { // x / x => x != 0
+ Node* const zero = Int32Constant(0);
+ return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero));
+ }
+ if (m.right().IsPowerOf2()) { // x / 2^n => x >> n
+ node->set_op(machine()->Word32Shr());
+ node->ReplaceInput(1,
Uint32Constant(WhichPowerOf2(m.right().Value())));
+ return Changed(node);
+ }
+ return NoChange();
+}
Reduction MachineOperatorReducer::ReduceInt32Mod(Node* node) {
Int32BinopMatcher m(node);
- if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0
- if (m.right().Is(-1)) return ReplaceInt32(0); // x % -1 => 0
- // TODO(turbofan): if (m.left().Is(0))
- // TODO(turbofan): if (m.right().Is(0))
- // TODO(turbofan): if (m.LeftEqualsRight())
- if (m.IsFoldable() && !m.right().Is(0)) { // K % K => K
- return ReplaceInt32(m.left().Value() % m.right().Value());
+ if (m.left().Is(0)) return Replace(m.left().node()); // 0 % x => 0
+ if (m.right().Is(0)) return Replace(m.right().node()); // x % 0 => 0
+ if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0
+ if (m.right().Is(-1)) return ReplaceInt32(0); // x % -1 => 0
+ if (m.LeftEqualsRight()) return ReplaceInt32(0); // x % x => 0
+ if (m.IsFoldable()) { // K % K => K
+ return ReplaceInt32(
+ base::bits::SignedMod32(m.left().Value(), m.right().Value()));
}
if (m.right().HasValue()) {
Node* const dividend = m.left().node();
@@ -637,6 +640,25 @@
}
return NoChange();
}
+
+
+Reduction MachineOperatorReducer::ReduceUint32Mod(Node* node) {
+ Uint32BinopMatcher m(node);
+ if (m.left().Is(0)) return Replace(m.left().node()); // 0 % x => 0
+ if (m.right().Is(0)) return Replace(m.right().node()); // x % 0 => 0
+ if (m.right().Is(1)) return ReplaceUint32(0); // x % 1 => 0
+ if (m.LeftEqualsRight()) return ReplaceInt32(0); // x % x => 0
+ if (m.IsFoldable()) { // K % K => K
+ return ReplaceUint32(
+ base::bits::UnsignedMod32(m.left().Value(), m.right().Value()));
+ }
+ if (m.right().IsPowerOf2()) { // x % 2^n => x & 2^n-1
+ node->set_op(machine()->Word32And());
+ node->ReplaceInput(1, Uint32Constant(m.right().Value() - 1));
+ return Changed(node);
+ }
+ return NoChange();
+}
Reduction MachineOperatorReducer::ReduceProjection(size_t index, Node*
node) {
=======================================
--- /trunk/src/compiler/machine-operator-reducer.h Wed Oct 15 13:35:30 2014
UTC
+++ /trunk/src/compiler/machine-operator-reducer.h Mon Oct 27 07:54:22 2014
UTC
@@ -37,6 +37,7 @@
Node* Word32And(Node* lhs, uint32_t rhs);
Node* Word32Sar(Node* lhs, uint32_t rhs);
Node* Word32Shr(Node* lhs, uint32_t rhs);
+ Node* Word32Equal(Node* lhs, Node* rhs);
Node* Int32Add(Node* lhs, Node* rhs);
Node* Int32Sub(Node* lhs, Node* rhs);
Node* Int32Mul(Node* lhs, Node* rhs);
@@ -53,12 +54,17 @@
Reduction ReplaceInt32(int32_t value) {
return Replace(Int32Constant(value));
}
+ Reduction ReplaceUint32(uint32_t value) {
+ return Replace(Uint32Constant(value));
+ }
Reduction ReplaceInt64(int64_t value) {
return Replace(Int64Constant(value));
}
Reduction ReduceInt32Div(Node* node);
+ Reduction ReduceUint32Div(Node* node);
Reduction ReduceInt32Mod(Node* node);
+ Reduction ReduceUint32Mod(Node* node);
Reduction ReduceProjection(size_t index, Node* node);
Graph* graph() const;
=======================================
--- /trunk/src/compiler/machine-operator.cc Wed Oct 15 13:35:30 2014 UTC
+++ /trunk/src/compiler/machine-operator.cc Mon Oct 27 07:54:22 2014 UTC
@@ -110,6 +110,10 @@
V(Float64Div, Operator::kNoProperties, 2,
1) \
V(Float64Mod, Operator::kNoProperties, 2,
1) \
V(Float64Sqrt, Operator::kNoProperties, 1,
1) \
+ V(Float64Ceil, Operator::kNoProperties, 1,
1) \
+ V(Float64Floor, Operator::kNoProperties, 1,
1) \
+ V(Float64RoundTruncate, Operator::kNoProperties, 1,
1) \
+ V(Float64RoundTiesAway, Operator::kNoProperties, 1,
1) \
V(Float64Equal, Operator::kCommutative, 2,
1) \
V(Float64LessThan, Operator::kNoProperties, 2,
1) \
V(Float64LessThanOrEqual, Operator::kNoProperties, 2,
1) \
@@ -188,8 +192,8 @@
LAZY_INSTANCE_INITIALIZER;
-MachineOperatorBuilder::MachineOperatorBuilder(MachineType word)
- : impl_(kImpl.Get()), word_(word) {
+MachineOperatorBuilder::MachineOperatorBuilder(MachineType word, Flags
flags)
+ : impl_(kImpl.Get()), word_(word), flags_(flags) {
DCHECK(word == kRepWord32 || word == kRepWord64);
}
@@ -236,7 +240,6 @@
UNREACHABLE();
return NULL;
}
-
} // namespace compiler
} // namespace internal
} // namespace v8
=======================================
--- /trunk/src/compiler/machine-operator.h Wed Oct 15 13:35:30 2014 UTC
+++ /trunk/src/compiler/machine-operator.h Mon Oct 27 07:54:22 2014 UTC
@@ -5,6 +5,7 @@
#ifndef V8_COMPILER_MACHINE_OPERATOR_H_
#define V8_COMPILER_MACHINE_OPERATOR_H_
+#include "src/base/flags.h"
#include "src/compiler/machine-type.h"
namespace v8 {
@@ -57,7 +58,19 @@
// for generating code to run on architectures such as ia32, x64, arm, etc.
class MachineOperatorBuilder FINAL {
public:
- explicit MachineOperatorBuilder(MachineType word = kMachPtr);
+ // Flags that specify which operations are available. This is useful
+ // for operations that are unsupported by some back-ends.
+ enum class Flag : unsigned {
+ kNoFlags = 0,
+ kFloat64Floor = 1 << 0,
+ kFloat64Ceil = 1 << 1,
+ kFloat64RoundTruncate = 1 << 2,
+ kFloat64RoundTiesAway = 1 << 3
+ };
+ typedef base::Flags<Flag, unsigned> Flags;
+
+ explicit MachineOperatorBuilder(MachineType word = kMachPtr,
+ Flags supportedOperators =
Flag::kNoFlags);
const Operator* Word32And();
const Operator* Word32Or();
@@ -134,6 +147,20 @@
const Operator* Float64Equal();
const Operator* Float64LessThan();
const Operator* Float64LessThanOrEqual();
+
+ // Floating point rounding.
+ const Operator* Float64Floor();
+ const Operator* Float64Ceil();
+ const Operator* Float64RoundTruncate();
+ const Operator* Float64RoundTiesAway();
+ bool HasFloat64Floor() { return flags_ & Flag::kFloat64Floor; }
+ bool HasFloat64Ceil() { return flags_ & Flag::kFloat64Ceil; }
+ bool HasFloat64RoundTruncate() {
+ return flags_ & Flag::kFloat64RoundTruncate;
+ }
+ bool HasFloat64RoundTiesAway() {
+ return flags_ & Flag::kFloat64RoundTiesAway;
+ }
// load [base + index]
const Operator* Load(LoadRepresentation rep);
@@ -181,8 +208,11 @@
private:
const MachineOperatorBuilderImpl& impl_;
const MachineType word_;
+ const Flags flags_;
};
+
+DEFINE_OPERATORS_FOR_FLAGS(MachineOperatorBuilder::Flags)
} // namespace compiler
} // namespace internal
} // namespace v8
=======================================
--- /trunk/src/compiler/mips/instruction-selector-mips.cc Fri Oct 17
20:38:26 2014 UTC
+++ /trunk/src/compiler/mips/instruction-selector-mips.cc Mon Oct 27
07:54:22 2014 UTC
@@ -647,6 +647,12 @@
VisitFloat64Compare(this, node, &cont);
}
+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+ return MachineOperatorBuilder::Flag::kNoFlags;
+}
} // namespace compiler
} // namespace internal
} // namespace v8
=======================================
--- /trunk/src/compiler/opcodes.h Thu Oct 23 08:44:45 2014 UTC
+++ /trunk/src/compiler/opcodes.h Mon Oct 27 07:54:22 2014 UTC
@@ -226,6 +226,10 @@
V(Float64Equal) \
V(Float64LessThan) \
V(Float64LessThanOrEqual) \
+ V(Float64Floor) \
+ V(Float64Ceil) \
+ V(Float64RoundTruncate) \
+ V(Float64RoundTiesAway) \
V(LoadStackPointer)
#define VALUE_OP_LIST(V) \
=======================================
--- /trunk/src/compiler/operator-properties-inl.h Thu Oct 23 08:44:45 2014
UTC
+++ /trunk/src/compiler/operator-properties-inl.h Mon Oct 27 07:54:22 2014
UTC
@@ -81,6 +81,9 @@
case IrOpcode::kJSStoreProperty:
case IrOpcode::kJSSubtract:
+ // Conversions
+ case IrOpcode::kJSToObject:
+
// Other
case IrOpcode::kJSDeleteProperty:
return true;
=======================================
--- /trunk/src/compiler/pipeline.cc Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/compiler/pipeline.cc Mon Oct 27 07:54:22 2014 UTC
@@ -178,7 +178,8 @@
// construction. This is currently only needed for the node cache,
which the
// typer could sweep over later.
Typer typer(&graph, info()->context());
- MachineOperatorBuilder machine;
+ MachineOperatorBuilder machine(
+ kMachPtr, InstructionSelector::SupportedMachineOperatorFlags());
CommonOperatorBuilder common(zone());
JSOperatorBuilder javascript(zone());
JSGraph jsgraph(&graph, &common, &javascript, &machine);
=======================================
--- /trunk/src/compiler/schedule.cc Thu Oct 23 08:44:45 2014 UTC
+++ /trunk/src/compiler/schedule.cc Mon Oct 27 07:54:22 2014 UTC
@@ -51,7 +51,6 @@
void BasicBlock::set_control(Control control) {
- DCHECK(control_ == BasicBlock::kNone);
control_ = control;
}
@@ -213,12 +212,42 @@
SetControlInput(block, input);
if (block != end()) AddSuccessor(block, end());
}
+
+
+void Schedule::InsertBranch(BasicBlock* block, BasicBlock* end, Node*
branch,
+ BasicBlock* tblock, BasicBlock* fblock) {
+ DCHECK(block->control() != BasicBlock::kNone);
+ DCHECK(end->control() == BasicBlock::kNone);
+ end->set_control(block->control());
+ block->set_control(BasicBlock::kBranch);
+ MoveSuccessors(block, end);
+ AddSuccessor(block, tblock);
+ AddSuccessor(block, fblock);
+ if (block->control_input() != NULL) {
+ SetControlInput(end, block->control_input());
+ }
+ SetControlInput(block, branch);
+}
void Schedule::AddSuccessor(BasicBlock* block, BasicBlock* succ) {
block->AddSuccessor(succ);
succ->AddPredecessor(block);
}
+
+
+void Schedule::MoveSuccessors(BasicBlock* from, BasicBlock* to) {
+ for (BasicBlock::Predecessors::iterator i = from->successors_begin();
+ i != from->successors_end(); ++i) {
+ BasicBlock* succ = *i;
+ to->AddSuccessor(succ);
+ for (BasicBlock::Predecessors::iterator j = succ->predecessors_begin();
+ j != succ->predecessors_end(); ++j) {
+ if (*j == from) *j = to;
+ }
+ }
+ from->ClearSuccessors();
+}
void Schedule::SetControlInput(BasicBlock* block, Node* node) {
=======================================
--- /trunk/src/compiler/schedule.h Thu Oct 23 08:44:45 2014 UTC
+++ /trunk/src/compiler/schedule.h Mon Oct 27 07:54:22 2014 UTC
@@ -95,6 +95,7 @@
}
size_t PredecessorCount() const { return predecessors_.size(); }
BasicBlock* PredecessorAt(size_t index) { return predecessors_[index]; }
+ void ClearPredecessors() { predecessors_.clear(); }
void AddPredecessor(BasicBlock* predecessor);
typedef ZoneVector<BasicBlock*> Successors;
@@ -108,6 +109,7 @@
}
size_t SuccessorCount() const { return successors_.size(); }
BasicBlock* SuccessorAt(size_t index) { return successors_[index]; }
+ void ClearSuccessors() { successors_.clear(); }
void AddSuccessor(BasicBlock* successor);
// Nodes in the basic block.
@@ -240,7 +242,14 @@
// BasicBlock building: add a throw at the end of {block}.
void AddThrow(BasicBlock* block, Node* input);
- void AddSuccessor(BasicBlock* block, BasicBlock* succ);
+ // BasicBlock mutation: insert a branch into the end of {block}.
+ void InsertBranch(BasicBlock* block, BasicBlock* end, Node* branch,
+ BasicBlock* tblock, BasicBlock* fblock);
+
+ // Exposed publicly for testing only.
+ void AddSuccessorForTesting(BasicBlock* block, BasicBlock* succ) {
+ return AddSuccessor(block, succ);
+ }
BasicBlockVector* rpo_order() { return &rpo_order_; }
const BasicBlockVector* rpo_order() const { return &rpo_order_; }
@@ -256,6 +265,9 @@
friend class ScheduleVisualizer;
friend class BasicBlockInstrumentor;
+ void AddSuccessor(BasicBlock* block, BasicBlock* succ);
+ void MoveSuccessors(BasicBlock* from, BasicBlock* to);
+
void SetControlInput(BasicBlock* block, Node* node);
void SetBlockForNode(BasicBlock* block, Node* node);
=======================================
--- /trunk/src/compiler/scheduler.cc Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/compiler/scheduler.cc Mon Oct 27 07:54:22 2014 UTC
@@ -239,6 +239,7 @@
switch (node->opcode()) {
case IrOpcode::kLoop:
case IrOpcode::kMerge:
+ case IrOpcode::kTerminate:
BuildBlockForNode(node);
break;
case IrOpcode::kBranch:
@@ -561,15 +562,26 @@
BasicBlockVector* final_order = schedule_->rpo_order();
order->Serialize(final_order);
- // Compute the correct loop header for every block and set the correct
loop
- // ends.
+ // Compute the correct loop headers and set the correct loop ends.
LoopInfo* current_loop = NULL;
BasicBlock* current_header = NULL;
int loop_depth = 0;
for (BasicBlockVectorIter i = final_order->begin(); i !=
final_order->end();
++i) {
BasicBlock* current = *i;
+
+ // Finish the previous loop(s) if we just exited them.
+ while (current_header != NULL &&
+ current->rpo_number() >= current_header->loop_end()) {
+ DCHECK(current_header->IsLoopHeader());
+ DCHECK(current_loop != NULL);
+ current_loop = current_loop->prev;
+ current_header = current_loop == NULL ? NULL :
current_loop->header;
+ --loop_depth;
+ }
current->set_loop_header(current_header);
+
+ // Push a new loop onto the stack if this loop is a loop header.
if (current->IsLoopHeader()) {
loop_depth++;
current_loop = &loops[current->loop_end()];
@@ -580,17 +592,10 @@
current_header = current_loop->header;
Trace("B%d is a loop header, increment loop depth to %d\n",
current->id().ToInt(), loop_depth);
- } else {
- while (current_header != NULL &&
- current->rpo_number() >= current_header->loop_end()) {
- DCHECK(current_header->IsLoopHeader());
- DCHECK(current_loop != NULL);
- current_loop = current_loop->prev;
- current_header = current_loop == NULL ? NULL :
current_loop->header;
- --loop_depth;
- }
}
+
current->set_loop_depth(loop_depth);
+
if (current->loop_header() == NULL) {
Trace("B%d is not in a loop (depth == %d)\n",
current->id().ToInt(),
current->loop_depth());
@@ -755,6 +760,12 @@
os << " range: [" << block->rpo_number() << ", " <<
block->loop_end()
<< ")";
}
+ if (block->loop_header() != NULL) {
+ os << " header: B" << block->loop_header()->id();
+ }
+ if (block->loop_depth() > 0) {
+ os << " depth: " << block->loop_depth();
+ }
os << "\n";
}
}
@@ -774,6 +785,7 @@
DCHECK(header->loop_end() >= 0);
DCHECK(header->loop_end() <= static_cast<int>(order->size()));
DCHECK(header->loop_end() > header->rpo_number());
+ DCHECK(header->loop_header() != header);
// Verify the start ... end list relationship.
int links = 0;
@@ -1073,31 +1085,29 @@
// Hoist nodes out of loops if possible. Nodes can be hoisted
iteratively
// into enclosing loop pre-headers until they would preceed their
// ScheduleEarly position.
- BasicBlock* hoist_block = block;
+ BasicBlock* hoist_block = GetPreHeader(block);
while (hoist_block != NULL && hoist_block->rpo_number() >= min_rpo) {
- if (hoist_block->loop_depth() < block->loop_depth()) {
- block = hoist_block;
- Trace(" hoisting #%d:%s to block %d\n", node->id(),
- node->op()->mnemonic(), block->id().ToInt());
- }
- // Try to hoist to the pre-header of the loop header.
- hoist_block = hoist_block->loop_header();
- if (hoist_block != NULL) {
- BasicBlock* pre_header = hoist_block->dominator();
- DCHECK(pre_header == NULL ||
- *hoist_block->predecessors_begin() == pre_header);
- Trace(
- " hoist to pre-header B%d of loop header B%d, depth would
be %d\n",
- pre_header->id().ToInt(), hoist_block->id().ToInt(),
- pre_header->loop_depth());
- hoist_block = pre_header;
- }
+ Trace(" hoisting #%d:%s to block %d\n", node->id(),
+ node->op()->mnemonic(), hoist_block->id().ToInt());
+ DCHECK_LT(hoist_block->loop_depth(), block->loop_depth());
+ block = hoist_block;
+ hoist_block = GetPreHeader(hoist_block);
}
ScheduleNode(block, node);
}
private:
+ BasicBlock* GetPreHeader(BasicBlock* block) {
+ if (block->IsLoopHeader()) {
+ return block->dominator();
+ } else if (block->loop_header() != NULL) {
+ return block->loop_header()->dominator();
+ } else {
+ return NULL;
+ }
+ }
+
BasicBlock* GetCommonDominatorOfUses(Node* node) {
BasicBlock* block = NULL;
Node::Uses uses = node->uses();
=======================================
--- /trunk/src/compiler/simplified-lowering.cc Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/compiler/simplified-lowering.cc Mon Oct 27 07:54:22 2014 UTC
@@ -915,6 +915,10 @@
case IrOpcode::kFloat64Mod:
return VisitFloat64Binop(node);
case IrOpcode::kFloat64Sqrt:
+ case IrOpcode::kFloat64Floor:
+ case IrOpcode::kFloat64Ceil:
+ case IrOpcode::kFloat64RoundTruncate:
+ case IrOpcode::kFloat64RoundTiesAway:
return VisitUnop(node, kMachFloat64, kMachFloat64);
case IrOpcode::kFloat64Equal:
case IrOpcode::kFloat64LessThan:
=======================================
--- /trunk/src/compiler/typer.cc Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/compiler/typer.cc Mon Oct 27 07:54:22 2014 UTC
@@ -1768,6 +1768,30 @@
Bounds Typer::Visitor::TypeFloat64LessThanOrEqual(Node* node) {
return Bounds(Type::Boolean());
}
+
+
+Bounds Typer::Visitor::TypeFloat64Floor(Node* node) {
+ // TODO(sigurds): We could have a tighter bound here.
+ return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64Ceil(Node* node) {
+ // TODO(sigurds): We could have a tighter bound here.
+ return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64RoundTruncate(Node* node) {
+ // TODO(sigurds): We could have a tighter bound here.
+ return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64RoundTiesAway(Node* node) {
+ // TODO(sigurds): We could have a tighter bound here.
+ return Bounds(Type::Number());
+}
Bounds Typer::Visitor::TypeLoadStackPointer(Node* node) {
=======================================
--- /trunk/src/compiler/verifier.cc Thu Oct 23 08:44:45 2014 UTC
+++ /trunk/src/compiler/verifier.cc Mon Oct 27 07:54:22 2014 UTC
@@ -702,6 +702,10 @@
case IrOpcode::kFloat64Div:
case IrOpcode::kFloat64Mod:
case IrOpcode::kFloat64Sqrt:
+ case IrOpcode::kFloat64Floor:
+ case IrOpcode::kFloat64Ceil:
+ case IrOpcode::kFloat64RoundTruncate:
+ case IrOpcode::kFloat64RoundTiesAway:
case IrOpcode::kFloat64Equal:
case IrOpcode::kFloat64LessThan:
case IrOpcode::kFloat64LessThanOrEqual:
=======================================
--- /trunk/src/compiler/x64/instruction-selector-x64.cc Fri Oct 24 14:44:48
2014 UTC
+++ /trunk/src/compiler/x64/instruction-selector-x64.cc Mon Oct 27 07:54:22
2014 UTC
@@ -1108,6 +1108,12 @@
VisitFloat64Compare(this, node, &cont);
}
+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+ return MachineOperatorBuilder::Flag::kNoFlags;
+}
} // namespace compiler
} // namespace internal
} // namespace v8
=======================================
--- /trunk/src/compiler.cc Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/compiler.cc Mon Oct 27 07:54:22 2014 UTC
@@ -414,9 +414,6 @@
compiler::Pipeline pipeline(info());
pipeline.GenerateCode();
if (!info()->code().is_null()) {
- if (FLAG_turbo_deoptimization) {
-
info()->context()->native_context()->AddOptimizedCode(*info()->code());
- }
return SetLastStatus(SUCCEEDED);
}
}
@@ -485,6 +482,9 @@
DCHECK(last_status() == SUCCEEDED);
// TODO(turbofan): Currently everything is done in the first phase.
if (!info()->code().is_null()) {
+ if (FLAG_turbo_deoptimization) {
+
info()->context()->native_context()->AddOptimizedCode(*info()->code());
+ }
RecordOptimizationStats();
return last_status();
}
=======================================
--- /trunk/src/flag-definitions.h Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/flag-definitions.h Mon Oct 27 07:54:22 2014 UTC
@@ -462,7 +462,7 @@
DEFINE_BOOL(trace_stub_failures, false,
"trace deoptimization of generated code stubs")
-DEFINE_BOOL(serialize_toplevel, false, "enable caching of toplevel
scripts")
+DEFINE_BOOL(serialize_toplevel, true, "enable caching of toplevel scripts")
DEFINE_BOOL(trace_code_serializer, false, "print code serializer trace")
// compiler.cc
=======================================
--- /trunk/src/heap/heap.cc Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/heap/heap.cc Mon Oct 27 07:54:22 2014 UTC
@@ -4549,6 +4549,19 @@
UNREACHABLE();
return false;
}
+
+
+bool Heap::RootIsImmortalImmovable(int root_index) {
+ switch (root_index) {
+#define CASE(name) \
+ case Heap::k##name##RootIndex: \
+ return true;
+ IMMORTAL_IMMOVABLE_ROOT_LIST(CASE);
+#undef CASE
+ default:
+ return false;
+ }
+}
#ifdef VERIFY_HEAP
=======================================
--- /trunk/src/heap/heap.h Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/heap/heap.h Mon Oct 27 07:54:22 2014 UTC
@@ -198,58 +198,6 @@
SMI_ROOT_LIST(V) \
V(StringTable, string_table, StringTable)
-// Heap roots that are known to be immortal immovable, for which we can
safely
-// skip write barriers.
-#define IMMORTAL_IMMOVABLE_ROOT_LIST(V) \
- V(byte_array_map) \
- V(free_space_map) \
- V(one_pointer_filler_map) \
- V(two_pointer_filler_map) \
- V(undefined_value) \
- V(the_hole_value) \
- V(null_value) \
- V(true_value) \
- V(false_value) \
- V(uninitialized_value) \
- V(cell_map) \
- V(global_property_cell_map) \
- V(shared_function_info_map) \
- V(meta_map) \
- V(heap_number_map) \
- V(mutable_heap_number_map) \
- V(native_context_map) \
- V(fixed_array_map) \
- V(code_map) \
- V(scope_info_map) \
- V(fixed_cow_array_map) \
- V(fixed_double_array_map) \
- V(constant_pool_array_map) \
- V(weak_cell_map) \
- V(no_interceptor_result_sentinel) \
- V(hash_table_map) \
- V(ordered_hash_table_map) \
- V(empty_fixed_array) \
- V(empty_byte_array) \
- V(empty_descriptor_array) \
- V(empty_constant_pool_array) \
- V(arguments_marker) \
- V(symbol_map) \
- V(sloppy_arguments_elements_map) \
- V(function_context_map) \
- V(catch_context_map) \
- V(with_context_map) \
- V(block_context_map) \
- V(module_context_map) \
- V(global_context_map) \
- V(undefined_map) \
- V(the_hole_map) \
- V(null_map) \
- V(boolean_map) \
- V(uninitialized_map) \
- V(message_object_map) \
- V(foreign_map) \
- V(neander_map)
-
#define INTERNALIZED_STRING_LIST(V) \
V(Object_string, "Object") \
V(proto_string, "__proto__") \
@@ -351,6 +299,60 @@
V(class_start_position_symbol) \
V(class_end_position_symbol)
+// Heap roots that are known to be immortal immovable, for which we can
safely
+// skip write barriers. This list is not complete and has omissions.
+#define IMMORTAL_IMMOVABLE_ROOT_LIST(V) \
+ V(ByteArrayMap) \
+ V(FreeSpaceMap) \
+ V(OnePointerFillerMap) \
+ V(TwoPointerFillerMap) \
+ V(UndefinedValue) \
+ V(TheHoleValue) \
+ V(NullValue) \
+ V(TrueValue) \
+ V(FalseValue) \
+ V(UninitializedValue) \
+ V(CellMap) \
+ V(GlobalPropertyCellMap) \
+ V(SharedFunctionInfoMap) \
+ V(MetaMap) \
+ V(HeapNumberMap) \
+ V(MutableHeapNumberMap) \
+ V(NativeContextMap) \
+ V(FixedArrayMap) \
+ V(CodeMap) \
+ V(ScopeInfoMap) \
+ V(FixedCOWArrayMap) \
+ V(FixedDoubleArrayMap) \
+ V(ConstantPoolArrayMap) \
+ V(WeakCellMap) \
+ V(NoInterceptorResultSentinel) \
+ V(HashTableMap) \
+ V(OrderedHashTableMap) \
+ V(EmptyFixedArray) \
+ V(EmptyByteArray) \
+ V(EmptyDescriptorArray) \
+ V(EmptyConstantPoolArray) \
+ V(ArgumentsMarker) \
+ V(SymbolMap) \
+ V(SloppyArgumentsElementsMap) \
+ V(FunctionContextMap) \
+ V(CatchContextMap) \
+ V(WithContextMap) \
+ V(BlockContextMap) \
+ V(ModuleContextMap) \
+ V(GlobalContextMap) \
+ V(UndefinedMap) \
+ V(TheHoleMap) \
+ V(NullMap) \
+ V(BooleanMap) \
+ V(UninitializedMap) \
+ V(ArgumentsMarkerMap) \
+ V(JSMessageObjectMap) \
+ V(ForeignMap) \
+ V(NeanderMap) \
+ PRIVATE_SYMBOL_LIST(V)
+
// Forward declarations.
class HeapStats;
class Isolate;
@@ -927,6 +929,8 @@
Address* store_buffer_top_address() {
return reinterpret_cast<Address*>(&roots_[kStoreBufferTopRootIndex]);
}
+
+ static bool RootIsImmortalImmovable(int root_index);
#ifdef VERIFY_HEAP
// Verify the heap is in its normal state before or after a GC.
@@ -1115,6 +1119,8 @@
kStrongRootListLength = kStringTableRootIndex,
kSmiRootsStart = kStringTableRootIndex + 1
};
+
+ Object* root(RootListIndex index) { return roots_[index]; }
STATIC_ASSERT(kUndefinedValueRootIndex ==
Internals::kUndefinedValueRootIndex);
=======================================
--- /trunk/src/heap-snapshot-generator.cc Thu Oct 2 00:05:29 2014 UTC
+++ /trunk/src/heap-snapshot-generator.cc Mon Oct 27 07:54:22 2014 UTC
@@ -1711,11 +1711,11 @@
AccessorPair* accessors = AccessorPair::cast(callback_obj);
Object* getter = accessors->getter();
if (!getter->IsOddball()) {
- SetPropertyReference(js_obj, entry, String::cast(key),
getter, "get %s");
+ SetPropertyReference(js_obj, entry, Name::cast(key), getter, "get %s");
}
Object* setter = accessors->setter();
if (!setter->IsOddball()) {
- SetPropertyReference(js_obj, entry, String::cast(key),
setter, "set %s");
+ SetPropertyReference(js_obj, entry, Name::cast(key), setter, "set %s");
}
return true;
}
=======================================
--- /trunk/src/hydrogen-instructions.cc Fri Oct 3 00:04:58 2014 UTC
+++ /trunk/src/hydrogen-instructions.cc Mon Oct 27 07:54:22 2014 UTC
@@ -2862,7 +2862,7 @@
DCHECK(!object_.IsKnownGlobal(heap->nan_value()));
return
#define IMMORTAL_IMMOVABLE_ROOT(name) \
- object_.IsKnownGlobal(heap->name()) ||
+ object_.IsKnownGlobal(heap->root(Heap::k##name##RootIndex)) ||
IMMORTAL_IMMOVABLE_ROOT_LIST(IMMORTAL_IMMOVABLE_ROOT)
#undef IMMORTAL_IMMOVABLE_ROOT
#define INTERNALIZED_STRING(name, value) \
@@ -2873,9 +2873,6 @@
object_.IsKnownGlobal(heap->name##_map()) ||
STRING_TYPE_LIST(STRING_TYPE)
#undef STRING_TYPE
-#define SYMBOL(name) object_.IsKnownGlobal(heap->name()) ||
- PRIVATE_SYMBOL_LIST(SYMBOL)
-#undef SYMBOL
false;
}
=======================================
***Additional files exist in this changeset.***
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.