From: svenpanne@chromium.org Date: Tue, 6 Aug 2013 13:34:51 +0000 (+0000) Subject: Desugar bitwise negation into XOR and kill all UnaryOp stuff. X-Git-Tag: upstream/4.7.83~13033 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bc6fe88030b1d1bd73338e072536b6de3122e154;p=platform%2Fupstream%2Fv8.git Desugar bitwise negation into XOR and kill all UnaryOp stuff. R=mstarzinger@chromium.org, verwaest@chromium.org Review URL: https://codereview.chromium.org/22184004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16073 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 288e18f32..98a835fd1 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -246,17 +246,6 @@ void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( } -void UnaryOpStub::InitializeInterfaceDescriptor( - Isolate* isolate, - CodeStubInterfaceDescriptor* descriptor) { - static Register registers[] = { r0 }; - descriptor->register_param_count_ = 1; - descriptor->register_params_ = registers; - descriptor->deoptimization_handler_ = - FUNCTION_ADDR(UnaryOpIC_Miss); -} - - void StoreGlobalStub::InitializeInterfaceDescriptor( Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index dd347928d..b73006a17 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -4349,32 +4349,12 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { break; } - case Token::BIT_NOT: - EmitUnaryOperation(expr, "[ UnaryOperation (BIT_NOT)"); - break; - default: UNREACHABLE(); } } -void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr, - const char* comment) { - ASSERT_EQ(Token::BIT_NOT, expr->op()); - // TODO(svenpanne): Allowing format strings in Comment would be nice here... - Comment cmt(masm_, comment); - UnaryOpStub stub(expr->op()); - // UnaryOpStub expects the argument to be in the - // accumulator register r0. - VisitForAccumulatorValue(expr->expression()); - SetSourcePosition(expr->position()); - CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, - expr->UnaryOperationFeedbackId()); - context()->Plug(r0); -} - - void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { Comment cmnt(masm_, "[ CountOperation"); SetSourcePosition(expr->position()); diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 048840f10..43f0fd329 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -1325,15 +1325,6 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { } -LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { - ASSERT(instr->value()->representation().IsInteger32()); - ASSERT(instr->representation().IsInteger32()); - if (instr->HasNoUses()) return NULL; - LOperand* value = UseRegisterAtStart(instr->value()); - return DefineAsRegister(new(zone()) LBitNotI(value)); -} - - LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { if (instr->representation().IsDouble()) { return DoArithmeticD(Token::DIV, instr); diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h index db2d898a8..7ce907a7a 100644 --- a/src/arm/lithium-arm.h +++ b/src/arm/lithium-arm.h @@ -50,7 +50,6 @@ class LCodeGen; V(ArithmeticD) \ V(ArithmeticT) \ V(BitI) \ - V(BitNotI) \ V(BoundsCheck) \ V(Branch) \ V(CallConstantFunction) \ @@ -1377,18 +1376,6 @@ class LThrow: public LTemplateInstruction<0, 1, 0> { }; -class LBitNotI: public LTemplateInstruction<1, 1, 0> { - public: - explicit LBitNotI(LOperand* value) { - inputs_[0] = value; - } - - LOperand* value() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i") -}; - - class LAddI: public LTemplateInstruction<1, 2, 0> { public: LAddI(LOperand* left, LOperand* right) { diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 6ca885133..0b704d07e 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -1669,7 +1669,11 @@ void LCodeGen::DoBitI(LBitI* instr) { __ orr(result, left, right); break; case Token::BIT_XOR: - __ eor(result, left, right); + if (right_op->IsConstantOperand() && right.immediate() == int32_t(~0)) { + __ mvn(result, Operand(left)); + } else { + __ eor(result, left, right); + } break; default: UNREACHABLE(); @@ -1953,13 +1957,6 @@ void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { } -void LCodeGen::DoBitNotI(LBitNotI* instr) { - Register input = ToRegister(instr->value()); - Register result = ToRegister(instr->result()); - __ mvn(result, Operand(input)); -} - - void LCodeGen::DoThrow(LThrow* instr) { Register input_reg = EmitLoadRegister(instr->value(), ip); __ push(input_reg); diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h index 6125e27e2..143109c92 100644 --- a/src/arm/lithium-codegen-arm.h +++ b/src/arm/lithium-codegen-arm.h @@ -115,7 +115,7 @@ class LCodeGen BASE_EMBEDDED { DwVfpRegister EmitLoadDoubleRegister(LOperand* op, SwVfpRegister flt_scratch, DwVfpRegister dbl_scratch); - int ToRepresentation(LConstantOperand* op, const Representation& r) const; + int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const; int32_t ToInteger32(LConstantOperand* op) const; Smi* ToSmi(LConstantOperand* op) const; double ToDouble(LConstantOperand* op) const; diff --git a/src/ast.cc b/src/ast.cc index f99eaef40..2077f87d7 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -304,16 +304,6 @@ void UnaryOperation::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { } -bool UnaryOperation::ResultOverwriteAllowed() { - switch (op_) { - case Token::BIT_NOT: - return true; - default: - return false; - } -} - - void BinaryOperation::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { // TODO(olivf) If this Operation is used in a test context, then the right // hand side has a ToBoolean stub and we want to collect the type information. diff --git a/src/ast.h b/src/ast.h index db8cb2e36..a8b74213a 100644 --- a/src/ast.h +++ b/src/ast.h @@ -1847,8 +1847,6 @@ class UnaryOperation: public Expression { public: DECLARE_NODE_TYPE(UnaryOperation) - virtual bool ResultOverwriteAllowed(); - Token::Value op() const { return op_; } Expression* expression() const { return expression_; } virtual int position() const { return pos_; } @@ -1856,8 +1854,6 @@ class UnaryOperation: public Expression { BailoutId MaterializeTrueId() { return materialize_true_id_; } BailoutId MaterializeFalseId() { return materialize_false_id_; } - TypeFeedbackId UnaryOperationFeedbackId() const { return reuse(id()); } - virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle); protected: diff --git a/src/builtins.h b/src/builtins.h index 6a6ce9c29..bb36c0251 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -259,7 +259,6 @@ enum BuiltinExtraArguments { V(BIT_OR, 1) \ V(BIT_AND, 1) \ V(BIT_XOR, 1) \ - V(BIT_NOT, 0) \ V(SHL, 1) \ V(SAR, 1) \ V(SHR, 1) \ diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc index 33681ed09..852f7b569 100644 --- a/src/code-stubs-hydrogen.cc +++ b/src/code-stubs-hydrogen.cc @@ -801,45 +801,6 @@ Handle CompareNilICStub::GenerateCode() { } -template <> -HValue* CodeStubGraphBuilder::BuildCodeInitializedStub() { - UnaryOpStub* stub = casted_stub(); - ASSERT_EQ(Token::BIT_NOT, stub->operation()); - Handle type = stub->GetType(graph()->isolate()); - HValue* input = GetParameter(0); - - // Prevent unwanted HChange being inserted to ensure that the stub - // deopts on newly encountered types. - if (!type->Maybe(Type::Double())) { - input = Add(input, Representation::Smi()); - } - - if (!type->Is(Type::Number())) { - // If we expect to see other things than Numbers, we will create a generic - // stub, which handles all numbers and calls into the runtime for the rest. - IfBuilder if_number(this); - if_number.If(input); - if_number.Then(); - HInstruction* res = BuildUnaryMathOp(input, type, stub->operation()); - if_number.Return(AddInstruction(res)); - if_number.Else(); - HValue* function = AddLoadJSBuiltin(stub->ToJSBuiltin()); - Add(GetParameter(0)); - HValue* result = Add(function, 1); - if_number.Return(result); - if_number.End(); - return graph()->GetConstantUndefined(); - } - - return AddInstruction(BuildUnaryMathOp(input, type, stub->operation())); -} - - -Handle UnaryOpStub::GenerateCode() { - return DoGenerateCode(this); -} - - template <> HValue* CodeStubGraphBuilder::BuildCodeInitializedStub() { ToBooleanStub* stub = casted_stub(); diff --git a/src/code-stubs.cc b/src/code-stubs.cc index 4def2b572..d472fa287 100644 --- a/src/code-stubs.cc +++ b/src/code-stubs.cc @@ -204,65 +204,6 @@ void CodeStub::PrintName(StringStream* stream) { } -Builtins::JavaScript UnaryOpStub::ToJSBuiltin() { - switch (operation_) { - default: - UNREACHABLE(); - case Token::BIT_NOT: - return Builtins::BIT_NOT; - } -} - - -Handle UnaryOpStub::ToJSFunction(Isolate* isolate) { - Handle builtins(isolate->js_builtins_object()); - Object* builtin = builtins->javascript_builtin(ToJSBuiltin()); - return Handle(JSFunction::cast(builtin), isolate); -} - - -MaybeObject* UnaryOpStub::Result(Handle object, Isolate* isolate) { - Handle builtin_function = ToJSFunction(isolate); - bool caught_exception; - Handle result = Execution::Call(builtin_function, object, - 0, NULL, &caught_exception); - if (caught_exception) { - return Failure::Exception(); - } - return *result; -} - - -void UnaryOpStub::UpdateStatus(Handle object) { - State old_state(state_); - if (object->IsSmi()) { - state_.Add(SMI); - } else if (object->IsHeapNumber()) { - state_.Add(HEAP_NUMBER); - } else { - state_.Add(GENERIC); - } - TraceTransition(old_state, state_); -} - - -Handle UnaryOpStub::GetType(Isolate* isolate) { - if (state_.Contains(GENERIC)) { - return handle(Type::Any(), isolate); - } - Handle type = handle(Type::None(), isolate); - if (state_.Contains(SMI)) { - type = handle( - Type::Union(type, handle(Type::Smi(), isolate)), isolate); - } - if (state_.Contains(HEAP_NUMBER)) { - type = handle( - Type::Union(type, handle(Type::Double(), isolate)), isolate); - } - return type; -} - - void BinaryOpStub::Generate(MacroAssembler* masm) { // Explicitly allow generation of nested stubs. It is safe here because // generation code does not use any raw pointers. @@ -348,28 +289,6 @@ void BinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) { #undef __ -void UnaryOpStub::PrintBaseName(StringStream* stream) { - CodeStub::PrintBaseName(stream); - if (operation_ == Token::BIT_NOT) stream->Add("Not"); -} - - -void UnaryOpStub::PrintState(StringStream* stream) { - state_.Print(stream); -} - - -void UnaryOpStub::State::Print(StringStream* stream) const { - stream->Add("("); - SimpleListPrinter printer(stream); - if (IsEmpty()) printer.Add("None"); - if (Contains(GENERIC)) printer.Add("Generic"); - if (Contains(HEAP_NUMBER)) printer.Add("HeapNumber"); - if (Contains(SMI)) printer.Add("Smi"); - stream->Add(")"); -} - - void BinaryOpStub::PrintName(StringStream* stream) { const char* op_name = Token::Name(op_); const char* overwrite_name; diff --git a/src/code-stubs.h b/src/code-stubs.h index 84d9b023b..c58acd6b1 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -40,7 +40,6 @@ namespace internal { #define CODE_STUB_LIST_ALL_PLATFORMS(V) \ V(CallFunction) \ V(CallConstruct) \ - V(UnaryOp) \ V(BinaryOp) \ V(StringAdd) \ V(SubString) \ @@ -593,73 +592,6 @@ class StoreGlobalStub : public HydrogenCodeStub { }; -class UnaryOpStub : public HydrogenCodeStub { - public: - // Stub without type info available -> construct uninitialized - explicit UnaryOpStub(Token::Value operation) - : HydrogenCodeStub(UNINITIALIZED), operation_(operation) { } - explicit UnaryOpStub(Code::ExtraICState ic_state) : - state_(StateBits::decode(ic_state)), - operation_(OperatorBits::decode(ic_state)) { } - - virtual void InitializeInterfaceDescriptor( - Isolate* isolate, - CodeStubInterfaceDescriptor* descriptor); - - virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; } - virtual InlineCacheState GetICState() { - if (state_.Contains(GENERIC)) { - return MEGAMORPHIC; - } else if (state_.IsEmpty()) { - return PREMONOMORPHIC; - } else { - return MONOMORPHIC; - } - } - virtual Code::ExtraICState GetExtraICState() { - return OperatorBits::encode(operation_) | - StateBits::encode(state_.ToIntegral()); - } - - Token::Value operation() { return operation_; } - Handle ToJSFunction(Isolate* isolate); - Builtins::JavaScript ToJSBuiltin(); - - void UpdateStatus(Handle object); - MaybeObject* Result(Handle object, Isolate* isolate); - Handle GenerateCode(); - Handle GetType(Isolate* isolate); - - protected: - void PrintState(StringStream* stream); - void PrintBaseName(StringStream* stream); - - private: - enum UnaryOpType { - SMI, - HEAP_NUMBER, - GENERIC, - NUMBER_OF_TYPES - }; - - class State : public EnumSet { - public: - State() : EnumSet() { } - explicit State(byte bits) : EnumSet(bits) { } - void Print(StringStream* stream) const; - }; - - class StateBits : public BitField { }; - class OperatorBits : public BitField { }; - - State state_; - Token::Value operation_; - - virtual CodeStub::Major MajorKey() { return UnaryOp; } - virtual int NotMissMinorKey() { return GetExtraICState(); } -}; - - class FastCloneShallowArrayStub : public HydrogenCodeStub { public: // Maximum length of copied elements array. diff --git a/src/debug.cc b/src/debug.cc index a0b988441..a34950234 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -159,7 +159,6 @@ void BreakLocationIterator::Next() { Code* code = Code::GetCodeFromTargetAddress(target); if ((code->is_inline_cache_stub() && !code->is_binary_op_stub() && - !code->is_unary_op_stub() && !code->is_compare_ic_stub() && !code->is_to_boolean_ic_stub()) || RelocInfo::IsConstructCall(rmode())) { diff --git a/src/full-codegen.h b/src/full-codegen.h index a9db54e32..5b9698a7c 100644 --- a/src/full-codegen.h +++ b/src/full-codegen.h @@ -625,8 +625,6 @@ class FullCodeGenerator: public AstVisitor { AST_NODE_LIST(DECLARE_VISIT) #undef DECLARE_VISIT - void EmitUnaryOperation(UnaryOperation* expr, const char* comment); - void VisitComma(BinaryOperation* expr); void VisitLogicalExpression(BinaryOperation* expr); void VisitArithmeticExpression(BinaryOperation* expr); diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 28511f714..997b7c2fd 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -1155,6 +1155,29 @@ void HLoadFieldByIndex::PrintDataTo(StringStream* stream) { } +static bool MatchLeftIsOnes(HValue* l, HValue* r, HValue** negated) { + if (!l->EqualsInteger32Constant(~0)) return false; + *negated = r; + return true; +} + + +static bool MatchNegationViaXor(HValue* instr, HValue** negated) { + if (!instr->IsBitwise()) return false; + HBitwise* b = HBitwise::cast(instr); + return (b->op() == Token::BIT_XOR) && + (MatchLeftIsOnes(b->left(), b->right(), negated) || + MatchLeftIsOnes(b->right(), b->left(), negated)); +} + + +static bool MatchDoubleNegation(HValue* instr, HValue** arg) { + HValue* negated; + return MatchNegationViaXor(instr, &negated) && + MatchNegationViaXor(negated, arg); +} + + HValue* HBitwise::Canonicalize() { if (!representation().IsSmiOrInteger32()) return this; // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x. @@ -1167,18 +1190,10 @@ HValue* HBitwise::Canonicalize() { !left()->CheckFlag(kUint32)) { return left(); } - return this; -} - - -HValue* HBitNot::Canonicalize() { - // Optimize ~~x, a common pattern used for ToInt32(x). - if (value()->IsBitNot()) { - HValue* result = HBitNot::cast(value())->value(); - ASSERT(result->representation().IsInteger32()); - if (!result->CheckFlag(kUint32)) { - return result; - } + // Optimize double negation, a common pattern used for ToInt32(x). + HValue* arg; + if (MatchDoubleNegation(this, &arg) && !arg->CheckFlag(kUint32)) { + return arg; } return this; } diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 17222d404..1dbedbd52 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -72,7 +72,6 @@ class LChunkBuilder; V(ArgumentsLength) \ V(ArgumentsObject) \ V(Bitwise) \ - V(BitNot) \ V(BlockEntry) \ V(BoundsCheck) \ V(BoundsCheckBaseIndexInformation) \ @@ -2392,37 +2391,6 @@ class HElementsKind: public HUnaryOperation { }; -class HBitNot: public HUnaryOperation { - public: - DECLARE_INSTRUCTION_FACTORY_P1(HBitNot, HValue*); - - virtual Representation RequiredInputRepresentation(int index) { - return Representation::Integer32(); - } - virtual Representation observed_input_representation(int index) { - return Representation::Integer32(); - } - - virtual HValue* Canonicalize(); - - DECLARE_CONCRETE_INSTRUCTION(BitNot) - - protected: - virtual bool DataEquals(HValue* other) { return true; } - - private: - explicit HBitNot(HValue* value) - : HUnaryOperation(value, HType::TaggedNumber()) { - set_representation(Representation::Integer32()); - SetFlag(kUseGVN); - SetFlag(kTruncatingToInt32); - SetFlag(kAllowUndefinedAsNaN); - } - - virtual bool IsDeletable() const { return true; } -}; - - class HUnaryMathOperation: public HTemplateInstruction<2> { public: static HInstruction* New(Zone* zone, diff --git a/src/hydrogen-uint32-analysis.cc b/src/hydrogen-uint32-analysis.cc index 67219f55d..835a198d4 100644 --- a/src/hydrogen-uint32-analysis.cc +++ b/src/hydrogen-uint32-analysis.cc @@ -33,11 +33,7 @@ namespace internal { bool HUint32AnalysisPhase::IsSafeUint32Use(HValue* val, HValue* use) { // Operations that operate on bits are safe. - if (use->IsBitwise() || - use->IsShl() || - use->IsSar() || - use->IsShr() || - use->IsBitNot()) { + if (use->IsBitwise() || use->IsShl() || use->IsSar() || use->IsShr()) { return true; } else if (use->IsChange() || use->IsSimulate()) { // Conversions and deoptimization have special support for unt32. diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 6043caa0f..837c9780c 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -1719,19 +1719,6 @@ HValue* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate, } -HInstruction* HGraphBuilder::BuildUnaryMathOp( - HValue* input, Handle type, Token::Value operation) { - ASSERT_EQ(Token::BIT_NOT, operation); - // We only handle the numeric cases here - type = handle( - Type::Intersect(type, handle(Type::Number(), isolate())), isolate()); - if (type->Is(Type::None())) { - Add(Deoptimizer::SOFT); - } - return New(input); -} - - void HGraphBuilder::BuildCompareNil( HValue* value, Handle type, @@ -7229,7 +7216,6 @@ void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { case Token::DELETE: return VisitDelete(expr); case Token::VOID: return VisitVoid(expr); case Token::TYPEOF: return VisitTypeof(expr); - case Token::BIT_NOT: return VisitBitNot(expr); case Token::NOT: return VisitNot(expr); default: UNREACHABLE(); } @@ -7291,15 +7277,6 @@ void HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) { } -void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { - CHECK_ALIVE(VisitForValue(expr->expression())); - Handle operand_type = expr->expression()->bounds().lower; - HValue* value = TruncateToNumber(Pop(), &operand_type); - HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::BIT_NOT); - return ast_context()->ReturnInstruction(instr, expr->id()); -} - - void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { if (ast_context()->IsTest()) { TestContext* context = TestContext::cast(ast_context()); diff --git a/src/hydrogen.h b/src/hydrogen.h index 47b4caa6e..6312a5237 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -1550,9 +1550,6 @@ class HGraphBuilder { ElementsKind kind, int length); - HInstruction* BuildUnaryMathOp( - HValue* value, Handle type, Token::Value token); - void BuildCompareNil( HValue* value, Handle type, @@ -1811,7 +1808,6 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor { void VisitDelete(UnaryOperation* expr); void VisitVoid(UnaryOperation* expr); void VisitTypeof(UnaryOperation* expr); - void VisitBitNot(UnaryOperation* expr); void VisitNot(UnaryOperation* expr); void VisitComma(BinaryOperation* expr); diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 02517351b..872165663 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -250,17 +250,6 @@ void ToBooleanStub::InitializeInterfaceDescriptor( } -void UnaryOpStub::InitializeInterfaceDescriptor( - Isolate* isolate, - CodeStubInterfaceDescriptor* descriptor) { - static Register registers[] = { eax }; - descriptor->register_param_count_ = 1; - descriptor->register_params_ = registers; - descriptor->deoptimization_handler_ = - FUNCTION_ADDR(UnaryOpIC_Miss); -} - - void StoreGlobalStub::InitializeInterfaceDescriptor( Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index a3e17a68b..f08a269e8 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -4347,31 +4347,12 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { break; } - case Token::BIT_NOT: - EmitUnaryOperation(expr, "[ UnaryOperation (BIT_NOT)"); - break; - default: UNREACHABLE(); } } -void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr, - const char* comment) { - ASSERT_EQ(Token::BIT_NOT, expr->op()); - Comment cmt(masm_, comment); - UnaryOpStub stub(expr->op()); - // UnaryOpStub expects the argument to be in the - // accumulator register eax. - VisitForAccumulatorValue(expr->expression()); - SetSourcePosition(expr->position()); - CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, - expr->UnaryOperationFeedbackId()); - context()->Plug(eax); -} - - void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { Comment cmnt(masm_, "[ CountOperation"); SetSourcePosition(expr->position()); diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index ab73406a1..061ec9b6d 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -1679,8 +1679,9 @@ void LCodeGen::DoBitI(LBitI* instr) { ASSERT(left->IsRegister()); if (right->IsConstantOperand()) { - int right_operand = ToRepresentation(LConstantOperand::cast(right), - instr->hydrogen()->representation()); + int32_t right_operand = + ToRepresentation(LConstantOperand::cast(right), + instr->hydrogen()->representation()); switch (instr->op()) { case Token::BIT_AND: __ and_(ToRegister(left), right_operand); @@ -1689,7 +1690,11 @@ void LCodeGen::DoBitI(LBitI* instr) { __ or_(ToRegister(left), right_operand); break; case Token::BIT_XOR: - __ xor_(ToRegister(left), right_operand); + if (right_operand == int32_t(~0)) { + __ not_(ToRegister(left)); + } else { + __ xor_(ToRegister(left), right_operand); + } break; default: UNREACHABLE(); @@ -1990,13 +1995,6 @@ void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { } -void LCodeGen::DoBitNotI(LBitNotI* instr) { - LOperand* input = instr->value(); - ASSERT(input->Equals(instr->result())); - __ not_(ToRegister(input)); -} - - void LCodeGen::DoThrow(LThrow* instr) { __ push(ToOperand(instr->value())); ASSERT(ToRegister(instr->context()).is(esi)); diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h index 42c523478..c9a78997f 100644 --- a/src/ia32/lithium-codegen-ia32.h +++ b/src/ia32/lithium-codegen-ia32.h @@ -294,7 +294,7 @@ class LCodeGen BASE_EMBEDDED { Register ToRegister(int index) const; XMMRegister ToDoubleRegister(int index) const; X87Register ToX87Register(int index) const; - int ToRepresentation(LConstantOperand* op, const Representation& r) const; + int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const; int32_t ToInteger32(LConstantOperand* op) const; ExternalReference ToExternalReference(LConstantOperand* op) const; diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index e3b64b796..52f39d424 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -1414,16 +1414,6 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { } -LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { - ASSERT(instr->value()->representation().IsInteger32()); - ASSERT(instr->representation().IsInteger32()); - if (instr->HasNoUses()) return NULL; - LOperand* input = UseRegisterAtStart(instr->value()); - LBitNotI* result = new(zone()) LBitNotI(input); - return DefineSameAsFirst(result); -} - - LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { if (instr->representation().IsDouble()) { return DoArithmeticD(Token::DIV, instr); diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index 9ed9a58ea..effecb73e 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -50,7 +50,6 @@ class LCodeGen; V(ArithmeticD) \ V(ArithmeticT) \ V(BitI) \ - V(BitNotI) \ V(BoundsCheck) \ V(Branch) \ V(CallConstantFunction) \ @@ -1357,18 +1356,6 @@ class LThrow: public LTemplateInstruction<0, 2, 0> { }; -class LBitNotI: public LTemplateInstruction<1, 1, 0> { - public: - explicit LBitNotI(LOperand* value) { - inputs_[0] = value; - } - - LOperand* value() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i") -}; - - class LAddI: public LTemplateInstruction<1, 2, 0> { public: LAddI(LOperand* left, LOperand* right) { diff --git a/src/ic.cc b/src/ic.cc index a55160a39..3c22580c2 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -390,7 +390,6 @@ void IC::Clear(Address address) { case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target); case Code::COMPARE_IC: return CompareIC::Clear(address, target); case Code::COMPARE_NIL_IC: return CompareNilIC::Clear(address, target); - case Code::UNARY_OP_IC: case Code::BINARY_OP_IC: case Code::TO_BOOLEAN_IC: // Clearing these is tricky and does not @@ -2589,27 +2588,6 @@ void BinaryOpIC::StubInfoToType(int minor_key, } -MaybeObject* UnaryOpIC::Transition(Handle object) { - Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); - UnaryOpStub stub(extra_ic_state); - - stub.UpdateStatus(object); - - Handle code = stub.GetCode(isolate()); - set_target(*code); - - return stub.Result(object, isolate()); -} - - -RUNTIME_FUNCTION(MaybeObject*, UnaryOpIC_Miss) { - HandleScope scope(isolate); - Handle object = args.at(0); - UnaryOpIC ic(isolate); - return ic.Transition(object); -} - - static BinaryOpIC::TypeInfo TypeInfoFromValue(Handle value, Token::Value op) { v8::internal::TypeInfo type = v8::internal::TypeInfo::FromValue(value); diff --git a/src/ic.h b/src/ic.h index 7820d407e..fcf0de58f 100644 --- a/src/ic.h +++ b/src/ic.h @@ -714,14 +714,6 @@ class KeyedStoreIC: public StoreIC { }; -class UnaryOpIC: public IC { - public: - explicit UnaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { } - - MUST_USE_RESULT MaybeObject* Transition(Handle object); -}; - - // Type Recording BinaryOpIC, that records the types of the inputs and outputs. class BinaryOpIC: public IC { public: diff --git a/src/log.cc b/src/log.cc index b89c2bfba..a1e5a6752 100644 --- a/src/log.cc +++ b/src/log.cc @@ -1644,7 +1644,6 @@ void Logger::LogCodeObject(Object* object) { case Code::FUNCTION: case Code::OPTIMIZED_FUNCTION: return; // We log this later using LogCompiledFunctions. - case Code::UNARY_OP_IC: // fall through case Code::BINARY_OP_IC: // fall through case Code::COMPARE_IC: // fall through case Code::COMPARE_NIL_IC: // fall through diff --git a/src/mips/assembler-mips.h b/src/mips/assembler-mips.h index 8d533b36f..cb0896a8d 100644 --- a/src/mips/assembler-mips.h +++ b/src/mips/assembler-mips.h @@ -358,6 +358,11 @@ class Operand BASE_EMBEDDED { // Return true if this is a register operand. INLINE(bool is_reg() const); + inline int32_t immediate() const { + ASSERT(!is_reg()); + return imm32_; + } + Register rm() const { return rm_; } private: diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index 0dd8ec468..8a03a9a31 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -247,17 +247,6 @@ void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( } -void UnaryOpStub::InitializeInterfaceDescriptor( - Isolate* isolate, - CodeStubInterfaceDescriptor* descriptor) { - static Register registers[] = { a0 }; - descriptor->register_param_count_ = 1; - descriptor->register_params_ = registers; - descriptor->deoptimization_handler_ = - FUNCTION_ADDR(UnaryOpIC_Miss); -} - - void StoreGlobalStub::InitializeInterfaceDescriptor( Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index 0a26dbe43..b60502c9a 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -4382,32 +4382,12 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { break; } - case Token::BIT_NOT: - EmitUnaryOperation(expr, "[ UnaryOperation (BIT_NOT)"); - break; - default: UNREACHABLE(); } } -void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr, - const char* comment) { - ASSERT_EQ(Token::BIT_NOT, expr->op()); - // TODO(svenpanne): Allowing format strings in Comment would be nice here... - Comment cmt(masm_, comment); - UnaryOpStub stub(expr->op()); - // GenericUnaryOpStub expects the argument to be in a0. - VisitForAccumulatorValue(expr->expression()); - SetSourcePosition(expr->position()); - __ mov(a0, result_register()); - CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, - expr->UnaryOperationFeedbackId()); - context()->Plug(v0); -} - - void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { Comment cmnt(masm_, "[ CountOperation"); SetSourcePosition(expr->position()); diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 8f3423ecd..644919741 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -1509,7 +1509,11 @@ void LCodeGen::DoBitI(LBitI* instr) { __ Or(result, left, right); break; case Token::BIT_XOR: - __ Xor(result, left, right); + if (right_op->IsConstantOperand() && right.immediate() == int32_t(~0)) { + __ Nor(result, zero_reg, left); + } else { + __ Xor(result, left, right); + } break; default: UNREACHABLE(); @@ -1787,13 +1791,6 @@ void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { } -void LCodeGen::DoBitNotI(LBitNotI* instr) { - Register input = ToRegister(instr->value()); - Register result = ToRegister(instr->result()); - __ Nor(result, zero_reg, Operand(input)); -} - - void LCodeGen::DoThrow(LThrow* instr) { Register input_reg = EmitLoadRegister(instr->value(), at); __ push(input_reg); diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h index cc3873d84..670c4cc87 100644 --- a/src/mips/lithium-codegen-mips.h +++ b/src/mips/lithium-codegen-mips.h @@ -114,7 +114,7 @@ class LCodeGen BASE_EMBEDDED { DoubleRegister EmitLoadDoubleRegister(LOperand* op, FloatRegister flt_scratch, DoubleRegister dbl_scratch); - int ToRepresentation(LConstantOperand* op, const Representation& r) const; + int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const; int32_t ToInteger32(LConstantOperand* op) const; Smi* ToSmi(LConstantOperand* op) const; double ToDouble(LConstantOperand* op) const; diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index 5adcff240..38ac19f60 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -1327,15 +1327,6 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { } -LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { - ASSERT(instr->value()->representation().IsInteger32()); - ASSERT(instr->representation().IsInteger32()); - if (instr->HasNoUses()) return NULL; - LOperand* value = UseRegisterAtStart(instr->value()); - return DefineAsRegister(new(zone()) LBitNotI(value)); -} - - LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { if (instr->representation().IsDouble()) { return DoArithmeticD(Token::DIV, instr); diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h index 75ab77dac..a21c32342 100644 --- a/src/mips/lithium-mips.h +++ b/src/mips/lithium-mips.h @@ -50,7 +50,6 @@ class LCodeGen; V(ArithmeticD) \ V(ArithmeticT) \ V(BitI) \ - V(BitNotI) \ V(BoundsCheck) \ V(Branch) \ V(CallConstantFunction) \ @@ -1355,18 +1354,6 @@ class LThrow: public LTemplateInstruction<0, 1, 0> { }; -class LBitNotI: public LTemplateInstruction<1, 1, 0> { - public: - explicit LBitNotI(LOperand* value) { - inputs_[0] = value; - } - - LOperand* value() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i") -}; - - class LAddI: public LTemplateInstruction<1, 2, 0> { public: LAddI(LOperand* left, LOperand* right) { diff --git a/src/objects-inl.h b/src/objects-inl.h index ed266436f..169475791 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -3822,7 +3822,6 @@ inline void Code::set_is_crankshafted(bool value) { int Code::major_key() { ASSERT(kind() == STUB || - kind() == UNARY_OP_IC || kind() == BINARY_OP_IC || kind() == COMPARE_IC || kind() == COMPARE_NIL_IC || @@ -3837,7 +3836,6 @@ int Code::major_key() { void Code::set_major_key(int major) { ASSERT(kind() == STUB || - kind() == UNARY_OP_IC || kind() == BINARY_OP_IC || kind() == COMPARE_IC || kind() == COMPARE_NIL_IC || @@ -4027,21 +4025,6 @@ void Code::set_check_type(CheckType value) { } -byte Code::unary_op_type() { - ASSERT(is_unary_op_stub()); - return UnaryOpTypeField::decode( - READ_UINT32_FIELD(this, kKindSpecificFlags1Offset)); -} - - -void Code::set_unary_op_type(byte value) { - ASSERT(is_unary_op_stub()); - int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset); - int updated = UnaryOpTypeField::update(previous, value); - WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated); -} - - byte Code::to_boolean_state() { return extended_extra_ic_state(); } diff --git a/src/objects.h b/src/objects.h index 529808a34..b2dc1816f 100644 --- a/src/objects.h +++ b/src/objects.h @@ -4781,7 +4781,6 @@ class Code: public HeapObject { V(KEYED_CALL_IC) \ V(STORE_IC) \ V(KEYED_STORE_IC) \ - V(UNARY_OP_IC) \ V(BINARY_OP_IC) \ V(COMPARE_IC) \ V(COMPARE_NIL_IC) \ @@ -4900,8 +4899,7 @@ class Code: public HeapObject { // TODO(danno): This is a bit of a hack right now since there are still // clients of this API that pass "extra" values in for argc. These clients // should be retrofitted to used ExtendedExtraICState. - return kind == COMPARE_NIL_IC || kind == TO_BOOLEAN_IC || - kind == UNARY_OP_IC; + return kind == COMPARE_NIL_IC || kind == TO_BOOLEAN_IC; } inline StubType type(); // Only valid for monomorphic IC stubs. @@ -4916,7 +4914,6 @@ class Code: public HeapObject { inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; } inline bool is_call_stub() { return kind() == CALL_IC; } inline bool is_keyed_call_stub() { return kind() == KEYED_CALL_IC; } - inline bool is_unary_op_stub() { return kind() == UNARY_OP_IC; } inline bool is_binary_op_stub() { return kind() == BINARY_OP_IC; } inline bool is_compare_ic_stub() { return kind() == COMPARE_IC; } inline bool is_compare_nil_ic_stub() { return kind() == COMPARE_NIL_IC; } @@ -4990,10 +4987,6 @@ class Code: public HeapObject { inline CheckType check_type(); inline void set_check_type(CheckType value); - // [type-recording unary op type]: For kind UNARY_OP_IC. - inline byte unary_op_type(); - inline void set_unary_op_type(byte value); - // [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in. inline byte to_boolean_state(); @@ -5232,9 +5225,6 @@ class Code: public HeapObject { // KindSpecificFlags1 layout (STUB and OPTIMIZED_FUNCTION) static const int kStackSlotsFirstBit = 0; static const int kStackSlotsBitCount = 24; - static const int kUnaryOpTypeFirstBit = - kStackSlotsFirstBit + kStackSlotsBitCount; - static const int kUnaryOpTypeBitCount = 3; static const int kHasFunctionCacheFirstBit = kStackSlotsFirstBit + kStackSlotsBitCount; static const int kHasFunctionCacheBitCount = 1; @@ -5243,15 +5233,12 @@ class Code: public HeapObject { static const int kMarkedForDeoptimizationBitCount = 1; STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32); - STATIC_ASSERT(kUnaryOpTypeFirstBit + kUnaryOpTypeBitCount <= 32); STATIC_ASSERT(kHasFunctionCacheFirstBit + kHasFunctionCacheBitCount <= 32); STATIC_ASSERT(kMarkedForDeoptimizationFirstBit + kMarkedForDeoptimizationBitCount <= 32); class StackSlotsField: public BitField {}; // NOLINT - class UnaryOpTypeField: public BitField {}; // NOLINT class HasFunctionCacheField: public BitField {}; // NOLINT class MarkedForDeoptimizationField: public BitFieldNewNumberLiteral(-1), position); } + // ...and one more time for '~foo' => 'foo^(~0)'. + if (op == Token::BIT_NOT) { + return factory()->NewBinaryOperation(Token::BIT_XOR, + expression, + factory()->NewNumberLiteral(~0), + position); + } return factory()->NewUnaryOperation(op, expression, position); diff --git a/src/runtime.cc b/src/runtime.cc index 0a8fbebfb..17784181b 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -7245,15 +7245,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberXor) { } -RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberNot) { - SealHandleScope shs(isolate); - ASSERT(args.length() == 1); - - CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); - return isolate->heap()->NumberFromInt32(~x); -} - - RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberShl) { SealHandleScope shs(isolate); ASSERT(args.length() == 2); diff --git a/src/runtime.h b/src/runtime.h index df557c1dc..6b68f241d 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -158,7 +158,6 @@ namespace internal { F(NumberOr, 2, 1) \ F(NumberAnd, 2, 1) \ F(NumberXor, 2, 1) \ - F(NumberNot, 1, 1) \ \ F(NumberShl, 2, 1) \ F(NumberShr, 2, 1) \ diff --git a/src/runtime.js b/src/runtime.js index f1b4585d3..5339570ef 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -294,13 +294,6 @@ function BIT_XOR(y) { } -// ECMA-262, section 11.4.8, page 48. -function BIT_NOT() { - var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); - return %NumberNot(x); -} - - // ECMA-262, section 11.7.1, page 51. function SHL(y) { var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); diff --git a/src/type-info.cc b/src/type-info.cc index 769df07e4..336b459d6 100644 --- a/src/type-info.cc +++ b/src/type-info.cc @@ -384,17 +384,6 @@ void TypeFeedbackOracle::CompareType(TypeFeedbackId id, } -Handle TypeFeedbackOracle::UnaryType(TypeFeedbackId id) { - Handle object = GetInfo(id); - if (!object->IsCode()) { - return handle(Type::None(), isolate()); - } - Handle code = Handle::cast(object); - ASSERT(code->is_unary_op_stub()); - return UnaryOpStub(code->extended_extra_ic_state()).GetType(isolate()); -} - - void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, Handle* left, Handle* right, @@ -658,7 +647,6 @@ void TypeFeedbackOracle::ProcessRelocInfos(ZoneList* infos) { } break; - case Code::UNARY_OP_IC: case Code::BINARY_OP_IC: case Code::COMPARE_IC: case Code::TO_BOOLEAN_IC: diff --git a/src/type-info.h b/src/type-info.h index 1a7c67dfb..4b376c84b 100644 --- a/src/type-info.h +++ b/src/type-info.h @@ -297,7 +297,6 @@ class TypeFeedbackOracle: public ZoneObject { byte ToBooleanTypes(TypeFeedbackId id); // Get type information for arithmetic operations and compares. - Handle UnaryType(TypeFeedbackId id); void BinaryType(TypeFeedbackId id, Handle* left, Handle* right, diff --git a/src/typing.cc b/src/typing.cc index 0611d7e07..df2cee51e 100644 --- a/src/typing.cc +++ b/src/typing.cc @@ -497,8 +497,6 @@ void AstTyper::VisitCallRuntime(CallRuntime* expr) { void AstTyper::VisitUnaryOperation(UnaryOperation* expr) { // Collect type feedback. - Handle op_type = oracle()->UnaryType(expr->UnaryOperationFeedbackId()); - NarrowLowerType(expr->expression(), op_type); if (expr->op() == Token::NOT) { // TODO(rossberg): only do in test or value context. expr->expression()->RecordToBooleanTypeFeedback(oracle()); @@ -514,9 +512,6 @@ void AstTyper::VisitUnaryOperation(UnaryOperation* expr) { case Token::VOID: NarrowType(expr, Bounds(Type::Undefined(), isolate_)); break; - case Token::BIT_NOT: - NarrowType(expr, Bounds(Type::Smi(), Type::Signed32(), isolate_)); - break; case Token::TYPEOF: NarrowType(expr, Bounds(Type::InternalizedString(), isolate_)); break; diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 76479d3e2..ad33a8c63 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -246,17 +246,6 @@ void ToBooleanStub::InitializeInterfaceDescriptor( } -void UnaryOpStub::InitializeInterfaceDescriptor( - Isolate* isolate, - CodeStubInterfaceDescriptor* descriptor) { - static Register registers[] = { rax }; - descriptor->register_param_count_ = 1; - descriptor->register_params_ = registers; - descriptor->deoptimization_handler_ = - FUNCTION_ADDR(UnaryOpIC_Miss); -} - - void StoreGlobalStub::InitializeInterfaceDescriptor( Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index f3e5a5032..6333e87be 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -4335,32 +4335,12 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { break; } - case Token::BIT_NOT: - EmitUnaryOperation(expr, "[ UnaryOperation (BIT_NOT)"); - break; - default: UNREACHABLE(); } } -void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr, - const char* comment) { - ASSERT_EQ(Token::BIT_NOT, expr->op()); - // TODO(svenpanne): Allowing format strings in Comment would be nice here... - Comment cmt(masm_, comment); - UnaryOpStub stub(expr->op()); - // UnaryOpStub expects the argument to be in the - // accumulator register rax. - VisitForAccumulatorValue(expr->expression()); - SetSourcePosition(expr->position()); - CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, - expr->UnaryOperationFeedbackId()); - context()->Plug(rax); -} - - void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { Comment cmnt(masm_, "[ CountOperation"); SetSourcePosition(expr->position()); diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index b129d4b7e..d4c125bcd 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -1270,7 +1270,7 @@ void LCodeGen::DoMulI(LMulI* instr) { bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); if (right->IsConstantOperand()) { - int right_value = ToInteger32(LConstantOperand::cast(right)); + int32_t right_value = ToInteger32(LConstantOperand::cast(right)); if (right_value == -1) { __ negl(left); } else if (right_value == 0) { @@ -1362,7 +1362,7 @@ void LCodeGen::DoBitI(LBitI* instr) { ASSERT(left->IsRegister()); if (right->IsConstantOperand()) { - int right_operand = ToInteger32(LConstantOperand::cast(right)); + int32_t right_operand = ToInteger32(LConstantOperand::cast(right)); switch (instr->op()) { case Token::BIT_AND: __ andl(ToRegister(left), Immediate(right_operand)); @@ -1371,7 +1371,11 @@ void LCodeGen::DoBitI(LBitI* instr) { __ orl(ToRegister(left), Immediate(right_operand)); break; case Token::BIT_XOR: - __ xorl(ToRegister(left), Immediate(right_operand)); + if (right_operand == int32_t(~0)) { + __ not_(ToRegister(left)); + } else { + __ xorl(ToRegister(left), Immediate(right_operand)); + } break; default: UNREACHABLE(); @@ -1442,7 +1446,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { break; } } else { - int value = ToInteger32(LConstantOperand::cast(right)); + int32_t value = ToInteger32(LConstantOperand::cast(right)); uint8_t shift_count = static_cast(value & 0x1F); switch (instr->op()) { case Token::ROR: @@ -1656,13 +1660,6 @@ void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { } -void LCodeGen::DoBitNotI(LBitNotI* instr) { - LOperand* input = instr->value(); - ASSERT(input->Equals(instr->result())); - __ not_(ToRegister(input)); -} - - void LCodeGen::DoThrow(LThrow* instr) { __ push(ToRegister(instr->value())); CallRuntime(Runtime::kThrow, 1, instr); @@ -2898,8 +2895,8 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { if (instr->length()->IsConstantOperand() && instr->index()->IsConstantOperand()) { - int const_index = ToInteger32(LConstantOperand::cast(instr->index())); - int const_length = ToInteger32(LConstantOperand::cast(instr->length())); + int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index())); + int32_t const_length = ToInteger32(LConstantOperand::cast(instr->length())); int index = (const_length - const_index) + 1; __ movq(result, Operand(arguments, index * kPointerSize)); } else { @@ -3086,7 +3083,7 @@ Operand LCodeGen::BuildFastArrayOperand( Register elements_pointer_reg = ToRegister(elements_pointer); int shift_size = ElementsKindToShiftSize(elements_kind); if (key->IsConstantOperand()) { - int constant_value = ToInteger32(LConstantOperand::cast(key)); + int32_t constant_value = ToInteger32(LConstantOperand::cast(key)); if (constant_value & 0xF0000000) { Abort(kArrayIndexConstantValueTooBig); } @@ -4096,7 +4093,7 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { __ AssertZeroExtended(reg); } if (instr->index()->IsConstantOperand()) { - int constant_index = + int32_t constant_index = ToInteger32(LConstantOperand::cast(instr->index())); if (instr->hydrogen()->length()->representation().IsSmi()) { __ Cmp(reg, Smi::FromInt(constant_index)); @@ -4113,7 +4110,7 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { } else { Operand length = ToOperand(instr->length()); if (instr->index()->IsConstantOperand()) { - int constant_index = + int32_t constant_index = ToInteger32(LConstantOperand::cast(instr->index())); if (instr->hydrogen()->length()->representation().IsSmi()) { __ Cmp(length, Smi::FromInt(constant_index)); @@ -4400,7 +4397,7 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { // DoStringCharCodeAt above. STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); if (instr->index()->IsConstantOperand()) { - int const_index = ToInteger32(LConstantOperand::cast(instr->index())); + int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index())); __ Push(Smi::FromInt(const_index)); } else { Register index = ToRegister(instr->index()); diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h index e5e87d0cd..e13422950 100644 --- a/src/x64/lithium-codegen-x64.h +++ b/src/x64/lithium-codegen-x64.h @@ -102,7 +102,6 @@ class LCodeGen BASE_EMBEDDED { XMMRegister ToDoubleRegister(LOperand* op) const; bool IsInteger32Constant(LConstantOperand* op) const; bool IsSmiConstant(LConstantOperand* op) const; - int ToRepresentation(LConstantOperand* op, const Representation& r) const; int32_t ToInteger32(LConstantOperand* op) const; Smi* ToSmi(LConstantOperand* op) const; double ToDouble(LConstantOperand* op) const; diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 6be237351..913e17059 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -1321,16 +1321,6 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { } -LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { - ASSERT(instr->value()->representation().IsInteger32()); - ASSERT(instr->representation().IsInteger32()); - if (instr->HasNoUses()) return NULL; - LOperand* input = UseRegisterAtStart(instr->value()); - LBitNotI* result = new(zone()) LBitNotI(input); - return DefineSameAsFirst(result); -} - - LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { if (instr->representation().IsDouble()) { return DoArithmeticD(Token::DIV, instr); diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index 6716f4847..c3b9db4c5 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -50,7 +50,6 @@ class LCodeGen; V(ArithmeticD) \ V(ArithmeticT) \ V(BitI) \ - V(BitNotI) \ V(BoundsCheck) \ V(Branch) \ V(CallConstantFunction) \ @@ -1311,18 +1310,6 @@ class LThrow: public LTemplateInstruction<0, 1, 0> { }; -class LBitNotI: public LTemplateInstruction<1, 1, 0> { - public: - explicit LBitNotI(LOperand* value) { - inputs_[0] = value; - } - - LOperand* value() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i") -}; - - class LAddI: public LTemplateInstruction<1, 2, 0> { public: LAddI(LOperand* left, LOperand* right) {