| OLD | NEW | 
|    1 // Copyright 2015 the V8 project authors. All rights reserved. |    1 // Copyright 2015 the V8 project authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "src/interpreter/bytecodes.h" |    5 #include "src/interpreter/bytecodes.h" | 
|    6  |    6  | 
|    7 #include <iomanip> |    7 #include <iomanip> | 
|    8  |    8  | 
|    9 #include "src/frames.h" |    9 #include "src/frames.h" | 
|   10 #include "src/interpreter/bytecode-traits.h" |   10 #include "src/interpreter/bytecode-traits.h" | 
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   67     OPERAND_TYPE_LIST(CASE) |   67     OPERAND_TYPE_LIST(CASE) | 
|   68 #undef CASE |   68 #undef CASE | 
|   69   } |   69   } | 
|   70   UNREACHABLE(); |   70   UNREACHABLE(); | 
|   71   return ""; |   71   return ""; | 
|   72 } |   72 } | 
|   73  |   73  | 
|   74 // static |   74 // static | 
|   75 const char* Bytecodes::OperandScaleToString(OperandScale operand_scale) { |   75 const char* Bytecodes::OperandScaleToString(OperandScale operand_scale) { | 
|   76   switch (operand_scale) { |   76   switch (operand_scale) { | 
|   77     case OperandScale::kSingle: |   77 #define CASE(Name, _)         \ | 
|   78       return "Single"; |   78   case OperandScale::k##Name: \ | 
|   79     case OperandScale::kDouble: |   79     return #Name; | 
|   80       return "Double"; |   80     OPERAND_SCALE_LIST(CASE) | 
|   81     case OperandScale::kQuadruple: |   81 #undef CASE | 
|   82       return "Quadruple"; |  | 
|   83     case OperandScale::kInvalid: |  | 
|   84       UNREACHABLE(); |  | 
|   85   } |   82   } | 
 |   83   UNREACHABLE(); | 
|   86   return ""; |   84   return ""; | 
|   87 } |   85 } | 
|   88  |   86  | 
|   89 // static |   87 // static | 
|   90 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) { |   88 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) { | 
|   91   switch (operand_size) { |   89   switch (operand_size) { | 
|   92     case OperandSize::kNone: |   90     case OperandSize::kNone: | 
|   93       return "None"; |   91       return "None"; | 
|   94     case OperandSize::kByte: |   92     case OperandSize::kByte: | 
|   95       return "Byte"; |   93       return "Byte"; | 
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  234          AccumulatorUse::kRead; |  232          AccumulatorUse::kRead; | 
|  235 } |  233 } | 
|  236  |  234  | 
|  237 // static |  235 // static | 
|  238 bool Bytecodes::WritesAccumulator(Bytecode bytecode) { |  236 bool Bytecodes::WritesAccumulator(Bytecode bytecode) { | 
|  239   return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) == |  237   return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) == | 
|  240          AccumulatorUse::kWrite; |  238          AccumulatorUse::kWrite; | 
|  241 } |  239 } | 
|  242  |  240  | 
|  243 // static |  241 // static | 
 |  242 bool Bytecodes::WritesBooleanToAccumulator(Bytecode bytecode) { | 
 |  243   switch (bytecode) { | 
 |  244     case Bytecode::kLdaTrue: | 
 |  245     case Bytecode::kLdaFalse: | 
 |  246     case Bytecode::kLogicalNot: | 
 |  247     case Bytecode::kTestEqual: | 
 |  248     case Bytecode::kTestNotEqual: | 
 |  249     case Bytecode::kTestEqualStrict: | 
 |  250     case Bytecode::kTestLessThan: | 
 |  251     case Bytecode::kTestLessThanOrEqual: | 
 |  252     case Bytecode::kTestGreaterThan: | 
 |  253     case Bytecode::kTestGreaterThanOrEqual: | 
 |  254     case Bytecode::kTestInstanceOf: | 
 |  255     case Bytecode::kTestIn: | 
 |  256     case Bytecode::kForInDone: | 
 |  257       return true; | 
 |  258     default: | 
 |  259       return false; | 
 |  260   } | 
 |  261 } | 
 |  262  | 
 |  263 // static | 
 |  264 bool Bytecodes::IsAccumulatorLoadWithoutEffects(Bytecode bytecode) { | 
 |  265   switch (bytecode) { | 
 |  266     case Bytecode::kLdaZero: | 
 |  267     case Bytecode::kLdaSmi: | 
 |  268     case Bytecode::kLdaUndefined: | 
 |  269     case Bytecode::kLdaNull: | 
 |  270     case Bytecode::kLdaTheHole: | 
 |  271     case Bytecode::kLdaTrue: | 
 |  272     case Bytecode::kLdaFalse: | 
 |  273     case Bytecode::kLdaConstant: | 
 |  274     case Bytecode::kLdar: | 
 |  275       return true; | 
 |  276     default: | 
 |  277       return false; | 
 |  278   } | 
 |  279 } | 
 |  280  | 
 |  281 // static | 
|  244 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) { |  282 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) { | 
 |  283   DCHECK_LE(bytecode, Bytecode::kLast); | 
 |  284   DCHECK_LT(i, NumberOfOperands(bytecode)); | 
 |  285   DCHECK_GE(i, 0); | 
 |  286   return GetOperandTypes(bytecode)[i]; | 
 |  287 } | 
 |  288  | 
 |  289 // static | 
 |  290 const OperandType* Bytecodes::GetOperandTypes(Bytecode bytecode) { | 
|  245   DCHECK(bytecode <= Bytecode::kLast); |  291   DCHECK(bytecode <= Bytecode::kLast); | 
|  246   switch (bytecode) { |  292   switch (bytecode) { | 
|  247 #define CASE(Name, ...)   \ |  293 #define CASE(Name, ...)   \ | 
|  248   case Bytecode::k##Name: \ |  294   case Bytecode::k##Name: \ | 
|  249     return BytecodeTraits<__VA_ARGS__>::GetOperandType(i); |  295     return BytecodeTraits<__VA_ARGS__>::GetOperandTypes(); | 
|  250     BYTECODE_LIST(CASE) |  296     BYTECODE_LIST(CASE) | 
|  251 #undef CASE |  297 #undef CASE | 
|  252   } |  298   } | 
|  253   UNREACHABLE(); |  299   UNREACHABLE(); | 
|  254   return OperandType::kNone; |  300   return nullptr; | 
|  255 } |  301 } | 
|  256  |  302  | 
|  257 // static |  303 // static | 
|  258 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i, |  304 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i, | 
|  259                                       OperandScale operand_scale) { |  305                                       OperandScale operand_scale) { | 
|  260   OperandType op_type = GetOperandType(bytecode, i); |  306   DCHECK(bytecode <= Bytecode::kLast); | 
|  261   return ScaledOperandSize(op_type, operand_scale); |  307   switch (bytecode) { | 
 |  308 #define CASE(Name, ...)   \ | 
 |  309   case Bytecode::k##Name: \ | 
 |  310     return BytecodeTraits<__VA_ARGS__>::GetOperandSize(i, operand_scale); | 
 |  311     BYTECODE_LIST(CASE) | 
 |  312 #undef CASE | 
 |  313   } | 
 |  314   UNREACHABLE(); | 
 |  315   return OperandSize::kNone; | 
|  262 } |  316 } | 
|  263  |  317  | 
|  264 // static |  318 // static | 
|  265 int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) { |  319 int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) { | 
|  266   DCHECK(bytecode <= Bytecode::kLast); |  320   DCHECK(bytecode <= Bytecode::kLast); | 
|  267   switch (bytecode) { |  321   switch (bytecode) { | 
|  268 #define CASE(Name, ...)                              \ |  322 #define CASE(Name, ...)                              \ | 
|  269   case Bytecode::k##Name:                            \ |  323   case Bytecode::k##Name:                            \ | 
|  270     typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \ |  324     typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \ | 
|  271     return Name##Trait::kRegisterOperandBitmap; |  325     return Name##Trait::kRegisterOperandBitmap; | 
|  272     BYTECODE_LIST(CASE) |  326     BYTECODE_LIST(CASE) | 
|  273 #undef CASE |  327 #undef CASE | 
|  274   } |  328   } | 
|  275   UNREACHABLE(); |  329   UNREACHABLE(); | 
|  276   return false; |  330   return false; | 
|  277 } |  331 } | 
|  278  |  332  | 
|  279 // static |  333 // static | 
|  280 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i, |  334 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i, | 
|  281                                 OperandScale operand_scale) { |  335                                 OperandScale operand_scale) { | 
 |  336   DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode)); | 
|  282   // TODO(oth): restore this to a statically determined constant. |  337   // TODO(oth): restore this to a statically determined constant. | 
|  283   int offset = 1; |  338   int offset = 1; | 
|  284   for (int operand_index = 0; operand_index < i; ++operand_index) { |  339   for (int operand_index = 0; operand_index < i; ++operand_index) { | 
|  285     OperandSize operand_size = |  340     OperandSize operand_size = | 
|  286         GetOperandSize(bytecode, operand_index, operand_scale); |  341         GetOperandSize(bytecode, operand_index, operand_scale); | 
|  287     offset += static_cast<int>(operand_size); |  342     offset += static_cast<int>(operand_size); | 
|  288   } |  343   } | 
|  289   return offset; |  344   return offset; | 
|  290 } |  345 } | 
|  291  |  346  | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  336 bool Bytecodes::IsJumpConstant(Bytecode bytecode) { |  391 bool Bytecodes::IsJumpConstant(Bytecode bytecode) { | 
|  337   return bytecode == Bytecode::kJumpConstant || |  392   return bytecode == Bytecode::kJumpConstant || | 
|  338          IsConditionalJumpConstant(bytecode); |  393          IsConditionalJumpConstant(bytecode); | 
|  339 } |  394 } | 
|  340  |  395  | 
|  341 // static |  396 // static | 
|  342 bool Bytecodes::IsJump(Bytecode bytecode) { |  397 bool Bytecodes::IsJump(Bytecode bytecode) { | 
|  343   return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode); |  398   return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode); | 
|  344 } |  399 } | 
|  345  |  400  | 
 |  401 // static | 
 |  402 bool Bytecodes::IsJumpIfToBoolean(Bytecode bytecode) { | 
 |  403   return bytecode == Bytecode::kJumpIfToBooleanTrue || | 
 |  404          bytecode == Bytecode::kJumpIfToBooleanFalse || | 
 |  405          bytecode == Bytecode::kJumpIfToBooleanTrueConstant || | 
 |  406          bytecode == Bytecode::kJumpIfToBooleanFalseConstant; | 
 |  407 } | 
 |  408  | 
 |  409 // static | 
 |  410 Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) { | 
 |  411   switch (bytecode) { | 
 |  412     case Bytecode::kJumpIfToBooleanTrue: | 
 |  413       return Bytecode::kJumpIfTrue; | 
 |  414     case Bytecode::kJumpIfToBooleanFalse: | 
 |  415       return Bytecode::kJumpIfFalse; | 
 |  416     case Bytecode::kJumpIfToBooleanTrueConstant: | 
 |  417       return Bytecode::kJumpIfTrueConstant; | 
 |  418     case Bytecode::kJumpIfToBooleanFalseConstant: | 
 |  419       return Bytecode::kJumpIfFalseConstant; | 
 |  420     default: | 
 |  421       break; | 
 |  422   } | 
 |  423   UNREACHABLE(); | 
 |  424   return Bytecode::kIllegal; | 
 |  425 } | 
|  346  |  426  | 
|  347 // static |  427 // static | 
|  348 bool Bytecodes::IsCallOrNew(Bytecode bytecode) { |  428 bool Bytecodes::IsCallOrNew(Bytecode bytecode) { | 
|  349   return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall || |  429   return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall || | 
|  350          bytecode == Bytecode::kNew; |  430          bytecode == Bytecode::kNew; | 
|  351 } |  431 } | 
|  352  |  432  | 
|  353 // static |  433 // static | 
|  354 bool Bytecodes::IsCallRuntime(Bytecode bytecode) { |  434 bool Bytecodes::IsCallRuntime(Bytecode bytecode) { | 
|  355   return bytecode == Bytecode::kCallRuntime || |  435   return bytecode == Bytecode::kCallRuntime || | 
|  356          bytecode == Bytecode::kCallRuntimeForPair || |  436          bytecode == Bytecode::kCallRuntimeForPair || | 
|  357          bytecode == Bytecode::kInvokeIntrinsic; |  437          bytecode == Bytecode::kInvokeIntrinsic; | 
|  358 } |  438 } | 
|  359  |  439  | 
|  360 // static |  440 // static | 
|  361 bool Bytecodes::IsDebugBreak(Bytecode bytecode) { |  441 bool Bytecodes::IsDebugBreak(Bytecode bytecode) { | 
|  362   switch (bytecode) { |  442   switch (bytecode) { | 
|  363 #define CASE(Name, ...) case Bytecode::k##Name: |  443 #define CASE(Name, ...) case Bytecode::k##Name: | 
|  364     DEBUG_BREAK_BYTECODE_LIST(CASE); |  444     DEBUG_BREAK_BYTECODE_LIST(CASE); | 
|  365 #undef CASE |  445 #undef CASE | 
|  366     return true; |  446     return true; | 
|  367     default: |  447     default: | 
|  368       break; |  448       break; | 
|  369   } |  449   } | 
|  370   return false; |  450   return false; | 
|  371 } |  451 } | 
|  372  |  452  | 
|  373 // static |  453 // static | 
 |  454 bool Bytecodes::IsLdarOrStar(Bytecode bytecode) { | 
 |  455   return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar; | 
 |  456 } | 
 |  457  | 
 |  458 // static | 
|  374 bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) { |  459 bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) { | 
|  375   switch (bytecode) { |  460   switch (bytecode) { | 
|  376 #define CASE(Name, ...)                              \ |  461 #define CASE(Name, ...)                              \ | 
|  377   case Bytecode::k##Name:                            \ |  462   case Bytecode::k##Name:                            \ | 
|  378     typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \ |  463     typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \ | 
|  379     return Name##Trait::IsScalable(); |  464     return Name##Trait::IsScalable(); | 
|  380     BYTECODE_LIST(CASE) |  465     BYTECODE_LIST(CASE) | 
|  381 #undef CASE |  466 #undef CASE | 
|  382   } |  467   } | 
|  383   UNREACHABLE(); |  468   UNREACHABLE(); | 
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  454   case OperandType::k##Name: \ |  539   case OperandType::k##Name: \ | 
|  455     break; |  540     break; | 
|  456     NON_REGISTER_OPERAND_TYPE_LIST(CASE) |  541     NON_REGISTER_OPERAND_TYPE_LIST(CASE) | 
|  457     REGISTER_INPUT_OPERAND_TYPE_LIST(CASE) |  542     REGISTER_INPUT_OPERAND_TYPE_LIST(CASE) | 
|  458 #undef CASE |  543 #undef CASE | 
|  459   } |  544   } | 
|  460   return false; |  545   return false; | 
|  461 } |  546 } | 
|  462  |  547  | 
|  463 // static |  548 // static | 
 |  549 int Bytecodes::GetNumberOfRegistersRepresentedBy(OperandType operand_type) { | 
 |  550   switch (operand_type) { | 
 |  551     case OperandType::kMaybeReg: | 
 |  552     case OperandType::kReg: | 
 |  553     case OperandType::kRegOut: | 
 |  554       return 1; | 
 |  555     case OperandType::kRegPair: | 
 |  556     case OperandType::kRegOutPair: | 
 |  557       return 2; | 
 |  558     case OperandType::kRegOutTriple: | 
 |  559       return 3; | 
 |  560     default: | 
 |  561       UNREACHABLE(); | 
 |  562   } | 
 |  563   return 0; | 
 |  564 } | 
 |  565  | 
 |  566 // static | 
|  464 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) { |  567 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) { | 
|  465   switch (operand_type) { |  568   switch (operand_type) { | 
|  466 #define CASE(Name, _)        \ |  569 #define CASE(Name, _)        \ | 
|  467   case OperandType::k##Name: \ |  570   case OperandType::k##Name: \ | 
|  468     return OperandTraits<OperandType::k##Name>::TypeInfo::kIsUnsigned; |  571     return OperandTraits<OperandType::k##Name>::TypeInfo::kIsUnsigned; | 
|  469     OPERAND_TYPE_LIST(CASE) |  572     OPERAND_TYPE_LIST(CASE) | 
|  470 #undef CASE |  573 #undef CASE | 
|  471   } |  574   } | 
|  472   UNREACHABLE(); |  575   UNREACHABLE(); | 
|  473   return false; |  576   return false; | 
|  474 } |  577 } | 
|  475  |  578  | 
|  476 // static |  579 // static | 
|  477 OperandScale Bytecodes::NextOperandScale(OperandScale operand_scale) { |  580 OperandSize Bytecodes::SizeForSignedOperand(int value) { | 
|  478   DCHECK(operand_scale >= OperandScale::kSingle && |  581   if (kMinInt8 <= value && value <= kMaxInt8) { | 
|  479          operand_scale <= OperandScale::kMaxValid); |  582     return OperandSize::kByte; | 
|  480   return static_cast<OperandScale>(2 * static_cast<int>(operand_scale)); |  583   } else if (kMinInt16 <= value && value <= kMaxInt16) { | 
 |  584     return OperandSize::kShort; | 
 |  585   } else { | 
 |  586     return OperandSize::kQuad; | 
 |  587   } | 
|  481 } |  588 } | 
|  482  |  589  | 
|  483 // static |  590 // static | 
 |  591 OperandSize Bytecodes::SizeForUnsignedOperand(int value) { | 
 |  592   DCHECK_GE(value, 0); | 
 |  593   if (value <= kMaxUInt8) { | 
 |  594     return OperandSize::kByte; | 
 |  595   } else if (value <= kMaxUInt16) { | 
 |  596     return OperandSize::kShort; | 
 |  597   } else { | 
 |  598     return OperandSize::kQuad; | 
 |  599   } | 
 |  600 } | 
 |  601  | 
 |  602 OperandSize Bytecodes::SizeForUnsignedOperand(size_t value) { | 
 |  603   if (value <= static_cast<size_t>(kMaxUInt8)) { | 
 |  604     return OperandSize::kByte; | 
 |  605   } else if (value <= static_cast<size_t>(kMaxUInt16)) { | 
 |  606     return OperandSize::kShort; | 
 |  607   } else if (value <= kMaxUInt32) { | 
 |  608     return OperandSize::kQuad; | 
 |  609   } else { | 
 |  610     UNREACHABLE(); | 
 |  611     return OperandSize::kQuad; | 
 |  612   } | 
 |  613 } | 
 |  614  | 
 |  615 OperandScale Bytecodes::OperandSizesToScale(OperandSize size0, | 
 |  616                                             OperandSize size1, | 
 |  617                                             OperandSize size2, | 
 |  618                                             OperandSize size3) { | 
 |  619   OperandSize upper = std::max(size0, size1); | 
 |  620   OperandSize lower = std::max(size2, size3); | 
 |  621   OperandSize result = std::max(upper, lower); | 
 |  622   // Operand sizes have been scaled before calling this function. | 
 |  623   // Currently all scalable operands are byte sized at | 
 |  624   // OperandScale::kSingle. | 
 |  625   STATIC_ASSERT(static_cast<int>(OperandSize::kByte) == | 
 |  626                     static_cast<int>(OperandScale::kSingle) && | 
 |  627                 static_cast<int>(OperandSize::kShort) == | 
 |  628                     static_cast<int>(OperandScale::kDouble) && | 
 |  629                 static_cast<int>(OperandSize::kQuad) == | 
 |  630                     static_cast<int>(OperandScale::kQuadruple)); | 
 |  631   OperandScale operand_scale = static_cast<OperandScale>(result); | 
 |  632   DCHECK(operand_scale == OperandScale::kSingle || | 
 |  633          operand_scale == OperandScale::kDouble || | 
 |  634          operand_scale == OperandScale::kQuadruple); | 
 |  635   return operand_scale; | 
 |  636 } | 
 |  637  | 
 |  638 // static | 
|  484 Register Bytecodes::DecodeRegisterOperand(const uint8_t* operand_start, |  639 Register Bytecodes::DecodeRegisterOperand(const uint8_t* operand_start, | 
|  485                                           OperandType operand_type, |  640                                           OperandType operand_type, | 
|  486                                           OperandScale operand_scale) { |  641                                           OperandScale operand_scale) { | 
|  487   DCHECK(Bytecodes::IsRegisterOperandType(operand_type)); |  642   DCHECK(Bytecodes::IsRegisterOperandType(operand_type)); | 
|  488   int32_t operand = |  643   int32_t operand = | 
|  489       DecodeSignedOperand(operand_start, operand_type, operand_scale); |  644       DecodeSignedOperand(operand_start, operand_type, operand_scale); | 
|  490   return Register::FromOperand(operand); |  645   return Register::FromOperand(operand); | 
|  491 } |  646 } | 
|  492  |  647  | 
|  493 // static |  648 // static | 
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  767   } else { |  922   } else { | 
|  768     std::ostringstream s; |  923     std::ostringstream s; | 
|  769     s << "r" << index(); |  924     s << "r" << index(); | 
|  770     return s.str(); |  925     return s.str(); | 
|  771   } |  926   } | 
|  772 } |  927 } | 
|  773  |  928  | 
|  774 }  // namespace interpreter |  929 }  // namespace interpreter | 
|  775 }  // namespace internal |  930 }  // namespace internal | 
|  776 }  // namespace v8 |  931 }  // namespace v8 | 
| OLD | NEW |