static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
- Condition cond, bool strong);
+ Condition cond, Strength strength);
static void EmitSmiNonsmiComparison(MacroAssembler* masm,
Register lhs,
Register rhs,
// Equality is almost reflexive (everything but NaN), so this is a test
// for "identity and not NaN".
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
- Condition cond, bool strong) {
+ Condition cond, Strength strength) {
Label not_identical;
Label heap_number, return_equal;
__ cmp(r0, r1);
// Call runtime on identical symbols since we need to throw a TypeError.
__ cmp(r4, Operand(SYMBOL_TYPE));
__ b(eq, slow);
- if (strong) {
+ if (is_strong(strength)) {
// Call the runtime on anything that is converted in the semantics, since
// we need to throw a TypeError. Smis have already been ruled out.
__ cmp(r4, Operand(HEAP_NUMBER_TYPE));
// Call runtime on identical symbols since we need to throw a TypeError.
__ cmp(r4, Operand(SYMBOL_TYPE));
__ b(eq, slow);
- if (strong) {
+ if (is_strong(strength)) {
// Call the runtime on anything that is converted in the semantics,
// since we need to throw a TypeError. Smis and heap numbers have
// already been ruled out.
// Handle the case where the objects are identical. Either returns the answer
// or goes to slow. Only falls through if the objects were not identical.
- EmitIdenticalObjectComparison(masm, &slow, cc, strong());
+ EmitIdenticalObjectComparison(masm, &slow, cc, strength());
// If either is a Smi (we know that not both are), then they can only
// be strictly equal if the other is a HeapNumber.
if (cc == eq) {
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
} else {
- native = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
+ native =
+ is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
int ncr; // NaN compare result
if (cc == lt || cc == le) {
ncr = GREATER;
__ bind(&unordered);
__ bind(&generic_stub);
- CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
+ CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
CompareICState::GENERIC, CompareICState::GENERIC);
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
- language_mode()).code();
+ strength(language_mode())).code();
CallIC(ic, clause->CompareId());
patch_site.EmitPatchInfo();
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
__ bind(&stub_call);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done);
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ pop(r1);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
// Record position before stub call.
SetSourcePosition(expr->position());
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), Token::ADD, language_mode()).code();
+ Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD,
+ strength(language_mode())).code();
CallIC(code, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
// Record position and call the compare IC.
SetSourcePosition(expr->position());
- Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, language_mode()).code();
+ Handle<Code> ic = CodeFactory::CompareIC(
+ isolate(), op, strength(language_mode())).code();
CallIC(ic, expr->CompareOperationFeedbackId());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
- LanguageMode language_mode() { return hydrogen()->language_mode(); }
+ Strength strength() { return hydrogen()->strength(); }
Token::Value op() const { return hydrogen()->token(); }
};
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
- LanguageMode language_mode() { return hydrogen()->language_mode(); }
+ Strength strength() { return hydrogen()->strength(); }
private:
Token::Value op_;
DCHECK(ToRegister(instr->right()).is(r0));
DCHECK(ToRegister(instr->result()).is(r0));
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), instr->op(), instr->language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
// Block literal pool emission to ensure nop indicating no inlined smi code
// is in the correct position.
Assembler::BlockConstPoolScope block_const_pool(masm());
DCHECK(ToRegister(instr->context()).is(cp));
Token::Value op = instr->op();
- Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
+ Handle<Code> ic =
+ CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
// This instruction also signals no smi code inlined.
__ cmp(r0, Operand::Zero());
Token::Value op = instr->op();
Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
+ CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
// This instruction also signals no smi code inlined.
__ cmp(r0, Operand::Zero());
Register right, Register scratch,
FPRegister double_scratch,
Label* slow, Condition cond,
- bool strong) {
+ Strength strength) {
DCHECK(!AreAliased(left, right, scratch));
Label not_identical, return_equal, heap_number;
Register result = x0;
// Call runtime on identical symbols since we need to throw a TypeError.
__ Cmp(right_type, SYMBOL_TYPE);
__ B(eq, slow);
- if (strong) {
+ if (is_strong(strength)) {
// Call the runtime on anything that is converted in the semantics, since
// we need to throw a TypeError. Smis have already been ruled out.
__ Cmp(right_type, Operand(HEAP_NUMBER_TYPE));
// Call runtime on identical symbols since we need to throw a TypeError.
__ Cmp(right_type, SYMBOL_TYPE);
__ B(eq, slow);
- if (strong) {
+ if (is_strong(strength)) {
// Call the runtime on anything that is converted in the semantics,
// since we need to throw a TypeError. Smis and heap numbers have
// already been ruled out.
// Handle the case where the objects are identical. Either returns the answer
// or goes to slow. Only falls through if the objects were not identical.
- EmitIdenticalObjectComparison(masm, lhs, rhs, x10, d0, &slow, cond, strong());
+ EmitIdenticalObjectComparison(masm, lhs, rhs, x10, d0, &slow, cond,
+ strength());
// If either is a smi (we know that at least one is not a smi), then they can
// only be strictly equal if the other is a HeapNumber.
if (cond == eq) {
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
} else {
- native = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
+ native =
+ is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
int ncr; // NaN compare result
if ((cond == lt) || (cond == le)) {
ncr = GREATER;
__ Ret();
__ Bind(&unordered);
- CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
+ CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
CompareICState::GENERIC, CompareICState::GENERIC);
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
- language_mode()).code();
+ strength(language_mode())).code();
CallIC(ic, clause->CompareId());
patch_site.EmitPatchInfo();
__ Bind(&stub_call);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
{
Assembler::BlockPoolsScope scope(masm_);
CallIC(code, expr->BinaryOperationFeedbackId());
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ Pop(x1);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code.
{
Assembler::BlockPoolsScope scope(masm_);
{
Assembler::BlockPoolsScope scope(masm_);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), Token::ADD, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), Token::ADD,
+ strength(language_mode())).code();
CallIC(code, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
}
// Record position and call the compare IC.
SetSourcePosition(expr->position());
- Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, language_mode()).code();
+ Handle<Code> ic = CodeFactory::CompareIC(
+ isolate(), op, strength(language_mode())).code();
CallIC(ic, expr->CompareOperationFeedbackId());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
- LanguageMode language_mode() { return hydrogen()->language_mode(); }
+ Strength strength() { return hydrogen()->strength(); }
private:
Token::Value op_;
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
- LanguageMode language_mode() { return hydrogen()->language_mode(); }
+ Strength strength() { return hydrogen()->strength(); }
Token::Value op() const { return hydrogen()->token(); }
};
DCHECK(ToRegister(instr->right()).is(x0));
DCHECK(ToRegister(instr->result()).is(x0));
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), instr->op(), instr->language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
CallCode(code, RelocInfo::CODE_TARGET, instr);
}
DCHECK(ToRegister(instr->left()).Is(x1));
DCHECK(ToRegister(instr->right()).Is(x0));
Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
+ CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
// Signal that we don't inline smi code before this stub.
InlineSmiCheckInfo::EmitNotInlined(masm());
DCHECK(ToRegister(instr->context()).is(cp));
Token::Value op = instr->op();
- Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
+ Handle<Code> ic =
+ CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
InlineSmiCheckInfo::EmitNotInlined(masm());
has_double && IsFastObjectElementsKind(elements_kind)
? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE : DONT_INITIALIZE_ARRAY_ELEMENTS;
Handle<JSArray> result_array = isolate->factory()->NewJSArray(
- elements_kind, result_len, result_len, WEAK, mode);
+ elements_kind, result_len, result_len, Strength::WEAK, mode);
if (result_len == 0) return *result_array;
int j = 0;
// static
Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op,
- LanguageMode language_mode) {
- Handle<Code> code =
- CompareIC::GetUninitialized(isolate, op, is_strong(language_mode));
+ Strength strength) {
+ Handle<Code> code = CompareIC::GetUninitialized(isolate, op, strength);
return Callable(code, CompareDescriptor(isolate));
}
// static
Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op,
- LanguageMode language_mode) {
- BinaryOpICStub stub(isolate, op, language_mode);
+ Strength strength) {
+ BinaryOpICStub stub(isolate, op, strength);
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
}
InlineCacheState initialization_state);
static Callable CompareIC(Isolate* isolate, Token::Value op,
- LanguageMode language_mode);
+ Strength strength);
static Callable BinaryOpIC(Isolate* isolate, Token::Value op,
- LanguageMode language_mode);
+ Strength strength);
// Code stubs. Add methods here as needed to reduce dependency on
// code-stubs.h.
if_leftisstring.If<HIsStringAndBranch>(left);
if_leftisstring.Then();
{
- Push(BuildBinaryOperation(
- state.op(), left, right,
- Type::String(zone()), right_type,
- result_type, state.fixed_right_arg(),
- allocation_mode, state.language_mode()));
+ Push(BuildBinaryOperation(state.op(), left, right, Type::String(zone()),
+ right_type, result_type,
+ state.fixed_right_arg(), allocation_mode,
+ state.strength()));
}
if_leftisstring.Else();
{
Push(BuildBinaryOperation(
- state.op(), left, right,
- left_type, right_type, result_type,
- state.fixed_right_arg(), allocation_mode,
- state.language_mode()));
+ state.op(), left, right, left_type, right_type, result_type,
+ state.fixed_right_arg(), allocation_mode, state.strength()));
}
if_leftisstring.End();
result = Pop();
if_rightisstring.If<HIsStringAndBranch>(right);
if_rightisstring.Then();
{
- Push(BuildBinaryOperation(
- state.op(), left, right,
- left_type, Type::String(zone()),
- result_type, state.fixed_right_arg(),
- allocation_mode, state.language_mode()));
+ Push(BuildBinaryOperation(state.op(), left, right, left_type,
+ Type::String(zone()), result_type,
+ state.fixed_right_arg(), allocation_mode,
+ state.strength()));
}
if_rightisstring.Else();
{
Push(BuildBinaryOperation(
- state.op(), left, right,
- left_type, right_type, result_type,
- state.fixed_right_arg(), allocation_mode,
- state.language_mode()));
+ state.op(), left, right, left_type, right_type, result_type,
+ state.fixed_right_arg(), allocation_mode, state.strength()));
}
if_rightisstring.End();
result = Pop();
}
} else {
result = BuildBinaryOperation(
- state.op(), left, right,
- left_type, right_type, result_type,
- state.fixed_right_arg(), allocation_mode, state.language_mode());
+ state.op(), left, right, left_type, right_type, result_type,
+ state.fixed_right_arg(), allocation_mode, state.strength());
}
// If we encounter a generic argument, the number conversion is
Type* result_type = state.GetResultType(zone());
HAllocationMode allocation_mode(allocation_site);
- return BuildBinaryOperation(state.op(), left, right,
- left_type, right_type, result_type,
- state.fixed_right_arg(), allocation_mode,
- state.language_mode());
+ return BuildBinaryOperation(state.op(), left, right, left_type, right_type,
+ result_type, state.fixed_right_arg(),
+ allocation_mode, state.strength());
}
void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate) {
// Generate the uninitialized versions of the stub.
for (int op = Token::BIT_OR; op <= Token::MOD; ++op) {
- BinaryOpICStub stub(isolate, static_cast<Token::Value>(op),
- LanguageMode::SLOPPY);
+ BinaryOpICStub stub(isolate, static_cast<Token::Value>(op), Strength::WEAK);
stub.GetCode();
}
class BinaryOpICStub : public HydrogenCodeStub {
public:
- BinaryOpICStub(Isolate* isolate, Token::Value op, LanguageMode language_mode)
+ BinaryOpICStub(Isolate* isolate, Token::Value op, Strength strength)
: HydrogenCodeStub(isolate, UNINITIALIZED) {
- BinaryOpICState state(isolate, op, language_mode);
+ BinaryOpICState state(isolate, op, strength);
set_sub_minor_key(state.GetExtraICState());
}
class BinaryOpWithAllocationSiteStub final : public BinaryOpICStub {
public:
BinaryOpWithAllocationSiteStub(Isolate* isolate, Token::Value op,
- LanguageMode language_mode)
- : BinaryOpICStub(isolate, op, language_mode) {}
+ Strength strength)
+ : BinaryOpICStub(isolate, op, strength) {}
BinaryOpWithAllocationSiteStub(Isolate* isolate, const BinaryOpICState& state)
: BinaryOpICStub(isolate, state) {}
class CompareICStub : public PlatformCodeStub {
public:
- CompareICStub(Isolate* isolate, Token::Value op, bool strong,
+ CompareICStub(Isolate* isolate, Token::Value op, Strength strength,
CompareICState::State left, CompareICState::State right,
CompareICState::State state)
: PlatformCodeStub(isolate) {
DCHECK(Token::IsCompareOp(op));
- minor_key_ = OpBits::encode(op - Token::EQ) | StrongBits::encode(strong) |
+ minor_key_ = OpBits::encode(op - Token::EQ) |
+ StrengthBits::encode(is_strong(strength)) |
LeftStateBits::encode(left) | RightStateBits::encode(right) |
StateBits::encode(state);
}
return static_cast<Token::Value>(Token::EQ + OpBits::decode(minor_key_));
}
- bool strong() const { return StrongBits::decode(minor_key_); }
+ Strength strength() const {
+ return StrengthBits::decode(minor_key_) ? Strength::STRONG : Strength::WEAK;
+ }
CompareICState::State left() const {
return LeftStateBits::decode(minor_key_);
}
class OpBits : public BitField<int, 0, 3> {};
- class StrongBits : public BitField<bool, 3, 1> {};
+ class StrengthBits : public BitField<bool, 3, 1> {};
class LeftStateBits : public BitField<CompareICState::State, 4, 4> {};
class RightStateBits : public BitField<CompareICState::State, 8, 4> {};
class StateBits : public BitField<CompareICState::State, 12, 4> {};
}
-#define REPLACE_BINARY_OP_IC_CALL(op, token) \
- void JSGenericLowering::Lower##op(Node* node) { \
- CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); \
- ReplaceWithStubCall( \
- node, CodeFactory::BinaryOpIC(isolate(), token, \
- OpParameter<LanguageMode>(node)), \
- CallDescriptor::kPatchableCallSiteWithNop | flags); \
+#define REPLACE_BINARY_OP_IC_CALL(op, token) \
+ void JSGenericLowering::Lower##op(Node* node) { \
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); \
+ ReplaceWithStubCall(node, CodeFactory::BinaryOpIC( \
+ isolate(), token, \
+ strength(OpParameter<LanguageMode>(node))), \
+ CallDescriptor::kPatchableCallSiteWithNop | flags); \
}
REPLACE_BINARY_OP_IC_CALL(JSBitwiseOr, Token::BIT_OR)
REPLACE_BINARY_OP_IC_CALL(JSBitwiseXor, Token::BIT_XOR)
void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) {
- Callable callable =
- CodeFactory::CompareIC(isolate(), token, OpParameter<LanguageMode>(node));
+ Callable callable = CodeFactory::CompareIC(
+ isolate(), token, strength(OpParameter<LanguageMode>(node)));
// Create a new call node asking a CompareIC for help.
NodeVector inputs(zone());
Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind,
- ObjectStrength strength,
+ Strength strength,
PretenureFlag pretenure) {
Map* map = isolate()->get_initial_js_array_map(elements_kind, strength);
if (map == nullptr) {
- DCHECK(strength == WEAK);
+ DCHECK(strength == Strength::WEAK);
Context* native_context = isolate()->context()->native_context();
JSFunction* array_function = native_context->array_function();
map = array_function->initial_map();
Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind, int length,
- int capacity, ObjectStrength strength,
+ int capacity, Strength strength,
ArrayStorageAllocationMode mode,
PretenureFlag pretenure) {
Handle<JSArray> array = NewJSArray(elements_kind, strength, pretenure);
Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements,
ElementsKind elements_kind,
- int length,
- ObjectStrength strength,
+ int length, Strength strength,
PretenureFlag pretenure) {
DCHECK(length <= elements->length());
Handle<JSArray> array = NewJSArray(elements_kind, strength, pretenure);
// JS arrays are pretenured when allocated by the parser.
// Create a JSArray with no elements.
- Handle<JSArray> NewJSArray(
- ElementsKind elements_kind,
- ObjectStrength strength = WEAK,
- PretenureFlag pretenure = NOT_TENURED);
+ Handle<JSArray> NewJSArray(ElementsKind elements_kind,
+ Strength strength = Strength::WEAK,
+ PretenureFlag pretenure = NOT_TENURED);
// Create a JSArray with a specified length and elements initialized
// according to the specified mode.
Handle<JSArray> NewJSArray(
ElementsKind elements_kind, int length, int capacity,
- ObjectStrength strength = WEAK,
+ Strength strength = Strength::WEAK,
ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS,
PretenureFlag pretenure = NOT_TENURED);
Handle<JSArray> NewJSArray(
- int capacity,
- ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
- ObjectStrength strength = WEAK,
+ int capacity, ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
+ Strength strength = Strength::WEAK,
PretenureFlag pretenure = NOT_TENURED) {
if (capacity != 0) {
elements_kind = GetHoleyElementsKind(elements_kind);
}
// Create a JSArray with the given elements.
- Handle<JSArray> NewJSArrayWithElements(
- Handle<FixedArrayBase> elements,
- ElementsKind elements_kind,
- int length,
- ObjectStrength strength = WEAK,
- PretenureFlag pretenure = NOT_TENURED);
+ Handle<JSArray> NewJSArrayWithElements(Handle<FixedArrayBase> elements,
+ ElementsKind elements_kind, int length,
+ Strength strength = Strength::WEAK,
+ PretenureFlag pretenure = NOT_TENURED);
Handle<JSArray> NewJSArrayWithElements(
Handle<FixedArrayBase> elements,
ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
- ObjectStrength strength = WEAK,
+ Strength strength = Strength::WEAK,
PretenureFlag pretenure = NOT_TENURED) {
return NewJSArrayWithElements(elements, elements_kind, elements->length(),
strength, pretenure);
// -----------------------------------------------------------------------------
// Declarations for use in both the preparser and the rest of V8.
-enum ObjectStrength {
- WEAK,
- FIRM // strong object
-};
-
// The Strict Mode (ECMA-262 5th edition, 4.2.2).
enum LanguageMode {
}
-inline ObjectStrength strength(LanguageMode language_mode) {
- return is_strong(language_mode) ? FIRM : WEAK;
+// Strong mode behaviour must sometimes be signalled by a two valued enum where
+// caching is involved, to prevent sloppy and strict mode from being incorrectly
+// differentiated.
+enum class Strength : bool {
+ WEAK, // sloppy, strict behaviour
+ STRONG // strong behaviour
+};
+
+
+inline bool is_strong(Strength strength) {
+ return strength == Strength::STRONG;
+}
+
+
+inline std::ostream& operator<<(std::ostream& os, const Strength& strength) {
+ return os << (is_strong(strength) ? "strong" : "weak");
+}
+
+
+inline Strength strength(LanguageMode language_mode) {
+ return is_strong(language_mode) ? Strength::STRONG : Strength::WEAK;
+}
+
+
+inline size_t hash_value(Strength strength) {
+ return static_cast<size_t>(strength);
}
#define H_CONSTANT_DOUBLE(val) \
HConstant::New(isolate, zone, context, static_cast<double>(val))
-#define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \
- HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context, \
- HValue* left, HValue* right, \
- LanguageMode language_mode) { \
- if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \
- HConstant* c_left = HConstant::cast(left); \
- HConstant* c_right = HConstant::cast(right); \
- if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \
- double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \
- if (IsInt32Double(double_res)) { \
- return H_CONSTANT_INT(double_res); \
- } \
- return H_CONSTANT_DOUBLE(double_res); \
- } \
- } \
- return new (zone) HInstr(context, left, right, language_mode); \
+#define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \
+ HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context, \
+ HValue* left, HValue* right, Strength strength) { \
+ if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \
+ HConstant* c_left = HConstant::cast(left); \
+ HConstant* c_right = HConstant::cast(right); \
+ if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \
+ double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \
+ if (IsInt32Double(double_res)) { \
+ return H_CONSTANT_INT(double_res); \
+ } \
+ return H_CONSTANT_DOUBLE(double_res); \
+ } \
+ } \
+ return new (zone) HInstr(context, left, right, strength); \
}
HInstruction* HStringAdd::New(Isolate* isolate, Zone* zone, HValue* context,
- HValue* left, HValue* right,
- LanguageMode language_mode,
+ HValue* left, HValue* right, Strength strength,
PretenureFlag pretenure_flag,
StringAddFlags flags,
Handle<AllocationSite> allocation_site) {
}
}
}
- return new(zone) HStringAdd(
- context, left, right, language_mode, pretenure_flag, flags,
- allocation_site);
+ return new (zone) HStringAdd(context, left, right, strength, pretenure_flag,
+ flags, allocation_site);
}
HInstruction* HMod::New(Isolate* isolate, Zone* zone, HValue* context,
- HValue* left, HValue* right,
- LanguageMode language_mode) {
+ HValue* left, HValue* right, Strength strength) {
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
HConstant* c_left = HConstant::cast(left);
HConstant* c_right = HConstant::cast(right);
}
}
}
- return new(zone) HMod(context, left, right, language_mode);
+ return new (zone) HMod(context, left, right, strength);
}
HInstruction* HDiv::New(Isolate* isolate, Zone* zone, HValue* context,
- HValue* left, HValue* right,
- LanguageMode language_mode) {
+ HValue* left, HValue* right, Strength strength) {
// If left and right are constant values, try to return a constant value.
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
HConstant* c_left = HConstant::cast(left);
}
}
}
- return new(zone) HDiv(context, left, right, language_mode);
+ return new (zone) HDiv(context, left, right, strength);
}
HInstruction* HBitwise::New(Isolate* isolate, Zone* zone, HValue* context,
Token::Value op, HValue* left, HValue* right,
- LanguageMode language_mode) {
+ Strength strength) {
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
HConstant* c_left = HConstant::cast(left);
HConstant* c_right = HConstant::cast(right);
return H_CONSTANT_INT(result);
}
}
- return new(zone) HBitwise(context, op, left, right, language_mode);
+ return new (zone) HBitwise(context, op, left, right, strength);
}
-#define DEFINE_NEW_H_BITWISE_INSTR(HInstr, result) \
- HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context, \
- HValue* left, HValue* right, \
- LanguageMode language_mode) { \
- if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \
- HConstant* c_left = HConstant::cast(left); \
- HConstant* c_right = HConstant::cast(right); \
- if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \
- return H_CONSTANT_INT(result); \
- } \
- } \
- return new (zone) HInstr(context, left, right, language_mode); \
+#define DEFINE_NEW_H_BITWISE_INSTR(HInstr, result) \
+ HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context, \
+ HValue* left, HValue* right, Strength strength) { \
+ if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \
+ HConstant* c_left = HConstant::cast(left); \
+ HConstant* c_right = HConstant::cast(right); \
+ if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \
+ return H_CONSTANT_INT(result); \
+ } \
+ } \
+ return new (zone) HInstr(context, left, right, strength); \
}
HInstruction* HShr::New(Isolate* isolate, Zone* zone, HValue* context,
- HValue* left, HValue* right,
- LanguageMode language_mode) {
+ HValue* left, HValue* right, Strength strength) {
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
HConstant* c_left = HConstant::cast(left);
HConstant* c_right = HConstant::cast(right);
return H_CONSTANT_INT(static_cast<uint32_t>(left_val) >> right_val);
}
}
- return new(zone) HShr(context, left, right, language_mode);
+ return new (zone) HShr(context, left, right, strength);
}
class HBinaryOperation : public HTemplateInstruction<3> {
public:
HBinaryOperation(HValue* context, HValue* left, HValue* right,
- LanguageMode language_mode, HType type = HType::Tagged())
- : HTemplateInstruction<3>(type), language_mode_(language_mode),
+ Strength strength, HType type = HType::Tagged())
+ : HTemplateInstruction<3>(type),
+ strength_(strength),
observed_output_representation_(Representation::None()) {
DCHECK(left != NULL && right != NULL);
SetOperandAt(0, context);
HValue* context() const { return OperandAt(0); }
HValue* left() const { return OperandAt(1); }
HValue* right() const { return OperandAt(2); }
- LanguageMode language_mode() const { return language_mode_; }
+ Strength strength() const { return strength_; }
// True if switching left and right operands likely generates better code.
bool AreOperandsBetterSwitched() {
return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(value));
}
- LanguageMode language_mode() {
- return language_mode_;
- }
+ Strength strength() { return strength_; }
DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
private:
bool IgnoreObservedOutputRepresentation(Representation current_rep);
- LanguageMode language_mode_;
+ Strength strength_;
Representation observed_input_representation_[2];
Representation observed_output_representation_;
class HBitwiseBinaryOperation : public HBinaryOperation {
public:
HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right,
- LanguageMode language_mode,
- HType type = HType::TaggedNumber())
- : HBinaryOperation(context, left, right, language_mode, type) {
+ Strength strength, HType type = HType::TaggedNumber())
+ : HBinaryOperation(context, left, right, strength, type) {
SetFlag(kFlexibleRepresentation);
SetFlag(kTruncatingToInt32);
SetFlag(kAllowUndefinedAsNaN);
private:
HMathFloorOfDiv(HValue* context, HValue* left, HValue* right)
- : HBinaryOperation(context, left, right, SLOPPY) {
+ : HBinaryOperation(context, left, right, Strength::WEAK) {
set_representation(Representation::Integer32());
SetFlag(kUseGVN);
SetFlag(kCanOverflow);
class HArithmeticBinaryOperation : public HBinaryOperation {
public:
HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right,
- LanguageMode language_mode)
- : HBinaryOperation(context, left, right, language_mode,
+ Strength strength)
+ : HBinaryOperation(context, left, right, strength,
HType::TaggedNumber()) {
SetAllSideEffects();
SetFlag(kFlexibleRepresentation);
class HCompareGeneric final : public HBinaryOperation {
public:
static HCompareGeneric* New(Isolate* isolate, Zone* zone, HValue* context,
- HValue* left, HValue* right, Token::Value token,
- LanguageMode language_mode = SLOPPY) {
- return new(zone) HCompareGeneric(context, left, right, token,
- language_mode);
+ HValue* left, HValue* right, Token::Value token,
+ Strength strength = Strength::WEAK) {
+ return new (zone) HCompareGeneric(context, left, right, token, strength);
}
Representation RequiredInputRepresentation(int index) override {
DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
private:
- HCompareGeneric(HValue* context,
- HValue* left,
- HValue* right,
- Token::Value token,
- LanguageMode language_mode)
- : HBinaryOperation(context, left, right, language_mode, HType::Boolean()),
+ HCompareGeneric(HValue* context, HValue* left, HValue* right,
+ Token::Value token, Strength strength)
+ : HBinaryOperation(context, left, right, strength, HType::Boolean()),
token_(token) {
DCHECK(Token::IsCompareOp(token));
set_representation(Representation::Tagged());
private:
HInstanceOf(HValue* context, HValue* left, HValue* right)
- : HBinaryOperation(context, left, right, SLOPPY, HType::Boolean()) {
+ : HBinaryOperation(context, left, right, Strength::WEAK,
+ HType::Boolean()) {
set_representation(Representation::Tagged());
SetAllSideEffects();
}
public:
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
HValue* left, HValue* right,
- LanguageMode language_mode = SLOPPY);
+ Strength strength = Strength::WEAK);
// Add is only commutative if two integer values are added and not if two
// tagged values are added (because it might be a String concatenation).
Range* InferRange(Zone* zone) override;
private:
- HAdd(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
- : HArithmeticBinaryOperation(context, left, right, language_mode) {
+ HAdd(HValue* context, HValue* left, HValue* right, Strength strength)
+ : HArithmeticBinaryOperation(context, left, right, strength) {
SetFlag(kCanOverflow);
}
};
public:
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
HValue* left, HValue* right,
- LanguageMode language_mode = SLOPPY);
+ Strength strength = Strength::WEAK);
HValue* Canonicalize() override;
Range* InferRange(Zone* zone) override;
private:
- HSub(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
- : HArithmeticBinaryOperation(context, left, right, language_mode) {
+ HSub(HValue* context, HValue* left, HValue* right, Strength strength)
+ : HArithmeticBinaryOperation(context, left, right, strength) {
SetFlag(kCanOverflow);
}
};
public:
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
HValue* left, HValue* right,
- LanguageMode language_mode = SLOPPY);
+ Strength strength = Strength::WEAK);
static HInstruction* NewImul(Isolate* isolate, Zone* zone, HValue* context,
HValue* left, HValue* right,
- LanguageMode language_mode = SLOPPY) {
- HInstruction* instr = HMul::New(isolate, zone, context, left, right,
- language_mode);
+ Strength strength = Strength::WEAK) {
+ HInstruction* instr =
+ HMul::New(isolate, zone, context, left, right, strength);
if (!instr->IsMul()) return instr;
HMul* mul = HMul::cast(instr);
// TODO(mstarzinger): Prevent bailout on minus zero for imul.
Range* InferRange(Zone* zone) override;
private:
- HMul(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
- : HArithmeticBinaryOperation(context, left, right, language_mode) {
+ HMul(HValue* context, HValue* left, HValue* right, Strength strength)
+ : HArithmeticBinaryOperation(context, left, right, strength) {
SetFlag(kCanOverflow);
}
};
public:
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
HValue* left, HValue* right,
- LanguageMode language_mode = SLOPPY);
+ Strength strength = Strength::WEAK);
HValue* Canonicalize() override;
Range* InferRange(Zone* zone) override;
private:
- HMod(HValue* context,
- HValue* left,
- HValue* right,
- LanguageMode language_mode) : HArithmeticBinaryOperation(context, left,
- right,
- language_mode) {
+ HMod(HValue* context, HValue* left, HValue* right, Strength strength)
+ : HArithmeticBinaryOperation(context, left, right, strength) {
SetFlag(kCanBeDivByZero);
SetFlag(kCanOverflow);
SetFlag(kLeftCanBeNegative);
public:
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
HValue* left, HValue* right,
- LanguageMode language_mode = SLOPPY);
+ Strength strength = Strength::WEAK);
HValue* Canonicalize() override;
Range* InferRange(Zone* zone) override;
private:
- HDiv(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
- : HArithmeticBinaryOperation(context, left, right, language_mode) {
+ HDiv(HValue* context, HValue* left, HValue* right, Strength strength)
+ : HArithmeticBinaryOperation(context, left, right, strength) {
SetFlag(kCanBeDivByZero);
SetFlag(kCanOverflow);
}
private:
HMathMinMax(HValue* context, HValue* left, HValue* right, Operation op)
- : HArithmeticBinaryOperation(context, left, right, SLOPPY),
- operation_(op) { }
+ : HArithmeticBinaryOperation(context, left, right, Strength::WEAK),
+ operation_(op) {}
Operation operation_;
};
public:
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
Token::Value op, HValue* left, HValue* right,
- LanguageMode language_mode = SLOPPY);
+ Strength strength = Strength::WEAK);
Token::Value op() const { return op_; }
Range* InferRange(Zone* zone) override;
private:
- HBitwise(HValue* context,
- Token::Value op,
- HValue* left,
- HValue* right,
- LanguageMode language_mode)
- : HBitwiseBinaryOperation(context, left, right, language_mode),
- op_(op) {
+ HBitwise(HValue* context, Token::Value op, HValue* left, HValue* right,
+ Strength strength)
+ : HBitwiseBinaryOperation(context, left, right, strength), op_(op) {
DCHECK(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR);
// BIT_AND with a smi-range positive value will always unset the
// entire sign-extension of the smi-sign.
public:
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
HValue* left, HValue* right,
- LanguageMode language_mode = SLOPPY);
+ Strength strength = Strength::WEAK);
Range* InferRange(Zone* zone) override;
bool DataEquals(HValue* other) override { return true; }
private:
- HShl(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
- : HBitwiseBinaryOperation(context, left, right, language_mode) { }
+ HShl(HValue* context, HValue* left, HValue* right, Strength strength)
+ : HBitwiseBinaryOperation(context, left, right, strength) {}
};
public:
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
HValue* left, HValue* right,
- LanguageMode language_mode = SLOPPY);
+ Strength strength = Strength::WEAK);
bool TryDecompose(DecompositionResult* decomposition) override {
if (right()->IsInteger32Constant()) {
bool DataEquals(HValue* other) override { return true; }
private:
- HShr(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
- : HBitwiseBinaryOperation(context, left, right, language_mode) { }
+ HShr(HValue* context, HValue* left, HValue* right, Strength strength)
+ : HBitwiseBinaryOperation(context, left, right, strength) {}
};
public:
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
HValue* left, HValue* right,
- LanguageMode language_mode = SLOPPY);
+ Strength strength = Strength::WEAK);
bool TryDecompose(DecompositionResult* decomposition) override {
if (right()->IsInteger32Constant()) {
bool DataEquals(HValue* other) override { return true; }
private:
- HSar(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
- : HBitwiseBinaryOperation(context, left, right, language_mode) { }
+ HSar(HValue* context, HValue* left, HValue* right, Strength strength)
+ : HBitwiseBinaryOperation(context, left, right, strength) {}
};
public:
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
HValue* left, HValue* right,
- LanguageMode language_mode = SLOPPY) {
- return new(zone) HRor(context, left, right, language_mode);
+ Strength strength = Strength::WEAK) {
+ return new (zone) HRor(context, left, right, strength);
}
virtual void UpdateRepresentation(Representation new_rep,
bool DataEquals(HValue* other) override { return true; }
private:
- HRor(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
- : HBitwiseBinaryOperation(context, left, right, language_mode) {
+ HRor(HValue* context, HValue* left, HValue* right, Strength strength)
+ : HBitwiseBinaryOperation(context, left, right, strength) {
ChangeRepresentation(Representation::Integer32());
}
};
public:
static HInstruction* New(
Isolate* isolate, Zone* zone, HValue* context, HValue* left,
- HValue* right, LanguageMode language_mode = SLOPPY,
+ HValue* right, Strength strength = Strength::WEAK,
PretenureFlag pretenure_flag = NOT_TENURED,
StringAddFlags flags = STRING_ADD_CHECK_BOTH,
Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null());
}
private:
- HStringAdd(HValue* context,
- HValue* left,
- HValue* right,
- LanguageMode language_mode,
- PretenureFlag pretenure_flag,
- StringAddFlags flags,
+ HStringAdd(HValue* context, HValue* left, HValue* right, Strength strength,
+ PretenureFlag pretenure_flag, StringAddFlags flags,
Handle<AllocationSite> allocation_site)
- : HBinaryOperation(context, left, right, language_mode, HType::String()),
- flags_(flags), pretenure_flag_(pretenure_flag) {
+ : HBinaryOperation(context, left, right, strength, HType::String()),
+ flags_(flags),
+ pretenure_flag_(pretenure_flag) {
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
SetDependsOnFlag(kMaps);
HConstant* delta = (expr->op() == Token::INC)
? graph()->GetConstant1()
: graph()->GetConstantMinus1();
- HInstruction* instr = AddUncasted<HAdd>(Top(), delta,
- function_language_mode());
+ HInstruction* instr =
+ AddUncasted<HAdd>(Top(), delta, strength(function_language_mode()));
if (instr->IsAdd()) {
HAdd* add = HAdd::cast(instr);
add->set_observed_input_representation(1, rep);
HValue* result = HGraphBuilder::BuildBinaryOperation(
expr->op(), left, right, left_type, right_type, result_type,
- fixed_right_arg, allocation_mode, function_language_mode());
+ fixed_right_arg, allocation_mode, strength(function_language_mode()));
// Add a simulate after instructions with observable side effects, and
// after phis, which are the result of BuildBinaryOperation when we
// inlined some complex subgraph.
}
-HValue* HGraphBuilder::BuildBinaryOperation(
- Token::Value op,
- HValue* left,
- HValue* right,
- Type* left_type,
- Type* right_type,
- Type* result_type,
- Maybe<int> fixed_right_arg,
- HAllocationMode allocation_mode,
- LanguageMode language_mode) {
+HValue* HGraphBuilder::BuildBinaryOperation(Token::Value op, HValue* left,
+ HValue* right, Type* left_type,
+ Type* right_type, Type* result_type,
+ Maybe<int> fixed_right_arg,
+ HAllocationMode allocation_mode,
+ Strength strength) {
bool maybe_string_add = false;
if (op == Token::ADD) {
// If we are adding constant string with something for which we don't have
}
// Convert left argument as necessary.
- if (left_type->Is(Type::Number()) && !is_strong(language_mode)) {
+ if (left_type->Is(Type::Number()) && !is_strong(strength)) {
DCHECK(right_type->Is(Type::String()));
left = BuildNumberToString(left, left_type);
} else if (!left_type->Is(Type::String())) {
DCHECK(right_type->Is(Type::String()));
- HValue* function = AddLoadJSBuiltin(is_strong(language_mode) ?
- Builtins::STRING_ADD_RIGHT_STRONG :
- Builtins::STRING_ADD_RIGHT);
+ HValue* function = AddLoadJSBuiltin(
+ is_strong(strength) ? Builtins::STRING_ADD_RIGHT_STRONG
+ : Builtins::STRING_ADD_RIGHT);
Add<HPushArguments>(left, right);
return AddUncasted<HInvokeFunction>(function, 2);
}
// Convert right argument as necessary.
- if (right_type->Is(Type::Number()) && !is_strong(language_mode)) {
+ if (right_type->Is(Type::Number()) && !is_strong(strength)) {
DCHECK(left_type->Is(Type::String()));
right = BuildNumberToString(right, right_type);
} else if (!right_type->Is(Type::String())) {
DCHECK(left_type->Is(Type::String()));
- HValue* function = AddLoadJSBuiltin(is_strong(language_mode) ?
- Builtins::STRING_ADD_LEFT_STRONG :
- Builtins::STRING_ADD_LEFT);
+ HValue* function = AddLoadJSBuiltin(is_strong(strength)
+ ? Builtins::STRING_ADD_LEFT_STRONG
+ : Builtins::STRING_ADD_LEFT);
Add<HPushArguments>(left, right);
return AddUncasted<HInvokeFunction>(function, 2);
}
if (!right_string.is_null() && right_string->length() == 0) return left;
if (!left_string.is_null() && !right_string.is_null()) {
return AddUncasted<HStringAdd>(
- left, right, language_mode, allocation_mode.GetPretenureMode(),
+ left, right, strength, allocation_mode.GetPretenureMode(),
STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
}
// Fallback to using the string add stub.
return AddUncasted<HStringAdd>(
- left, right, language_mode, allocation_mode.GetPretenureMode(),
+ left, right, strength, allocation_mode.GetPretenureMode(),
STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
}
// inline several instructions (including the two pushes) for every tagged
// operation in optimized code, which is more expensive, than a stub call.
if (graph()->info()->IsStub() && is_non_primitive) {
- HValue* function = AddLoadJSBuiltin(
- BinaryOpIC::TokenToJSBuiltin(op, language_mode));
+ HValue* function =
+ AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op, strength));
Add<HPushArguments>(left, right);
instr = AddUncasted<HInvokeFunction>(function, 2);
} else {
switch (op) {
case Token::ADD:
- instr = AddUncasted<HAdd>(left, right, language_mode);
+ instr = AddUncasted<HAdd>(left, right, strength);
break;
case Token::SUB:
- instr = AddUncasted<HSub>(left, right, language_mode);
+ instr = AddUncasted<HSub>(left, right, strength);
break;
case Token::MUL:
- instr = AddUncasted<HMul>(left, right, language_mode);
+ instr = AddUncasted<HMul>(left, right, strength);
break;
case Token::MOD: {
if (fixed_right_arg.IsJust() &&
if_same.ElseDeopt(Deoptimizer::kUnexpectedRHSOfBinaryOperation);
right = fixed_right;
}
- instr = AddUncasted<HMod>(left, right, language_mode);
+ instr = AddUncasted<HMod>(left, right, strength);
break;
}
case Token::DIV:
- instr = AddUncasted<HDiv>(left, right, language_mode);
+ instr = AddUncasted<HDiv>(left, right, strength);
break;
case Token::BIT_XOR:
case Token::BIT_AND:
- instr = AddUncasted<HBitwise>(op, left, right, language_mode);
+ instr = AddUncasted<HBitwise>(op, left, right, strength);
break;
case Token::BIT_OR: {
HValue* operand, *shift_amount;
if (left_type->Is(Type::Signed32()) &&
right_type->Is(Type::Signed32()) &&
MatchRotateRight(left, right, &operand, &shift_amount)) {
- instr = AddUncasted<HRor>(operand, shift_amount, language_mode);
+ instr = AddUncasted<HRor>(operand, shift_amount, strength);
} else {
- instr = AddUncasted<HBitwise>(op, left, right, language_mode);
+ instr = AddUncasted<HBitwise>(op, left, right, strength);
}
break;
}
case Token::SAR:
- instr = AddUncasted<HSar>(left, right, language_mode);
+ instr = AddUncasted<HSar>(left, right, strength);
break;
case Token::SHR:
- instr = AddUncasted<HShr>(left, right, language_mode);
+ instr = AddUncasted<HShr>(left, right, strength);
if (instr->IsShr() && CanBeZero(right)) {
graph()->RecordUint32Instruction(instr);
}
break;
case Token::SHL:
- instr = AddUncasted<HShl>(left, right, language_mode);
+ instr = AddUncasted<HShl>(left, right, strength);
break;
default:
UNREACHABLE();
return result;
} else {
if (combined_rep.IsTagged() || combined_rep.IsNone()) {
- HCompareGeneric* result =
- Add<HCompareGeneric>(left, right, op, function_language_mode());
+ HCompareGeneric* result = Add<HCompareGeneric>(
+ left, right, op, strength(function_language_mode()));
result->set_observed_input_representation(1, left_rep);
result->set_observed_input_representation(2, right_rep);
if (result->HasObservableSideEffects()) {
CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
HValue* right = Pop();
HValue* left = Pop();
- HInstruction* result = NewUncasted<HStringAdd>(left, right,
- function_language_mode());
+ HInstruction* result =
+ NewUncasted<HStringAdd>(left, right, strength(function_language_mode()));
return ast_context()->ReturnInstruction(result, call->id());
}
HValue** operand,
HValue** shift_amount);
- HValue* BuildBinaryOperation(Token::Value op,
- HValue* left,
- HValue* right,
- Type* left_type,
- Type* right_type,
- Type* result_type,
- Maybe<int> fixed_right_arg,
+ HValue* BuildBinaryOperation(Token::Value op, HValue* left, HValue* right,
+ Type* left_type, Type* right_type,
+ Type* result_type, Maybe<int> fixed_right_arg,
HAllocationMode allocation_mode,
- LanguageMode language_mode);
+ Strength strength);
HLoadNamedField* AddLoadFixedArrayLength(HValue *object,
HValue *dependency = NULL);
// Check for undefined. undefined OP undefined is false even though
// undefined == undefined.
__ cmp(edx, isolate()->factory()->undefined_value());
- if (strong()) {
+ if (is_strong(strength())) {
// In strong mode, this comparison must throw, so call the runtime.
__ j(equal, &runtime_call, Label::kFar);
} else {
// Call runtime on identical symbols since we need to throw a TypeError.
__ cmpb(ecx, static_cast<uint8_t>(SYMBOL_TYPE));
__ j(equal, &runtime_call, Label::kFar);
- if (strong()) {
+ if (is_strong(strength())) {
// We have already tested for smis and heap numbers, so if both
// arguments are not strings we must proceed to the slow case.
__ test(ecx, Immediate(kIsNotStringMask));
if (cc == equal) {
builtin = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
} else {
- builtin = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
+ builtin =
+ is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
__ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
}
__ bind(&unordered);
__ bind(&generic_stub);
- CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
+ CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
CompareICState::GENERIC, CompareICState::GENERIC);
__ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
- language_mode()).code();
+ strength(language_mode())).code();
CallIC(ic, clause->CompareId());
patch_site.EmitPatchInfo();
__ bind(&stub_call);
__ mov(eax, ecx);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done, Label::kNear);
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ pop(edx);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&stub_call);
__ mov(edx, eax);
__ mov(eax, Immediate(Smi::FromInt(1)));
- Handle<Code> code =
- CodeFactory::BinaryOpIC(
- isolate(), expr->binary_op(), language_mode()).code();
+ Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(),
+ strength(language_mode())).code();
CallIC(code, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
// Record position and call the compare IC.
SetSourcePosition(expr->position());
- Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, language_mode()).code();
+ Handle<Code> ic = CodeFactory::CompareIC(
+ isolate(), op, strength(language_mode())).code();
CallIC(ic, expr->CompareOperationFeedbackId());
patch_site.EmitPatchInfo();
DCHECK(ToRegister(instr->right()).is(eax));
DCHECK(ToRegister(instr->result()).is(eax));
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), instr->op(), instr->language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
CallCode(code, RelocInfo::CODE_TARGET, instr);
}
void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
Token::Value op = instr->op();
- Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
+ Handle<Code> ic =
+ CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
Condition condition = ComputeCompareCondition(op);
Token::Value op = instr->op();
Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
+ CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
Condition condition = ComputeCompareCondition(op);
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
- LanguageMode language_mode() { return hydrogen()->language_mode(); }
+ Strength strength() { return hydrogen()->strength(); }
LOperand* context() { return inputs_[0]; }
Token::Value op() const { return hydrogen()->token(); }
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
- LanguageMode language_mode() { return hydrogen()->language_mode(); }
+ Strength strength() { return hydrogen()->strength(); }
private:
Token::Value op_;
isolate_(isolate) {
op_ =
static_cast<Token::Value>(FIRST_TOKEN + OpField::decode(extra_ic_state));
- strong_ = StrongField::decode(extra_ic_state);
+ strong_ = StrengthField::decode(extra_ic_state);
left_kind_ = LeftKindField::decode(extra_ic_state);
right_kind_ = fixed_right_arg_.IsJust()
? (Smi::IsValid(fixed_right_arg_.FromJust()) ? SMI : INT32)
ExtraICState BinaryOpICState::GetExtraICState() const {
ExtraICState extra_ic_state =
OpField::encode(op_ - FIRST_TOKEN) | LeftKindField::encode(left_kind_) |
- ResultKindField::encode(result_kind_) |
- StrongField::encode(strong_) |
+ ResultKindField::encode(result_kind_) | StrengthField::encode(strong_) |
HasFixedRightArgField::encode(fixed_right_arg_.IsJust());
if (fixed_right_arg_.IsJust()) {
extra_ic_state = FixedRightArgValueField::update(
// expensive at runtime. When solved we should be able to add most binops to
// the snapshot instead of hand-picking them.
// Generated list of commonly used stubs
-#define GENERATE(op, left_kind, right_kind, result_kind) \
- do { \
- BinaryOpICState state(isolate, op, LanguageMode::SLOPPY); \
- state.left_kind_ = left_kind; \
- state.fixed_right_arg_ = Nothing<int>(); \
- state.right_kind_ = right_kind; \
- state.result_kind_ = result_kind; \
- Generate(isolate, state); \
+#define GENERATE(op, left_kind, right_kind, result_kind) \
+ do { \
+ BinaryOpICState state(isolate, op, Strength::WEAK); \
+ state.left_kind_ = left_kind; \
+ state.fixed_right_arg_ = Nothing<int>(); \
+ state.right_kind_ = right_kind; \
+ state.result_kind_ = result_kind; \
+ Generate(isolate, state); \
} while (false)
GENERATE(Token::ADD, INT32, INT32, INT32);
GENERATE(Token::ADD, INT32, INT32, NUMBER);
#undef GENERATE
#define GENERATE(op, left_kind, fixed_right_arg_value, result_kind) \
do { \
- BinaryOpICState state(isolate, op, LanguageMode::SLOPPY); \
+ BinaryOpICState state(isolate, op, Strength::WEAK); \
state.left_kind_ = left_kind; \
state.fixed_right_arg_ = Just(fixed_right_arg_value); \
state.right_kind_ = SMI; \
class BinaryOpICState final BASE_EMBEDDED {
public:
BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state);
- BinaryOpICState(Isolate* isolate, Token::Value op, LanguageMode language_mode)
+ BinaryOpICState(Isolate* isolate, Token::Value op, Strength strength)
: op_(op),
- strong_(is_strong(language_mode)),
+ strong_(is_strong(strength)),
left_kind_(NONE),
right_kind_(NONE),
result_kind_(NONE),
return Max(left_kind_, right_kind_) == GENERIC;
}
- LanguageMode language_mode() const {
- return strong_ ? LanguageMode::STRONG : LanguageMode::SLOPPY;
+ Strength strength() const {
+ return strong_ ? Strength::STRONG : Strength::WEAK;
}
// Returns true if the IC should enable the inline smi code (i.e. if either
class OpField : public BitField<int, 0, 4> {};
class ResultKindField : public BitField<Kind, 4, 3> {};
class LeftKindField : public BitField<Kind, 7, 3> {};
- class StrongField : public BitField<bool, 10, 1> {};
+ class StrengthField : public BitField<bool, 10, 1> {};
// When fixed right arg is set, we don't need to store the right kind.
// Thus the two fields can overlap.
class HasFixedRightArgField : public BitField<bool, 11, 1> {};
// Only clear CompareICs that can retain objects.
if (stub.state() != CompareICState::KNOWN_OBJECT) return;
SetTargetAtAddress(address,
- GetRawUninitialized(isolate, stub.op(), stub.strong()),
+ GetRawUninitialized(isolate, stub.op(), stub.strength()),
constant_pool);
PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK);
}
// Compute the actual result using the builtin for the binary operation.
Object* builtin = isolate()->js_builtins_object()->javascript_builtin(
- TokenToJSBuiltin(state.op(), state.language_mode()));
+ TokenToJSBuiltin(state.op(), state.strength()));
Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate());
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(
Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op,
- bool strong) {
- CompareICStub stub(isolate, op, strong, CompareICState::UNINITIALIZED,
+ Strength strength) {
+ CompareICStub stub(isolate, op, strength, CompareICState::UNINITIALIZED,
CompareICState::UNINITIALIZED,
CompareICState::UNINITIALIZED);
Code* code = NULL;
Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op,
- bool strong) {
- CompareICStub stub(isolate, op, strong, CompareICState::UNINITIALIZED,
+ Strength strength) {
+ CompareICStub stub(isolate, op, strength, CompareICState::UNINITIALIZED,
CompareICState::UNINITIALIZED,
CompareICState::UNINITIALIZED);
return stub.GetCode();
CompareICState::State state = CompareICState::TargetState(
old_stub.state(), old_stub.left(), old_stub.right(), op_,
HasInlinedSmiCode(address()), x, y);
- CompareICStub stub(isolate(), op_, old_stub.strong(), new_left, new_right,
+ CompareICStub stub(isolate(), op_, old_stub.strength(), new_left, new_right,
state);
if (state == CompareICState::KNOWN_OBJECT) {
stub.set_known_map(
Builtins::JavaScript BinaryOpIC::TokenToJSBuiltin(Token::Value op,
- LanguageMode language_mode) {
- if (is_strong(language_mode)) {
+ Strength strength) {
+ if (is_strong(strength)) {
switch (op) {
default: UNREACHABLE();
case Token::ADD: return Builtins::ADD_STRONG;
explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
static Builtins::JavaScript TokenToJSBuiltin(Token::Value op,
- LanguageMode language_mode);
+ Strength strength);
MaybeHandle<Object> Transition(Handle<AllocationSite> allocation_site,
Handle<Object> left,
// Factory method for getting an uninitialized compare stub.
static Handle<Code> GetUninitialized(Isolate* isolate, Token::Value op,
- bool strong);
+ Strength strength);
private:
static bool HasInlinedSmiCode(Address address);
Condition GetCondition() const { return ComputeCondition(op_); }
static Code* GetRawUninitialized(Isolate* isolate, Token::Value op,
- bool strong);
+ Strength strength);
static void Clear(Isolate* isolate, Address address, Code* target,
Address constant_pool);
}
-Map* Isolate::get_initial_js_array_map(ElementsKind kind,
- ObjectStrength strength) {
+Map* Isolate::get_initial_js_array_map(ElementsKind kind, Strength strength) {
Context* native_context = context()->native_context();
- Object* maybe_map_array = strength ? native_context->js_array_strong_maps()
- : native_context->js_array_maps();
+ Object* maybe_map_array = is_strong(strength)
+ ? native_context->js_array_strong_maps()
+ : native_context->js_array_maps();
if (!maybe_map_array->IsUndefined()) {
Object* maybe_transitioned_map =
FixedArray::cast(maybe_map_array)->get(kind);
}
Map* get_initial_js_array_map(ElementsKind kind,
- ObjectStrength strength = WEAK);
+ Strength strength = Strength::WEAK);
static const int kArrayProtectorValid = 1;
static const int kArrayProtectorInvalid = 0;
fast_elements->set(i, *elements[i]);
}
Handle<Object> json_array = factory()->NewJSArrayWithElements(
- fast_elements, FAST_ELEMENTS, WEAK, pretenure_);
+ fast_elements, FAST_ELEMENTS, Strength::WEAK, pretenure_);
return scope.CloseAndEscape(json_array);
}
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
- Condition cc, bool strong);
+ Condition cc, Strength strength);
static void EmitSmiNonsmiComparison(MacroAssembler* masm,
Register lhs,
Register rhs,
// Equality is almost reflexive (everything but NaN), so this is a test
// for "identity and not NaN".
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
- Condition cc, bool strong) {
+ Condition cc, Strength strength) {
Label not_identical;
Label heap_number, return_equal;
Register exp_mask_reg = t5;
__ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE));
// Call runtime on identical symbols since we need to throw a TypeError.
__ Branch(slow, eq, t4, Operand(SYMBOL_TYPE));
- if (strong) {
+ if (is_strong(strength)) {
// Call the runtime on anything that is converted in the semantics, since
// we need to throw a TypeError. Smis have already been ruled out.
__ Branch(&return_equal, eq, t4, Operand(HEAP_NUMBER_TYPE));
__ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE));
// Call runtime on identical symbols since we need to throw a TypeError.
__ Branch(slow, eq, t4, Operand(SYMBOL_TYPE));
- if (strong) {
+ if (is_strong(strength)) {
// Call the runtime on anything that is converted in the semantics,
// since we need to throw a TypeError. Smis and heap numbers have
// already been ruled out.
// Handle the case where the objects are identical. Either returns the answer
// or goes to slow. Only falls through if the objects were not identical.
- EmitIdenticalObjectComparison(masm, &slow, cc, strong());
+ EmitIdenticalObjectComparison(masm, &slow, cc, strength());
// If either is a Smi (we know that not both are), then they can only
// be strictly equal if the other is a HeapNumber.
if (cc == eq) {
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
} else {
- native = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
+ native =
+ is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
int ncr; // NaN compare result.
if (cc == lt || cc == le) {
ncr = GREATER;
__ bind(&unordered);
__ bind(&generic_stub);
- CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
+ CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
CompareICState::GENERIC, CompareICState::GENERIC);
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
- language_mode()).code();
+ strength(language_mode())).code();
CallIC(ic, clause->CompareId());
patch_site.EmitPatchInfo();
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
__ bind(&stub_call);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done);
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ mov(a0, result_register());
__ pop(a1);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
// Record position before stub call.
SetSourcePosition(expr->position());
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), Token::ADD, language_mode()).code();
+ Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD,
+ strength(language_mode())).code();
CallIC(code, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
}
// Record position and call the compare IC.
SetSourcePosition(expr->position());
- Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, language_mode()).code();
+ Handle<Code> ic = CodeFactory::CompareIC(
+ isolate(), op, strength(language_mode())).code();
CallIC(ic, expr->CompareOperationFeedbackId());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
DCHECK(ToRegister(instr->right()).is(a0));
DCHECK(ToRegister(instr->result()).is(v0));
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), instr->op(), instr->language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
CallCode(code, RelocInfo::CODE_TARGET, instr);
// Other arch use a nop here, to signal that there is no inlined
// patchable code. Mips does not need the nop, since our marker
DCHECK(ToRegister(instr->context()).is(cp));
Token::Value op = instr->op();
- Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
+ Handle<Code> ic =
+ CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
Condition condition = ComputeCompareCondition(op);
Token::Value op = instr->op();
Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
+ CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
// On MIPS there is no need for a "no inlined smi code" marker (nop).
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
- LanguageMode language_mode() { return hydrogen()->language_mode(); }
+ Strength strength() { return hydrogen()->strength(); }
Token::Value op() const { return hydrogen()->token(); }
};
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
- LanguageMode language_mode() { return hydrogen()->language_mode(); }
+ Strength strength() { return hydrogen()->strength(); }
private:
Token::Value op_;
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
- Condition cc, bool strong);
+ Condition cc, Strength strength);
static void EmitSmiNonsmiComparison(MacroAssembler* masm,
Register lhs,
Register rhs,
// Equality is almost reflexive (everything but NaN), so this is a test
// for "identity and not NaN".
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
- Condition cc, bool strong) {
+ Condition cc, Strength strength) {
Label not_identical;
Label heap_number, return_equal;
Register exp_mask_reg = t1;
__ Branch(slow, greater, t0, Operand(FIRST_SPEC_OBJECT_TYPE));
// Call runtime on identical symbols since we need to throw a TypeError.
__ Branch(slow, eq, t0, Operand(SYMBOL_TYPE));
- if (strong) {
+ if (is_strong(strength)) {
// Call the runtime on anything that is converted in the semantics, since
// we need to throw a TypeError. Smis have already been ruled out.
__ Branch(&return_equal, eq, t0, Operand(HEAP_NUMBER_TYPE));
__ Branch(slow, greater, t0, Operand(FIRST_SPEC_OBJECT_TYPE));
// Call runtime on identical symbols since we need to throw a TypeError.
__ Branch(slow, eq, t0, Operand(SYMBOL_TYPE));
- if (strong) {
+ if (is_strong(strength)) {
// Call the runtime on anything that is converted in the semantics,
// since we need to throw a TypeError. Smis and heap numbers have
// already been ruled out.
// Handle the case where the objects are identical. Either returns the answer
// or goes to slow. Only falls through if the objects were not identical.
- EmitIdenticalObjectComparison(masm, &slow, cc, strong());
+ EmitIdenticalObjectComparison(masm, &slow, cc, strength());
// If either is a Smi (we know that not both are), then they can only
// be strictly equal if the other is a HeapNumber.
if (cc == eq) {
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
} else {
- native = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
+ native =
+ is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
int ncr; // NaN compare result.
if (cc == lt || cc == le) {
ncr = GREATER;
__ bind(&unordered);
__ bind(&generic_stub);
- CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
+ CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
CompareICState::GENERIC, CompareICState::GENERIC);
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
- language_mode()).code();
+ strength(language_mode())).code();
CallIC(ic, clause->CompareId());
patch_site.EmitPatchInfo();
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
__ bind(&stub_call);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done);
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ mov(a0, result_register());
__ pop(a1);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
// Record position before stub call.
SetSourcePosition(expr->position());
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), Token::ADD, language_mode()).code();
+ Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD,
+ strength(language_mode())).code();
CallIC(code, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
}
// Record position and call the compare IC.
SetSourcePosition(expr->position());
- Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, language_mode()).code();
+ Handle<Code> ic = CodeFactory::CompareIC(
+ isolate(), op, strength(language_mode())).code();
CallIC(ic, expr->CompareOperationFeedbackId());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
DCHECK(ToRegister(instr->right()).is(a0));
DCHECK(ToRegister(instr->result()).is(v0));
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), instr->op(), instr->language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
CallCode(code, RelocInfo::CODE_TARGET, instr);
// Other arch use a nop here, to signal that there is no inlined
// patchable code. Mips does not need the nop, since our marker
DCHECK(ToRegister(instr->context()).is(cp));
Token::Value op = instr->op();
- Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
+ Handle<Code> ic =
+ CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
Condition condition = ComputeCompareCondition(op);
Token::Value op = instr->op();
Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
+ CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
// On MIPS there is no need for a "no inlined smi code" marker (nop).
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
- LanguageMode language_mode() { return hydrogen()->language_mode(); }
+ Strength strength() { return hydrogen()->strength(); }
Token::Value op() const { return hydrogen()->token(); }
};
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
- LanguageMode language_mode() { return hydrogen()->language_mode(); }
+ Strength strength() { return hydrogen()->strength(); }
private:
Token::Value op_;
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
- Condition cond, bool strong);
+ Condition cond, Strength strength);
static void EmitSmiNonsmiComparison(MacroAssembler* masm, Register lhs,
Register rhs, Label* lhs_not_nan,
Label* slow, bool strict);
// Equality is almost reflexive (everything but NaN), so this is a test
// for "identity and not NaN".
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
- Condition cond, bool strong) {
+ Condition cond, Strength strength) {
Label not_identical;
Label heap_number, return_equal;
__ cmp(r3, r4);
// Call runtime on identical symbols since we need to throw a TypeError.
__ cmpi(r7, Operand(SYMBOL_TYPE));
__ beq(slow);
- if (strong) {
+ if (is_strong(strength)) {
// Call the runtime on anything that is converted in the semantics, since
// we need to throw a TypeError. Smis have already been ruled out.
__ cmpi(r7, Operand(HEAP_NUMBER_TYPE));
// Call runtime on identical symbols since we need to throw a TypeError.
__ cmpi(r7, Operand(SYMBOL_TYPE));
__ beq(slow);
- if (strong) {
+ if (is_strong(strength)) {
// Call the runtime on anything that is converted in the semantics,
// since we need to throw a TypeError. Smis and heap numbers have
// already been ruled out.
// Handle the case where the objects are identical. Either returns the answer
// or goes to slow. Only falls through if the objects were not identical.
- EmitIdenticalObjectComparison(masm, &slow, cc, strong());
+ EmitIdenticalObjectComparison(masm, &slow, cc, strength());
// If either is a Smi (we know that not both are), then they can only
// be strictly equal if the other is a HeapNumber.
if (cc == eq) {
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
} else {
- native = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
+ native =
+ is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
int ncr; // NaN compare result
if (cc == lt || cc == le) {
ncr = GREATER;
__ bind(&unordered);
__ bind(&generic_stub);
- CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
+ CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
CompareICState::GENERIC, CompareICState::GENERIC);
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
- language_mode()).code();
+ strength(language_mode())).code();
CallIC(ic, clause->CompareId());
patch_site.EmitPatchInfo();
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
__ bind(&stub_call);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ b(&done);
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ pop(r4);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
// Record position before stub call.
SetSourcePosition(expr->position());
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), Token::ADD, language_mode()).code();
+ Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD,
+ strength(language_mode())).code();
CallIC(code, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
// Record position and call the compare IC.
SetSourcePosition(expr->position());
- Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, language_mode()).code();
+ Handle<Code> ic = CodeFactory::CompareIC(
+ isolate(), op, strength(language_mode())).code();
CallIC(ic, expr->CompareOperationFeedbackId());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
DCHECK(ToRegister(instr->right()).is(r3));
DCHECK(ToRegister(instr->result()).is(r3));
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), instr->op(), instr->language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
CallCode(code, RelocInfo::CODE_TARGET, instr);
}
DCHECK(ToRegister(instr->context()).is(cp));
Token::Value op = instr->op();
- Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
+ Handle<Code> ic =
+ CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
// This instruction also signals no smi code inlined
__ cmpi(r3, Operand::Zero());
Token::Value op = instr->op();
Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
+ CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
// This instruction also signals no smi code inlined
__ cmpi(r3, Operand::Zero());
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
- LanguageMode language_mode() { return hydrogen()->language_mode(); }
+ Strength strength() { return hydrogen()->strength(); }
Token::Value op() const { return hydrogen()->token(); }
};
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
- LanguageMode language_mode() { return hydrogen()->language_mode(); }
+ Strength strength() { return hydrogen()->strength(); }
private:
Token::Value op_;
// Check for undefined. undefined OP undefined is false even though
// undefined == undefined.
__ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
- if (strong()) {
+ if (is_strong(strength())) {
// In strong mode, this comparison must throw, so call the runtime.
__ j(equal, &runtime_call, Label::kFar);
} else {
// Call runtime on identical symbols since we need to throw a TypeError.
__ cmpb(rcx, Immediate(static_cast<uint8_t>(SYMBOL_TYPE)));
__ j(equal, &runtime_call, Label::kFar);
- if (strong()) {
+ if (is_strong(strength())) {
// We have already tested for smis and heap numbers, so if both
// arguments are not strings we must proceed to the slow case.
__ testb(rcx, Immediate(kIsNotStringMask));
if (cc == equal) {
builtin = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
} else {
- builtin = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
+ builtin =
+ is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
__ Push(Smi::FromInt(NegativeComparisonResult(cc)));
}
__ bind(&unordered);
__ bind(&generic_stub);
- CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
+ CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
CompareICState::GENERIC, CompareICState::GENERIC);
__ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
- language_mode()).code();
+ strength(language_mode())).code();
CallIC(ic, clause->CompareId());
patch_site.EmitPatchInfo();
__ bind(&stub_call);
__ movp(rax, rcx);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done, Label::kNear);
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ Pop(rdx);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&stub_call);
__ movp(rdx, rax);
__ Move(rax, Smi::FromInt(1));
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), expr->binary_op(), language_mode()).code();
+ Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(),
+ strength(language_mode())).code();
CallIC(code, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
// Record position and call the compare IC.
SetSourcePosition(expr->position());
- Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, language_mode()).code();
+ Handle<Code> ic = CodeFactory::CompareIC(
+ isolate(), op, strength(language_mode())).code();
CallIC(ic, expr->CompareOperationFeedbackId());
patch_site.EmitPatchInfo();
DCHECK(ToRegister(instr->right()).is(rax));
DCHECK(ToRegister(instr->result()).is(rax));
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), instr->op(), instr->language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
CallCode(code, RelocInfo::CODE_TARGET, instr);
}
DCHECK(ToRegister(instr->context()).is(rsi));
Token::Value op = instr->op();
- Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
+ Handle<Code> ic =
+ CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
Condition condition = TokenToCondition(op, false);
Token::Value op = instr->op();
Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
+ CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
Condition condition = TokenToCondition(op, false);
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
- LanguageMode language_mode() { return hydrogen()->language_mode(); }
+ Strength strength() { return hydrogen()->strength(); }
Token::Value op() const { return hydrogen()->token(); }
};
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
- LanguageMode language_mode() { return hydrogen()->language_mode(); }
+ Strength strength() { return hydrogen()->strength(); }
private:
Token::Value op_;
// Check for undefined. undefined OP undefined is false even though
// undefined == undefined.
__ cmp(edx, isolate()->factory()->undefined_value());
- if (strong()) {
+ if (is_strong(strength())) {
// In strong mode, this comparison must throw, so call the runtime.
__ j(equal, &runtime_call, Label::kFar);
} else {
// Call runtime on identical symbols since we need to throw a TypeError.
__ cmpb(ecx, static_cast<uint8_t>(SYMBOL_TYPE));
__ j(equal, &runtime_call, Label::kFar);
- if (strong()) {
+ if (is_strong(strength())) {
// We have already tested for smis and heap numbers, so if both
// arguments are not strings we must proceed to the slow case.
__ test(ecx, Immediate(kIsNotStringMask));
if (cc == equal) {
builtin = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
} else {
- builtin = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
+ builtin =
+ is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
__ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
}
__ bind(&unordered);
__ bind(&generic_stub);
- CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
+ CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
CompareICState::GENERIC, CompareICState::GENERIC);
__ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
- language_mode()).code();
+ strength(language_mode())).code();
CallIC(ic, clause->CompareId());
patch_site.EmitPatchInfo();
__ bind(&stub_call);
__ mov(eax, ecx);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done, Label::kNear);
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ pop(edx);
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), op, language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&stub_call);
__ mov(edx, eax);
__ mov(eax, Immediate(Smi::FromInt(1)));
- Handle<Code> code =
- CodeFactory::BinaryOpIC(
- isolate(), expr->binary_op(), language_mode()).code();
+ Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(),
+ strength(language_mode())).code();
CallIC(code, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
// Record position and call the compare IC.
SetSourcePosition(expr->position());
- Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, language_mode()).code();
+ Handle<Code> ic = CodeFactory::CompareIC(
+ isolate(), op, strength(language_mode())).code();
CallIC(ic, expr->CompareOperationFeedbackId());
patch_site.EmitPatchInfo();
DCHECK(ToRegister(instr->right()).is(eax));
DCHECK(ToRegister(instr->result()).is(eax));
- Handle<Code> code = CodeFactory::BinaryOpIC(
- isolate(), instr->op(), instr->language_mode()).code();
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
CallCode(code, RelocInfo::CODE_TARGET, instr);
}
void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
Token::Value op = instr->op();
- Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
+ Handle<Code> ic =
+ CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
Condition condition = ComputeCompareCondition(op);
Token::Value op = instr->op();
Handle<Code> ic =
- CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
+ CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
Condition condition = ComputeCompareCondition(op);
// Allocate a JS array to OLD_SPACE and NEW_SPACE
objs[next_objs_index++] = factory->NewJSArray(10);
objs[next_objs_index++] =
- factory->NewJSArray(10, FAST_HOLEY_ELEMENTS, WEAK, TENURED);
+ factory->NewJSArray(10, FAST_HOLEY_ELEMENTS, Strength::WEAK, TENURED);
// Allocate a small string to OLD_DATA_SPACE and NEW_SPACE
objs[next_objs_index++] = factory->NewStringFromStaticChars("abcdefghij");
{
AlwaysAllocateScope always_allocate(isolate);
SimulateFullSpace(space);
- prototype =
- factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, WEAK, TENURED);
+ prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS,
+ Strength::WEAK, TENURED);
}
// Add a prototype on an evacuation candidate and verify that transition
CcTest::heap()->CollectGarbage(i::NEW_SPACE);
// Create temp object in the new space.
- Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, WEAK, NOT_TENURED);
+ Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS);
CHECK(isolate->heap()->new_space()->Contains(*temp));
// Construct a double value that looks like a pointer to the new space object
AlwaysAllocateScope always_allocate(isolate);
// Make sure |obj_value| is placed on an old-space evacuation candidate.
SimulateFullSpace(old_space);
- obj_value =
- factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, WEAK, TENURED);
+ obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS,
+ Strength::WEAK, TENURED);
ec_page = Page::FromAddress(obj_value->address());
}
CHECK(isolate->heap()->old_space()->Contains(*obj));
// Create temp object in the new space.
- Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, WEAK, NOT_TENURED);
+ Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS);
CHECK(isolate->heap()->new_space()->Contains(*temp));
// Construct a double value that looks like a pointer to the new space object
// Make sure |obj_value| is placed on an old-space evacuation candidate.
SimulateFullSpace(old_space);
- obj_value =
- factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, WEAK, TENURED);
+ obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS,
+ Strength::WEAK, TENURED);
ec_page = Page::FromAddress(obj_value->address());
CHECK_NE(ec_page, Page::FromAddress(obj->address()));
}