| 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/bytecode-array-builder.h" | 5 #include "src/interpreter/bytecode-array-builder.h" |
| 6 |
| 6 #include "src/compiler.h" | 7 #include "src/compiler.h" |
| 8 #include "src/interpreter/bytecode-array-writer.h" |
| 9 #include "src/interpreter/bytecode-peephole-optimizer.h" |
| 7 #include "src/interpreter/interpreter-intrinsics.h" | 10 #include "src/interpreter/interpreter-intrinsics.h" |
| 8 | 11 |
| 9 namespace v8 { | 12 namespace v8 { |
| 10 namespace internal { | 13 namespace internal { |
| 11 namespace interpreter { | 14 namespace interpreter { |
| 12 | 15 |
| 13 class BytecodeArrayBuilder::PreviousBytecodeHelper BASE_EMBEDDED { | |
| 14 public: | |
| 15 explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder) | |
| 16 : array_builder_(array_builder), | |
| 17 previous_bytecode_start_(array_builder_.last_bytecode_start_) { | |
| 18 // This helper is expected to be instantiated only when the last bytecode is | |
| 19 // in the same basic block. | |
| 20 DCHECK(array_builder_.LastBytecodeInSameBlock()); | |
| 21 bytecode_ = Bytecodes::FromByte( | |
| 22 array_builder_.bytecodes()->at(previous_bytecode_start_)); | |
| 23 operand_scale_ = OperandScale::kSingle; | |
| 24 if (Bytecodes::IsPrefixScalingBytecode(bytecode_)) { | |
| 25 operand_scale_ = Bytecodes::PrefixBytecodeToOperandScale(bytecode_); | |
| 26 bytecode_ = Bytecodes::FromByte( | |
| 27 array_builder_.bytecodes()->at(previous_bytecode_start_ + 1)); | |
| 28 } | |
| 29 } | |
| 30 | |
| 31 // Returns the previous bytecode in the same basic block. | |
| 32 MUST_USE_RESULT Bytecode GetBytecode() const { | |
| 33 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); | |
| 34 return bytecode_; | |
| 35 } | |
| 36 | |
| 37 MUST_USE_RESULT Register GetRegisterOperand(int operand_index) const { | |
| 38 return Register::FromOperand(GetSignedOperand(operand_index)); | |
| 39 } | |
| 40 | |
| 41 MUST_USE_RESULT uint32_t GetIndexOperand(int operand_index) const { | |
| 42 return GetUnsignedOperand(operand_index); | |
| 43 } | |
| 44 | |
| 45 Handle<Object> GetConstantForIndexOperand(int operand_index) const { | |
| 46 return array_builder_.constant_array_builder()->At( | |
| 47 GetIndexOperand(operand_index)); | |
| 48 } | |
| 49 | |
| 50 private: | |
| 51 // Returns the signed operand at operand_index for the previous | |
| 52 // bytecode in the same basic block. | |
| 53 MUST_USE_RESULT int32_t GetSignedOperand(int operand_index) const { | |
| 54 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); | |
| 55 OperandType operand_type = | |
| 56 Bytecodes::GetOperandType(bytecode_, operand_index); | |
| 57 DCHECK(!Bytecodes::IsUnsignedOperandType(operand_type)); | |
| 58 const uint8_t* operand_start = GetOperandStart(operand_index); | |
| 59 return Bytecodes::DecodeSignedOperand(operand_start, operand_type, | |
| 60 operand_scale_); | |
| 61 } | |
| 62 | |
| 63 // Returns the unsigned operand at operand_index for the previous | |
| 64 // bytecode in the same basic block. | |
| 65 MUST_USE_RESULT uint32_t GetUnsignedOperand(int operand_index) const { | |
| 66 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); | |
| 67 OperandType operand_type = | |
| 68 Bytecodes::GetOperandType(bytecode_, operand_index); | |
| 69 DCHECK(Bytecodes::IsUnsignedOperandType(operand_type)); | |
| 70 const uint8_t* operand_start = GetOperandStart(operand_index); | |
| 71 return Bytecodes::DecodeUnsignedOperand(operand_start, operand_type, | |
| 72 operand_scale_); | |
| 73 } | |
| 74 | |
| 75 const uint8_t* GetOperandStart(int operand_index) const { | |
| 76 size_t operand_offset = | |
| 77 previous_bytecode_start_ + prefix_offset() + | |
| 78 Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale_); | |
| 79 return &(*array_builder_.bytecodes())[0] + operand_offset; | |
| 80 } | |
| 81 | |
| 82 int prefix_offset() const { | |
| 83 return Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale_) ? 1 | |
| 84 : 0; | |
| 85 } | |
| 86 | |
| 87 const BytecodeArrayBuilder& array_builder_; | |
| 88 OperandScale operand_scale_; | |
| 89 Bytecode bytecode_; | |
| 90 size_t previous_bytecode_start_; | |
| 91 | |
| 92 DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper); | |
| 93 }; | |
| 94 | |
| 95 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone, | 16 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone, |
| 96 int parameter_count, | 17 int parameter_count, |
| 97 int context_count, int locals_count, | 18 int context_count, int locals_count, |
| 98 FunctionLiteral* literal) | 19 FunctionLiteral* literal) |
| 99 : isolate_(isolate), | 20 : isolate_(isolate), |
| 100 zone_(zone), | 21 zone_(zone), |
| 101 bytecodes_(zone), | |
| 102 bytecode_generated_(false), | 22 bytecode_generated_(false), |
| 103 constant_array_builder_(isolate, zone), | 23 constant_array_builder_(isolate, zone), |
| 104 handler_table_builder_(isolate, zone), | 24 handler_table_builder_(isolate, zone), |
| 105 source_position_table_builder_(isolate, zone), | 25 source_position_table_builder_(isolate, zone), |
| 106 last_block_end_(0), | |
| 107 last_bytecode_start_(~0), | |
| 108 exit_seen_in_block_(false), | 26 exit_seen_in_block_(false), |
| 109 unbound_jumps_(0), | 27 unbound_jumps_(0), |
| 110 parameter_count_(parameter_count), | 28 parameter_count_(parameter_count), |
| 111 local_register_count_(locals_count), | 29 local_register_count_(locals_count), |
| 112 context_register_count_(context_count), | 30 context_register_count_(context_count), |
| 113 temporary_allocator_(zone, fixed_register_count()) { | 31 temporary_allocator_(zone, fixed_register_count()), |
| 32 bytecode_array_writer_(zone, &source_position_table_builder_), |
| 33 pipeline_(&bytecode_array_writer_) { |
| 114 DCHECK_GE(parameter_count_, 0); | 34 DCHECK_GE(parameter_count_, 0); |
| 115 DCHECK_GE(context_register_count_, 0); | 35 DCHECK_GE(context_register_count_, 0); |
| 116 DCHECK_GE(local_register_count_, 0); | 36 DCHECK_GE(local_register_count_, 0); |
| 37 |
| 38 if (FLAG_ignition_peephole) { |
| 39 pipeline_ = new (zone) |
| 40 BytecodePeepholeOptimizer(&constant_array_builder_, pipeline_); |
| 41 } |
| 42 |
| 117 return_position_ = | 43 return_position_ = |
| 118 literal ? std::max(literal->start_position(), literal->end_position() - 1) | 44 literal ? std::max(literal->start_position(), literal->end_position() - 1) |
| 119 : RelocInfo::kNoPosition; | 45 : RelocInfo::kNoPosition; |
| 120 LOG_CODE_EVENT(isolate_, CodeStartLinePosInfoRecordEvent( | 46 LOG_CODE_EVENT(isolate_, CodeStartLinePosInfoRecordEvent( |
| 121 source_position_table_builder())); | 47 source_position_table_builder())); |
| 122 } | 48 } |
| 123 | 49 |
| 124 Register BytecodeArrayBuilder::first_context_register() const { | 50 Register BytecodeArrayBuilder::first_context_register() const { |
| 125 DCHECK_GT(context_register_count_, 0); | 51 DCHECK_GT(context_register_count_, 0); |
| 126 return Register(local_register_count_); | 52 return Register(local_register_count_); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 142 bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const { | 68 bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const { |
| 143 return reg.is_parameter() || reg.index() < locals_count(); | 69 return reg.is_parameter() || reg.index() < locals_count(); |
| 144 } | 70 } |
| 145 | 71 |
| 146 | 72 |
| 147 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { | 73 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { |
| 148 DCHECK_EQ(0, unbound_jumps_); | 74 DCHECK_EQ(0, unbound_jumps_); |
| 149 DCHECK_EQ(bytecode_generated_, false); | 75 DCHECK_EQ(bytecode_generated_, false); |
| 150 DCHECK(exit_seen_in_block_); | 76 DCHECK(exit_seen_in_block_); |
| 151 | 77 |
| 152 int bytecode_size = static_cast<int>(bytecodes_.size()); | 78 pipeline()->FlushBasicBlock(); |
| 153 int register_count = fixed_and_temporary_register_count(); | 79 const ZoneVector<uint8_t>* bytecodes = bytecode_array_writer()->bytecodes(); |
| 154 int frame_size = register_count * kPointerSize; | 80 |
| 81 int bytecode_size = static_cast<int>(bytecodes->size()); |
| 82 |
| 83 // All locals need a frame slot for the debugger, but may not be |
| 84 // present in generated code. |
| 85 int frame_size_for_locals = fixed_register_count() * kPointerSize; |
| 86 int frame_size_measured = bytecode_array_writer()->GetMeasuredFrameSize(); |
| 87 int frame_size = std::max(frame_size_for_locals, frame_size_measured); |
| 155 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray(); | 88 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray(); |
| 156 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); | 89 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); |
| 157 Handle<ByteArray> source_position_table = | 90 Handle<ByteArray> source_position_table = |
| 158 source_position_table_builder()->ToSourcePositionTable(); | 91 source_position_table_builder()->ToSourcePositionTable(); |
| 159 Handle<BytecodeArray> bytecode_array = isolate_->factory()->NewBytecodeArray( | 92 Handle<BytecodeArray> bytecode_array = isolate_->factory()->NewBytecodeArray( |
| 160 bytecode_size, &bytecodes_.front(), frame_size, parameter_count(), | 93 bytecode_size, &bytecodes->front(), frame_size, parameter_count(), |
| 161 constant_pool); | 94 constant_pool); |
| 162 bytecode_array->set_handler_table(*handler_table); | 95 bytecode_array->set_handler_table(*handler_table); |
| 163 bytecode_array->set_source_position_table(*source_position_table); | 96 bytecode_array->set_source_position_table(*source_position_table); |
| 164 | 97 |
| 165 void* line_info = source_position_table_builder()->DetachJITHandlerData(); | 98 void* line_info = source_position_table_builder()->DetachJITHandlerData(); |
| 166 LOG_CODE_EVENT(isolate_, CodeEndLinePosInfoRecordEvent( | 99 LOG_CODE_EVENT(isolate_, CodeEndLinePosInfoRecordEvent( |
| 167 AbstractCode::cast(*bytecode_array), line_info)); | 100 AbstractCode::cast(*bytecode_array), line_info)); |
| 168 | 101 |
| 169 bytecode_generated_ = true; | 102 bytecode_generated_ = true; |
| 170 return bytecode_array; | 103 return bytecode_array; |
| 171 } | 104 } |
| 172 | 105 |
| 173 template <size_t N> | |
| 174 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t (&operands)[N], | |
| 175 OperandScale operand_scale) { | |
| 176 // Don't output dead code. | |
| 177 if (exit_seen_in_block_) return; | |
| 178 | |
| 179 int operand_count = static_cast<int>(N); | |
| 180 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count); | |
| 181 | |
| 182 last_bytecode_start_ = bytecodes()->size(); | |
| 183 // Emit prefix bytecode for scale if required. | |
| 184 if (Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale)) { | |
| 185 bytecodes()->push_back(Bytecodes::ToByte( | |
| 186 Bytecodes::OperandScaleToPrefixBytecode(operand_scale))); | |
| 187 } | |
| 188 | |
| 189 // Emit bytecode. | |
| 190 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | |
| 191 | |
| 192 // Emit operands. | |
| 193 for (int i = 0; i < operand_count; i++) { | |
| 194 DCHECK(OperandIsValid(bytecode, operand_scale, i, operands[i])); | |
| 195 switch (Bytecodes::GetOperandSize(bytecode, i, operand_scale)) { | |
| 196 case OperandSize::kNone: | |
| 197 UNREACHABLE(); | |
| 198 break; | |
| 199 case OperandSize::kByte: | |
| 200 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); | |
| 201 break; | |
| 202 case OperandSize::kShort: { | |
| 203 uint8_t operand_bytes[2]; | |
| 204 WriteUnalignedUInt16(operand_bytes, operands[i]); | |
| 205 bytecodes()->insert(bytecodes()->end(), operand_bytes, | |
| 206 operand_bytes + 2); | |
| 207 break; | |
| 208 } | |
| 209 case OperandSize::kQuad: { | |
| 210 uint8_t operand_bytes[4]; | |
| 211 WriteUnalignedUInt32(operand_bytes, operands[i]); | |
| 212 bytecodes()->insert(bytecodes()->end(), operand_bytes, | |
| 213 operand_bytes + 4); | |
| 214 break; | |
| 215 } | |
| 216 } | |
| 217 } | |
| 218 } | |
| 219 | |
| 220 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | 106 void BytecodeArrayBuilder::Output(Bytecode bytecode) { |
| 221 // Don't output dead code. | 107 // Don't output dead code. |
| 222 if (exit_seen_in_block_) return; | 108 if (exit_seen_in_block_) return; |
| 223 | 109 |
| 224 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); | 110 BytecodeNode node(bytecode); |
| 225 last_bytecode_start_ = bytecodes()->size(); | 111 if (latest_source_info_.is_valid()) { |
| 226 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | 112 node.source_info().Update(latest_source_info_); |
| 113 latest_source_info_.set_invalid(); |
| 114 } |
| 115 pipeline()->Write(&node); |
| 227 } | 116 } |
| 228 | 117 |
| 229 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | 118 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, |
| 230 OperandScale operand_scale, | 119 OperandScale operand_scale, |
| 231 uint32_t operand0, uint32_t operand1, | 120 uint32_t operand0, uint32_t operand1, |
| 232 uint32_t operand2, uint32_t operand3) { | 121 uint32_t operand2, uint32_t operand3) { |
| 233 uint32_t operands[] = {operand0, operand1, operand2, operand3}; | 122 // Don't output dead code. |
| 234 Output(bytecode, operands, operand_scale); | 123 if (exit_seen_in_block_) return; |
| 124 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); |
| 125 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1)); |
| 126 DCHECK(OperandIsValid(bytecode, operand_scale, 2, operand2)); |
| 127 DCHECK(OperandIsValid(bytecode, operand_scale, 3, operand3)); |
| 128 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3, |
| 129 operand_scale); |
| 130 if (latest_source_info_.is_valid()) { |
| 131 node.source_info().Update(latest_source_info_); |
| 132 latest_source_info_.set_invalid(); |
| 133 } |
| 134 pipeline()->Write(&node); |
| 235 } | 135 } |
| 236 | 136 |
| 237 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | 137 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, |
| 238 OperandScale operand_scale, | 138 OperandScale operand_scale, |
| 239 uint32_t operand0, uint32_t operand1, | 139 uint32_t operand0, uint32_t operand1, |
| 240 uint32_t operand2) { | 140 uint32_t operand2) { |
| 241 uint32_t operands[] = {operand0, operand1, operand2}; | 141 // Don't output dead code. |
| 242 Output(bytecode, operands, operand_scale); | 142 if (exit_seen_in_block_) return; |
| 143 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); |
| 144 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1)); |
| 145 DCHECK(OperandIsValid(bytecode, operand_scale, 2, operand2)); |
| 146 BytecodeNode node(bytecode, operand0, operand1, operand2, operand_scale); |
| 147 if (latest_source_info_.is_valid()) { |
| 148 node.source_info().Update(latest_source_info_); |
| 149 latest_source_info_.set_invalid(); |
| 150 } |
| 151 pipeline()->Write(&node); |
| 243 } | 152 } |
| 244 | 153 |
| 245 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | 154 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, |
| 246 OperandScale operand_scale, | 155 OperandScale operand_scale, |
| 247 uint32_t operand0, uint32_t operand1) { | 156 uint32_t operand0, uint32_t operand1) { |
| 248 uint32_t operands[] = {operand0, operand1}; | 157 // Don't output dead code. |
| 249 Output(bytecode, operands, operand_scale); | 158 if (exit_seen_in_block_) return; |
| 159 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); |
| 160 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1)); |
| 161 BytecodeNode node(bytecode, operand0, operand1, operand_scale); |
| 162 if (latest_source_info_.is_valid()) { |
| 163 node.source_info().Update(latest_source_info_); |
| 164 latest_source_info_.set_invalid(); |
| 165 } |
| 166 pipeline()->Write(&node); |
| 250 } | 167 } |
| 251 | 168 |
| 252 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | 169 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, |
| 253 OperandScale operand_scale, | 170 OperandScale operand_scale, |
| 254 uint32_t operand0) { | 171 uint32_t operand0) { |
| 255 uint32_t operands[] = {operand0}; | 172 // Don't output dead code. |
| 256 Output(bytecode, operands, operand_scale); | 173 if (exit_seen_in_block_) return; |
| 174 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); |
| 175 BytecodeNode node(bytecode, operand0, operand_scale); |
| 176 if (latest_source_info_.is_valid()) { |
| 177 node.source_info().Update(latest_source_info_); |
| 178 latest_source_info_.set_invalid(); |
| 179 } |
| 180 pipeline()->Write(&node); |
| 257 } | 181 } |
| 258 | 182 |
| 259 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 183 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, |
| 260 Register reg) { | 184 Register reg) { |
| 261 OperandScale operand_scale = OperandSizesToScale(reg.SizeOfOperand()); | 185 OperandScale operand_scale = |
| 186 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); |
| 262 OutputScaled(BytecodeForBinaryOperation(op), operand_scale, | 187 OutputScaled(BytecodeForBinaryOperation(op), operand_scale, |
| 263 RegisterOperand(reg)); | 188 RegisterOperand(reg)); |
| 264 return *this; | 189 return *this; |
| 265 } | 190 } |
| 266 | 191 |
| 267 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op) { | 192 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op) { |
| 268 Output(BytecodeForCountOperation(op)); | 193 Output(BytecodeForCountOperation(op)); |
| 269 return *this; | 194 return *this; |
| 270 } | 195 } |
| 271 | 196 |
| 272 | 197 |
| 273 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { | 198 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { |
| 274 Output(Bytecode::kLogicalNot); | 199 Output(Bytecode::kLogicalNot); |
| 275 return *this; | 200 return *this; |
| 276 } | 201 } |
| 277 | 202 |
| 278 | 203 |
| 279 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { | 204 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { |
| 280 Output(Bytecode::kTypeOf); | 205 Output(Bytecode::kTypeOf); |
| 281 return *this; | 206 return *this; |
| 282 } | 207 } |
| 283 | 208 |
| 284 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op, | 209 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op, |
| 285 Register reg) { | 210 Register reg) { |
| 286 OperandScale operand_scale = OperandSizesToScale(reg.SizeOfOperand()); | 211 OperandScale operand_scale = |
| 212 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); |
| 287 OutputScaled(BytecodeForCompareOperation(op), operand_scale, | 213 OutputScaled(BytecodeForCompareOperation(op), operand_scale, |
| 288 RegisterOperand(reg)); | 214 RegisterOperand(reg)); |
| 289 return *this; | 215 return *this; |
| 290 } | 216 } |
| 291 | 217 |
| 292 | 218 |
| 293 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( | 219 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( |
| 294 v8::internal::Smi* smi) { | 220 v8::internal::Smi* smi) { |
| 295 int32_t raw_smi = smi->value(); | 221 int32_t raw_smi = smi->value(); |
| 296 if (raw_smi == 0) { | 222 if (raw_smi == 0) { |
| 297 Output(Bytecode::kLdaZero); | 223 Output(Bytecode::kLdaZero); |
| 298 } else { | 224 } else { |
| 299 OperandSize operand_size = SizeForSignedOperand(raw_smi); | 225 OperandSize operand_size = Bytecodes::SizeForSignedOperand(raw_smi); |
| 300 OperandScale operand_scale = OperandSizesToScale(operand_size); | 226 OperandScale operand_scale = Bytecodes::OperandSizesToScale(operand_size); |
| 301 OutputScaled(Bytecode::kLdaSmi, operand_scale, | 227 OutputScaled(Bytecode::kLdaSmi, operand_scale, |
| 302 SignedOperand(raw_smi, operand_size)); | 228 SignedOperand(raw_smi, operand_size)); |
| 303 } | 229 } |
| 304 return *this; | 230 return *this; |
| 305 } | 231 } |
| 306 | 232 |
| 307 | 233 |
| 308 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) { | 234 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) { |
| 309 size_t entry = GetConstantPoolEntry(object); | 235 size_t entry = GetConstantPoolEntry(object); |
| 310 OperandScale operand_scale = | 236 OperandScale operand_scale = |
| 311 OperandSizesToScale(SizeForUnsignedOperand(entry)); | 237 Bytecodes::OperandSizesToScale(Bytecodes::SizeForUnsignedOperand(entry)); |
| 312 OutputScaled(Bytecode::kLdaConstant, operand_scale, UnsignedOperand(entry)); | 238 OutputScaled(Bytecode::kLdaConstant, operand_scale, UnsignedOperand(entry)); |
| 313 return *this; | 239 return *this; |
| 314 } | 240 } |
| 315 | 241 |
| 316 | 242 |
| 317 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() { | 243 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() { |
| 318 Output(Bytecode::kLdaUndefined); | 244 Output(Bytecode::kLdaUndefined); |
| 319 return *this; | 245 return *this; |
| 320 } | 246 } |
| 321 | 247 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 338 } | 264 } |
| 339 | 265 |
| 340 | 266 |
| 341 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { | 267 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { |
| 342 Output(Bytecode::kLdaFalse); | 268 Output(Bytecode::kLdaFalse); |
| 343 return *this; | 269 return *this; |
| 344 } | 270 } |
| 345 | 271 |
| 346 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( | 272 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( |
| 347 Register reg) { | 273 Register reg) { |
| 348 if (!IsRegisterInAccumulator(reg)) { | 274 OperandScale operand_scale = |
| 349 OperandScale operand_scale = OperandSizesToScale(reg.SizeOfOperand()); | 275 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); |
| 350 OutputScaled(Bytecode::kLdar, operand_scale, RegisterOperand(reg)); | 276 OutputScaled(Bytecode::kLdar, operand_scale, RegisterOperand(reg)); |
| 351 } | |
| 352 return *this; | 277 return *this; |
| 353 } | 278 } |
| 354 | 279 |
| 355 | 280 |
| 356 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( | 281 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( |
| 357 Register reg) { | 282 Register reg) { |
| 358 if (!IsRegisterInAccumulator(reg)) { | 283 OperandScale operand_scale = |
| 359 OperandScale operand_scale = OperandSizesToScale(reg.SizeOfOperand()); | 284 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); |
| 360 OutputScaled(Bytecode::kStar, operand_scale, RegisterOperand(reg)); | 285 OutputScaled(Bytecode::kStar, operand_scale, RegisterOperand(reg)); |
| 361 } | |
| 362 return *this; | 286 return *this; |
| 363 } | 287 } |
| 364 | 288 |
| 365 | 289 |
| 366 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, | 290 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, |
| 367 Register to) { | 291 Register to) { |
| 368 DCHECK(from != to); | 292 DCHECK(from != to); |
| 369 OperandScale operand_scale = | 293 OperandScale operand_scale = |
| 370 OperandSizesToScale(from.SizeOfOperand(), to.SizeOfOperand()); | 294 Bytecodes::OperandSizesToScale(from.SizeOfOperand(), to.SizeOfOperand()); |
| 371 OutputScaled(Bytecode::kMov, operand_scale, RegisterOperand(from), | 295 OutputScaled(Bytecode::kMov, operand_scale, RegisterOperand(from), |
| 372 RegisterOperand(to)); | 296 RegisterOperand(to)); |
| 373 return *this; | 297 return *this; |
| 374 } | 298 } |
| 375 | 299 |
| 376 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal( | 300 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal( |
| 377 const Handle<String> name, int feedback_slot, TypeofMode typeof_mode) { | 301 const Handle<String> name, int feedback_slot, TypeofMode typeof_mode) { |
| 378 // TODO(rmcilroy): Potentially store typeof information in an | 302 // TODO(rmcilroy): Potentially store typeof information in an |
| 379 // operand rather than having extra bytecodes. | 303 // operand rather than having extra bytecodes. |
| 380 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode); | 304 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode); |
| 381 size_t name_index = GetConstantPoolEntry(name); | 305 size_t name_index = GetConstantPoolEntry(name); |
| 382 OperandScale operand_scale = | 306 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 383 OperandSizesToScale(SizeForUnsignedOperand(name_index), | 307 Bytecodes::SizeForUnsignedOperand(name_index), |
| 384 SizeForUnsignedOperand(feedback_slot)); | 308 Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
| 385 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index), | 309 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index), |
| 386 UnsignedOperand(feedback_slot)); | 310 UnsignedOperand(feedback_slot)); |
| 387 return *this; | 311 return *this; |
| 388 } | 312 } |
| 389 | 313 |
| 390 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( | 314 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( |
| 391 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { | 315 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { |
| 392 Bytecode bytecode = BytecodeForStoreGlobal(language_mode); | 316 Bytecode bytecode = BytecodeForStoreGlobal(language_mode); |
| 393 size_t name_index = GetConstantPoolEntry(name); | 317 size_t name_index = GetConstantPoolEntry(name); |
| 394 OperandScale operand_scale = | 318 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 395 OperandSizesToScale(SizeForUnsignedOperand(name_index), | 319 Bytecodes::SizeForUnsignedOperand(name_index), |
| 396 SizeForUnsignedOperand(feedback_slot)); | 320 Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
| 397 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index), | 321 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index), |
| 398 UnsignedOperand(feedback_slot)); | 322 UnsignedOperand(feedback_slot)); |
| 399 return *this; | 323 return *this; |
| 400 } | 324 } |
| 401 | 325 |
| 402 | 326 |
| 403 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, | 327 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, |
| 404 int slot_index) { | 328 int slot_index) { |
| 405 OperandScale operand_scale = OperandSizesToScale( | 329 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 406 context.SizeOfOperand(), SizeForUnsignedOperand(slot_index)); | 330 context.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(slot_index)); |
| 407 OutputScaled(Bytecode::kLdaContextSlot, operand_scale, | 331 OutputScaled(Bytecode::kLdaContextSlot, operand_scale, |
| 408 RegisterOperand(context), UnsignedOperand(slot_index)); | 332 RegisterOperand(context), UnsignedOperand(slot_index)); |
| 409 return *this; | 333 return *this; |
| 410 } | 334 } |
| 411 | 335 |
| 412 | 336 |
| 413 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, | 337 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, |
| 414 int slot_index) { | 338 int slot_index) { |
| 415 OperandScale operand_scale = OperandSizesToScale( | 339 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 416 context.SizeOfOperand(), SizeForUnsignedOperand(slot_index)); | 340 context.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(slot_index)); |
| 417 OutputScaled(Bytecode::kStaContextSlot, operand_scale, | 341 OutputScaled(Bytecode::kStaContextSlot, operand_scale, |
| 418 RegisterOperand(context), UnsignedOperand(slot_index)); | 342 RegisterOperand(context), UnsignedOperand(slot_index)); |
| 419 return *this; | 343 return *this; |
| 420 } | 344 } |
| 421 | 345 |
| 422 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( | 346 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( |
| 423 const Handle<String> name, TypeofMode typeof_mode) { | 347 const Handle<String> name, TypeofMode typeof_mode) { |
| 424 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) | 348 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) |
| 425 ? Bytecode::kLdaLookupSlotInsideTypeof | 349 ? Bytecode::kLdaLookupSlotInsideTypeof |
| 426 : Bytecode::kLdaLookupSlot; | 350 : Bytecode::kLdaLookupSlot; |
| 427 size_t name_index = GetConstantPoolEntry(name); | 351 size_t name_index = GetConstantPoolEntry(name); |
| 428 OperandScale operand_scale = | 352 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 429 OperandSizesToScale(SizeForUnsignedOperand(name_index)); | 353 Bytecodes::SizeForUnsignedOperand(name_index)); |
| 430 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index)); | 354 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index)); |
| 431 return *this; | 355 return *this; |
| 432 } | 356 } |
| 433 | 357 |
| 434 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( | 358 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( |
| 435 const Handle<String> name, LanguageMode language_mode) { | 359 const Handle<String> name, LanguageMode language_mode) { |
| 436 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode); | 360 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode); |
| 437 size_t name_index = GetConstantPoolEntry(name); | 361 size_t name_index = GetConstantPoolEntry(name); |
| 438 OperandScale operand_scale = | 362 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 439 OperandSizesToScale(SizeForUnsignedOperand(name_index)); | 363 Bytecodes::SizeForUnsignedOperand(name_index)); |
| 440 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index)); | 364 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index)); |
| 441 return *this; | 365 return *this; |
| 442 } | 366 } |
| 443 | 367 |
| 444 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( | 368 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( |
| 445 Register object, const Handle<Name> name, int feedback_slot) { | 369 Register object, const Handle<Name> name, int feedback_slot) { |
| 446 size_t name_index = GetConstantPoolEntry(name); | 370 size_t name_index = GetConstantPoolEntry(name); |
| 447 OperandScale operand_scale = OperandSizesToScale( | 371 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 448 object.SizeOfOperand(), SizeForUnsignedOperand(name_index), | 372 object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(name_index), |
| 449 SizeForUnsignedOperand(feedback_slot)); | 373 Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
| 450 OutputScaled(Bytecode::kLoadIC, operand_scale, RegisterOperand(object), | 374 OutputScaled(Bytecode::kLoadIC, operand_scale, RegisterOperand(object), |
| 451 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | 375 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); |
| 452 return *this; | 376 return *this; |
| 453 } | 377 } |
| 454 | 378 |
| 455 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( | 379 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( |
| 456 Register object, int feedback_slot) { | 380 Register object, int feedback_slot) { |
| 457 OperandScale operand_scale = OperandSizesToScale( | 381 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 458 object.SizeOfOperand(), SizeForUnsignedOperand(feedback_slot)); | 382 object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
| 459 OutputScaled(Bytecode::kKeyedLoadIC, operand_scale, RegisterOperand(object), | 383 OutputScaled(Bytecode::kKeyedLoadIC, operand_scale, RegisterOperand(object), |
| 460 UnsignedOperand(feedback_slot)); | 384 UnsignedOperand(feedback_slot)); |
| 461 return *this; | 385 return *this; |
| 462 } | 386 } |
| 463 | 387 |
| 464 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( | 388 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( |
| 465 Register object, const Handle<Name> name, int feedback_slot, | 389 Register object, const Handle<Name> name, int feedback_slot, |
| 466 LanguageMode language_mode) { | 390 LanguageMode language_mode) { |
| 467 Bytecode bytecode = BytecodeForStoreIC(language_mode); | 391 Bytecode bytecode = BytecodeForStoreIC(language_mode); |
| 468 size_t name_index = GetConstantPoolEntry(name); | 392 size_t name_index = GetConstantPoolEntry(name); |
| 469 OperandScale operand_scale = OperandSizesToScale( | 393 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 470 object.SizeOfOperand(), SizeForUnsignedOperand(name_index), | 394 object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(name_index), |
| 471 SizeForUnsignedOperand(feedback_slot)); | 395 Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
| 472 OutputScaled(bytecode, operand_scale, RegisterOperand(object), | 396 OutputScaled(bytecode, operand_scale, RegisterOperand(object), |
| 473 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | 397 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); |
| 474 return *this; | 398 return *this; |
| 475 } | 399 } |
| 476 | 400 |
| 477 | 401 |
| 478 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( | 402 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( |
| 479 Register object, Register key, int feedback_slot, | 403 Register object, Register key, int feedback_slot, |
| 480 LanguageMode language_mode) { | 404 LanguageMode language_mode) { |
| 481 Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode); | 405 Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode); |
| 482 OperandScale operand_scale = | 406 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 483 OperandSizesToScale(object.SizeOfOperand(), key.SizeOfOperand(), | 407 object.SizeOfOperand(), key.SizeOfOperand(), |
| 484 SizeForUnsignedOperand(feedback_slot)); | 408 Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
| 485 OutputScaled(bytecode, operand_scale, RegisterOperand(object), | 409 OutputScaled(bytecode, operand_scale, RegisterOperand(object), |
| 486 RegisterOperand(key), UnsignedOperand(feedback_slot)); | 410 RegisterOperand(key), UnsignedOperand(feedback_slot)); |
| 487 return *this; | 411 return *this; |
| 488 } | 412 } |
| 489 | 413 |
| 490 | 414 |
| 491 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure( | 415 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure( |
| 492 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) { | 416 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) { |
| 493 size_t entry = GetConstantPoolEntry(shared_info); | 417 size_t entry = GetConstantPoolEntry(shared_info); |
| 494 OperandScale operand_scale = | 418 OperandScale operand_scale = |
| 495 OperandSizesToScale(SizeForUnsignedOperand(entry)); | 419 Bytecodes::OperandSizesToScale(Bytecodes::SizeForUnsignedOperand(entry)); |
| 496 OutputScaled(Bytecode::kCreateClosure, operand_scale, UnsignedOperand(entry), | 420 OutputScaled(Bytecode::kCreateClosure, operand_scale, UnsignedOperand(entry), |
| 497 UnsignedOperand(static_cast<size_t>(tenured))); | 421 UnsignedOperand(static_cast<size_t>(tenured))); |
| 498 return *this; | 422 return *this; |
| 499 } | 423 } |
| 500 | 424 |
| 501 | 425 |
| 502 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( | 426 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( |
| 503 CreateArgumentsType type) { | 427 CreateArgumentsType type) { |
| 504 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather | 428 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather |
| 505 // than having two different bytecodes once we have better support for | 429 // than having two different bytecodes once we have better support for |
| 506 // branches in the InterpreterAssembler. | 430 // branches in the InterpreterAssembler. |
| 507 Bytecode bytecode = BytecodeForCreateArguments(type); | 431 Bytecode bytecode = BytecodeForCreateArguments(type); |
| 508 Output(bytecode); | 432 Output(bytecode); |
| 509 return *this; | 433 return *this; |
| 510 } | 434 } |
| 511 | 435 |
| 512 | 436 |
| 513 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( | 437 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( |
| 514 Handle<String> pattern, int literal_index, int flags) { | 438 Handle<String> pattern, int literal_index, int flags) { |
| 515 size_t pattern_entry = GetConstantPoolEntry(pattern); | 439 size_t pattern_entry = GetConstantPoolEntry(pattern); |
| 516 OperandScale operand_scale = OperandSizesToScale( | 440 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 517 SizeForUnsignedOperand(pattern_entry), | 441 Bytecodes::SizeForUnsignedOperand(pattern_entry), |
| 518 SizeForUnsignedOperand(literal_index), SizeForUnsignedOperand(flags)); | 442 Bytecodes::SizeForUnsignedOperand(literal_index), |
| 443 Bytecodes::SizeForUnsignedOperand(flags)); |
| 519 OutputScaled(Bytecode::kCreateRegExpLiteral, operand_scale, | 444 OutputScaled(Bytecode::kCreateRegExpLiteral, operand_scale, |
| 520 UnsignedOperand(pattern_entry), UnsignedOperand(literal_index), | 445 UnsignedOperand(pattern_entry), UnsignedOperand(literal_index), |
| 521 UnsignedOperand(flags)); | 446 UnsignedOperand(flags)); |
| 522 return *this; | 447 return *this; |
| 523 } | 448 } |
| 524 | 449 |
| 525 | 450 |
| 526 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral( | 451 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral( |
| 527 Handle<FixedArray> constant_elements, int literal_index, int flags) { | 452 Handle<FixedArray> constant_elements, int literal_index, int flags) { |
| 528 size_t constant_elements_entry = GetConstantPoolEntry(constant_elements); | 453 size_t constant_elements_entry = GetConstantPoolEntry(constant_elements); |
| 529 OperandScale operand_scale = OperandSizesToScale( | 454 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 530 SizeForUnsignedOperand(constant_elements_entry), | 455 Bytecodes::SizeForUnsignedOperand(constant_elements_entry), |
| 531 SizeForUnsignedOperand(literal_index), SizeForUnsignedOperand(flags)); | 456 Bytecodes::SizeForUnsignedOperand(literal_index), |
| 457 Bytecodes::SizeForUnsignedOperand(flags)); |
| 532 OutputScaled(Bytecode::kCreateArrayLiteral, operand_scale, | 458 OutputScaled(Bytecode::kCreateArrayLiteral, operand_scale, |
| 533 UnsignedOperand(constant_elements_entry), | 459 UnsignedOperand(constant_elements_entry), |
| 534 UnsignedOperand(literal_index), UnsignedOperand(flags)); | 460 UnsignedOperand(literal_index), UnsignedOperand(flags)); |
| 535 return *this; | 461 return *this; |
| 536 } | 462 } |
| 537 | 463 |
| 538 | 464 |
| 539 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral( | 465 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral( |
| 540 Handle<FixedArray> constant_properties, int literal_index, int flags) { | 466 Handle<FixedArray> constant_properties, int literal_index, int flags) { |
| 541 size_t constant_properties_entry = GetConstantPoolEntry(constant_properties); | 467 size_t constant_properties_entry = GetConstantPoolEntry(constant_properties); |
| 542 OperandScale operand_scale = OperandSizesToScale( | 468 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 543 SizeForUnsignedOperand(constant_properties_entry), | 469 Bytecodes::SizeForUnsignedOperand(constant_properties_entry), |
| 544 SizeForUnsignedOperand(literal_index), SizeForUnsignedOperand(flags)); | 470 Bytecodes::SizeForUnsignedOperand(literal_index), |
| 471 Bytecodes::SizeForUnsignedOperand(flags)); |
| 545 OutputScaled(Bytecode::kCreateObjectLiteral, operand_scale, | 472 OutputScaled(Bytecode::kCreateObjectLiteral, operand_scale, |
| 546 UnsignedOperand(constant_properties_entry), | 473 UnsignedOperand(constant_properties_entry), |
| 547 UnsignedOperand(literal_index), UnsignedOperand(flags)); | 474 UnsignedOperand(literal_index), UnsignedOperand(flags)); |
| 548 return *this; | 475 return *this; |
| 549 } | 476 } |
| 550 | 477 |
| 551 | 478 |
| 552 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) { | 479 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) { |
| 553 OperandScale operand_scale = OperandSizesToScale(context.SizeOfOperand()); | 480 OperandScale operand_scale = |
| 481 Bytecodes::OperandSizesToScale(context.SizeOfOperand()); |
| 554 OutputScaled(Bytecode::kPushContext, operand_scale, RegisterOperand(context)); | 482 OutputScaled(Bytecode::kPushContext, operand_scale, RegisterOperand(context)); |
| 555 return *this; | 483 return *this; |
| 556 } | 484 } |
| 557 | 485 |
| 558 | 486 |
| 559 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { | 487 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { |
| 560 OperandScale operand_scale = OperandSizesToScale(context.SizeOfOperand()); | 488 OperandScale operand_scale = |
| 489 Bytecodes::OperandSizesToScale(context.SizeOfOperand()); |
| 561 OutputScaled(Bytecode::kPopContext, operand_scale, RegisterOperand(context)); | 490 OutputScaled(Bytecode::kPopContext, operand_scale, RegisterOperand(context)); |
| 562 return *this; | 491 return *this; |
| 563 } | 492 } |
| 564 | 493 |
| 565 | 494 |
| 566 bool BytecodeArrayBuilder::NeedToBooleanCast() { | |
| 567 if (!LastBytecodeInSameBlock()) { | |
| 568 return true; | |
| 569 } | |
| 570 PreviousBytecodeHelper previous_bytecode(*this); | |
| 571 switch (previous_bytecode.GetBytecode()) { | |
| 572 // If the previous bytecode puts a boolean in the accumulator return true. | |
| 573 case Bytecode::kLdaTrue: | |
| 574 case Bytecode::kLdaFalse: | |
| 575 case Bytecode::kLogicalNot: | |
| 576 case Bytecode::kTestEqual: | |
| 577 case Bytecode::kTestNotEqual: | |
| 578 case Bytecode::kTestEqualStrict: | |
| 579 case Bytecode::kTestLessThan: | |
| 580 case Bytecode::kTestLessThanOrEqual: | |
| 581 case Bytecode::kTestGreaterThan: | |
| 582 case Bytecode::kTestGreaterThanOrEqual: | |
| 583 case Bytecode::kTestInstanceOf: | |
| 584 case Bytecode::kTestIn: | |
| 585 case Bytecode::kForInDone: | |
| 586 return false; | |
| 587 default: | |
| 588 return true; | |
| 589 } | |
| 590 } | |
| 591 | |
| 592 | |
| 593 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() { | 495 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() { |
| 594 Output(Bytecode::kToObject); | 496 Output(Bytecode::kToObject); |
| 595 return *this; | 497 return *this; |
| 596 } | 498 } |
| 597 | 499 |
| 598 | 500 |
| 599 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() { | 501 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() { |
| 600 if (LastBytecodeInSameBlock()) { | |
| 601 PreviousBytecodeHelper previous_bytecode(*this); | |
| 602 switch (previous_bytecode.GetBytecode()) { | |
| 603 case Bytecode::kToName: | |
| 604 case Bytecode::kTypeOf: | |
| 605 return *this; | |
| 606 case Bytecode::kLdaConstant: { | |
| 607 Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0); | |
| 608 if (object->IsName()) return *this; | |
| 609 break; | |
| 610 } | |
| 611 default: | |
| 612 break; | |
| 613 } | |
| 614 } | |
| 615 Output(Bytecode::kToName); | 502 Output(Bytecode::kToName); |
| 616 return *this; | 503 return *this; |
| 617 } | 504 } |
| 618 | 505 |
| 619 | |
| 620 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() { | 506 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() { |
| 621 // TODO(rmcilroy): consider omitting if the preceeding bytecode always returns | 507 // TODO(rmcilroy): consider omitting if the preceeding bytecode always returns |
| 622 // a number. | 508 // a number. |
| 623 Output(Bytecode::kToNumber); | 509 Output(Bytecode::kToNumber); |
| 624 return *this; | 510 return *this; |
| 625 } | 511 } |
| 626 | 512 |
| 627 | 513 |
| 628 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { | 514 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { |
| 515 size_t current_offset = pipeline()->FlushForOffset(); |
| 629 if (label->is_forward_target()) { | 516 if (label->is_forward_target()) { |
| 630 // An earlier jump instruction refers to this label. Update it's location. | 517 // An earlier jump instruction refers to this label. Update it's location. |
| 631 PatchJump(bytecodes()->end(), bytecodes()->begin() + label->offset()); | 518 PatchJump(current_offset, label->offset()); |
| 632 // Now treat as if the label will only be back referred to. | 519 // Now treat as if the label will only be back referred to. |
| 633 } | 520 } |
| 634 label->bind_to(bytecodes()->size()); | 521 label->bind_to(current_offset); |
| 635 LeaveBasicBlock(); | 522 LeaveBasicBlock(); |
| 636 return *this; | 523 return *this; |
| 637 } | 524 } |
| 638 | 525 |
| 639 | 526 |
| 640 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, | 527 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, |
| 641 BytecodeLabel* label) { | 528 BytecodeLabel* label) { |
| 642 DCHECK(!label->is_bound()); | 529 DCHECK(!label->is_bound()); |
| 643 DCHECK(target.is_bound()); | 530 DCHECK(target.is_bound()); |
| 531 // There is no need to flush the pipeline here, it will have been |
| 532 // flushed when |target| was bound. |
| 644 if (label->is_forward_target()) { | 533 if (label->is_forward_target()) { |
| 645 // An earlier jump instruction refers to this label. Update it's location. | 534 // An earlier jump instruction refers to this label. Update it's location. |
| 646 PatchJump(bytecodes()->begin() + target.offset(), | 535 PatchJump(target.offset(), label->offset()); |
| 647 bytecodes()->begin() + label->offset()); | |
| 648 // Now treat as if the label will only be back referred to. | 536 // Now treat as if the label will only be back referred to. |
| 649 } | 537 } |
| 650 label->bind_to(target.offset()); | 538 label->bind_to(target.offset()); |
| 651 LeaveBasicBlock(); | 539 LeaveBasicBlock(); |
| 652 return *this; | 540 return *this; |
| 653 } | 541 } |
| 654 | 542 |
| 655 | 543 |
| 656 // static | 544 // static |
| 657 Bytecode BytecodeArrayBuilder::GetJumpWithConstantOperand( | 545 Bytecode BytecodeArrayBuilder::GetJumpWithConstantOperand( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 672 case Bytecode::kJumpIfNull: | 560 case Bytecode::kJumpIfNull: |
| 673 return Bytecode::kJumpIfNullConstant; | 561 return Bytecode::kJumpIfNullConstant; |
| 674 case Bytecode::kJumpIfUndefined: | 562 case Bytecode::kJumpIfUndefined: |
| 675 return Bytecode::kJumpIfUndefinedConstant; | 563 return Bytecode::kJumpIfUndefinedConstant; |
| 676 default: | 564 default: |
| 677 UNREACHABLE(); | 565 UNREACHABLE(); |
| 678 return Bytecode::kIllegal; | 566 return Bytecode::kIllegal; |
| 679 } | 567 } |
| 680 } | 568 } |
| 681 | 569 |
| 682 // static | 570 void BytecodeArrayBuilder::PatchJumpWith8BitOperand( |
| 683 Bytecode BytecodeArrayBuilder::GetJumpWithToBoolean(Bytecode jump_bytecode) { | 571 ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) { |
| 684 switch (jump_bytecode) { | 572 Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location)); |
| 685 case Bytecode::kJump: | |
| 686 case Bytecode::kJumpIfNull: | |
| 687 case Bytecode::kJumpIfUndefined: | |
| 688 case Bytecode::kJumpIfNotHole: | |
| 689 return jump_bytecode; | |
| 690 case Bytecode::kJumpIfTrue: | |
| 691 return Bytecode::kJumpIfToBooleanTrue; | |
| 692 case Bytecode::kJumpIfFalse: | |
| 693 return Bytecode::kJumpIfToBooleanFalse; | |
| 694 default: | |
| 695 UNREACHABLE(); | |
| 696 } | |
| 697 return Bytecode::kIllegal; | |
| 698 } | |
| 699 | |
| 700 | |
| 701 void BytecodeArrayBuilder::PatchIndirectJumpWith8BitOperand( | |
| 702 const ZoneVector<uint8_t>::iterator& jump_location, int delta) { | |
| 703 Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location); | |
| 704 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode)); | 573 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode)); |
| 705 ZoneVector<uint8_t>::iterator operand_location = jump_location + 1; | 574 size_t operand_location = jump_location + 1; |
| 706 DCHECK_EQ(*operand_location, 0); | 575 DCHECK_EQ(bytecodes->at(operand_location), 0); |
| 707 if (SizeForSignedOperand(delta) == OperandSize::kByte) { | 576 if (Bytecodes::SizeForSignedOperand(delta) == OperandSize::kByte) { |
| 708 // The jump fits within the range of an Imm operand, so cancel | 577 // The jump fits within the range of an Imm operand, so cancel |
| 709 // the reservation and jump directly. | 578 // the reservation and jump directly. |
| 710 constant_array_builder()->DiscardReservedEntry(OperandSize::kByte); | 579 constant_array_builder()->DiscardReservedEntry(OperandSize::kByte); |
| 711 *operand_location = static_cast<uint8_t>(delta); | 580 bytecodes->at(operand_location) = static_cast<uint8_t>(delta); |
| 712 } else { | 581 } else { |
| 713 // The jump does not fit within the range of an Imm operand, so | 582 // The jump does not fit within the range of an Imm operand, so |
| 714 // commit reservation putting the offset into the constant pool, | 583 // commit reservation putting the offset into the constant pool, |
| 715 // and update the jump instruction and operand. | 584 // and update the jump instruction and operand. |
| 716 size_t entry = constant_array_builder()->CommitReservedEntry( | 585 size_t entry = constant_array_builder()->CommitReservedEntry( |
| 717 OperandSize::kByte, handle(Smi::FromInt(delta), isolate())); | 586 OperandSize::kByte, handle(Smi::FromInt(delta), isolate())); |
| 718 DCHECK(SizeForUnsignedOperand(entry) == OperandSize::kByte); | 587 DCHECK(Bytecodes::SizeForUnsignedOperand(entry) == OperandSize::kByte); |
| 719 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode); | 588 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode); |
| 720 *jump_location = Bytecodes::ToByte(jump_bytecode); | 589 bytecodes->at(jump_location) = Bytecodes::ToByte(jump_bytecode); |
| 721 *operand_location = static_cast<uint8_t>(entry); | 590 bytecodes->at(operand_location) = static_cast<uint8_t>(entry); |
| 722 } | 591 } |
| 723 } | 592 } |
| 724 | 593 |
| 725 void BytecodeArrayBuilder::PatchIndirectJumpWith16BitOperand( | 594 void BytecodeArrayBuilder::PatchJumpWith16BitOperand( |
| 726 const ZoneVector<uint8_t>::iterator& jump_location, int delta) { | 595 ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) { |
| 727 Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location); | 596 Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location)); |
| 728 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode)); | 597 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode)); |
| 729 ZoneVector<uint8_t>::iterator operand_location = jump_location + 1; | 598 size_t operand_location = jump_location + 1; |
| 730 uint8_t operand_bytes[2]; | 599 uint8_t operand_bytes[2]; |
| 731 if (SizeForSignedOperand(delta) <= OperandSize::kShort) { | 600 if (Bytecodes::SizeForSignedOperand(delta) <= OperandSize::kShort) { |
| 732 constant_array_builder()->DiscardReservedEntry(OperandSize::kShort); | 601 constant_array_builder()->DiscardReservedEntry(OperandSize::kShort); |
| 733 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(delta)); | 602 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(delta)); |
| 734 } else { | 603 } else { |
| 735 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode); | 604 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode); |
| 736 *jump_location = Bytecodes::ToByte(jump_bytecode); | 605 bytecodes->at(jump_location) = Bytecodes::ToByte(jump_bytecode); |
| 737 size_t entry = constant_array_builder()->CommitReservedEntry( | 606 size_t entry = constant_array_builder()->CommitReservedEntry( |
| 738 OperandSize::kShort, handle(Smi::FromInt(delta), isolate())); | 607 OperandSize::kShort, handle(Smi::FromInt(delta), isolate())); |
| 739 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(entry)); | 608 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(entry)); |
| 740 } | 609 } |
| 741 DCHECK(*operand_location == 0 && *(operand_location + 1) == 0); | 610 DCHECK(bytecodes->at(operand_location) == 0 && |
| 742 *operand_location++ = operand_bytes[0]; | 611 bytecodes->at(operand_location + 1) == 0); |
| 743 *operand_location = operand_bytes[1]; | 612 bytecodes->at(operand_location++) = operand_bytes[0]; |
| 613 bytecodes->at(operand_location) = operand_bytes[1]; |
| 744 } | 614 } |
| 745 | 615 |
| 746 void BytecodeArrayBuilder::PatchIndirectJumpWith32BitOperand( | 616 void BytecodeArrayBuilder::PatchJumpWith32BitOperand( |
| 747 const ZoneVector<uint8_t>::iterator& jump_location, int delta) { | 617 ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) { |
| 748 DCHECK(Bytecodes::IsJumpImmediate(Bytecodes::FromByte(*jump_location))); | 618 DCHECK(Bytecodes::IsJumpImmediate( |
| 619 Bytecodes::FromByte(bytecodes->at(jump_location)))); |
| 749 constant_array_builder()->DiscardReservedEntry(OperandSize::kQuad); | 620 constant_array_builder()->DiscardReservedEntry(OperandSize::kQuad); |
| 750 ZoneVector<uint8_t>::iterator operand_location = jump_location + 1; | |
| 751 uint8_t operand_bytes[4]; | 621 uint8_t operand_bytes[4]; |
| 752 WriteUnalignedUInt32(operand_bytes, static_cast<uint32_t>(delta)); | 622 WriteUnalignedUInt32(operand_bytes, static_cast<uint32_t>(delta)); |
| 753 DCHECK(*operand_location == 0 && *(operand_location + 1) == 0 && | 623 size_t operand_location = jump_location + 1; |
| 754 *(operand_location + 2) == 0 && *(operand_location + 3) == 0); | 624 DCHECK(bytecodes->at(operand_location) == 0 && |
| 755 *operand_location++ = operand_bytes[0]; | 625 bytecodes->at(operand_location + 1) == 0 && |
| 756 *operand_location++ = operand_bytes[1]; | 626 bytecodes->at(operand_location + 2) == 0 && |
| 757 *operand_location++ = operand_bytes[2]; | 627 bytecodes->at(operand_location + 3) == 0); |
| 758 *operand_location = operand_bytes[3]; | 628 bytecodes->at(operand_location++) = operand_bytes[0]; |
| 629 bytecodes->at(operand_location++) = operand_bytes[1]; |
| 630 bytecodes->at(operand_location++) = operand_bytes[2]; |
| 631 bytecodes->at(operand_location) = operand_bytes[3]; |
| 759 } | 632 } |
| 760 | 633 |
| 761 void BytecodeArrayBuilder::PatchJump( | 634 void BytecodeArrayBuilder::PatchJump(size_t jump_target, size_t jump_location) { |
| 762 const ZoneVector<uint8_t>::iterator& jump_target, | 635 ZoneVector<uint8_t>* bytecodes = bytecode_array_writer()->bytecodes(); |
| 763 const ZoneVector<uint8_t>::iterator& jump_location) { | 636 Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location)); |
| 764 int delta = static_cast<int>(jump_target - jump_location); | 637 int delta = static_cast<int>(jump_target - jump_location); |
| 765 Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location); | |
| 766 int prefix_offset = 0; | 638 int prefix_offset = 0; |
| 767 OperandScale operand_scale = OperandScale::kSingle; | 639 OperandScale operand_scale = OperandScale::kSingle; |
| 768 if (Bytecodes::IsPrefixScalingBytecode(jump_bytecode)) { | 640 if (Bytecodes::IsPrefixScalingBytecode(jump_bytecode)) { |
| 769 // If a prefix scaling bytecode is emitted the target offset is one | 641 // If a prefix scaling bytecode is emitted the target offset is one |
| 770 // less than the case of no prefix scaling bytecode. | 642 // less than the case of no prefix scaling bytecode. |
| 771 delta -= 1; | 643 delta -= 1; |
| 772 prefix_offset = 1; | 644 prefix_offset = 1; |
| 773 operand_scale = Bytecodes::PrefixBytecodeToOperandScale(jump_bytecode); | 645 operand_scale = Bytecodes::PrefixBytecodeToOperandScale(jump_bytecode); |
| 774 jump_bytecode = Bytecodes::FromByte(*(jump_location + prefix_offset)); | 646 jump_bytecode = |
| 647 Bytecodes::FromByte(bytecodes->at(jump_location + prefix_offset)); |
| 775 } | 648 } |
| 776 | 649 |
| 777 DCHECK(Bytecodes::IsJump(jump_bytecode)); | 650 DCHECK(Bytecodes::IsJump(jump_bytecode)); |
| 778 switch (operand_scale) { | 651 switch (operand_scale) { |
| 779 case OperandScale::kSingle: | 652 case OperandScale::kSingle: |
| 780 PatchIndirectJumpWith8BitOperand(jump_location, delta); | 653 PatchJumpWith8BitOperand(bytecodes, jump_location, delta); |
| 781 break; | 654 break; |
| 782 case OperandScale::kDouble: | 655 case OperandScale::kDouble: |
| 783 PatchIndirectJumpWith16BitOperand(jump_location + prefix_offset, delta); | 656 PatchJumpWith16BitOperand(bytecodes, jump_location + prefix_offset, |
| 657 delta); |
| 784 break; | 658 break; |
| 785 case OperandScale::kQuadruple: | 659 case OperandScale::kQuadruple: |
| 786 PatchIndirectJumpWith32BitOperand(jump_location + prefix_offset, delta); | 660 PatchJumpWith32BitOperand(bytecodes, jump_location + prefix_offset, |
| 661 delta); |
| 787 break; | 662 break; |
| 788 default: | 663 default: |
| 789 UNREACHABLE(); | 664 UNREACHABLE(); |
| 790 } | 665 } |
| 791 unbound_jumps_--; | 666 unbound_jumps_--; |
| 792 } | 667 } |
| 793 | 668 |
| 794 | 669 |
| 795 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, | 670 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, |
| 796 BytecodeLabel* label) { | 671 BytecodeLabel* label) { |
| 797 // Don't emit dead code. | 672 // Don't emit dead code. |
| 798 if (exit_seen_in_block_) return *this; | 673 if (exit_seen_in_block_) return *this; |
| 799 | 674 |
| 800 // Check if the value in accumulator is boolean, if not choose an | |
| 801 // appropriate JumpIfToBoolean bytecode. | |
| 802 if (NeedToBooleanCast()) { | |
| 803 jump_bytecode = GetJumpWithToBoolean(jump_bytecode); | |
| 804 } | |
| 805 | |
| 806 if (label->is_bound()) { | 675 if (label->is_bound()) { |
| 807 // Label has been bound already so this is a backwards jump. | 676 // Label has been bound already so this is a backwards jump. |
| 808 CHECK_GE(bytecodes()->size(), label->offset()); | 677 size_t current_offset = pipeline()->FlushForOffset(); |
| 809 CHECK_LE(bytecodes()->size(), static_cast<size_t>(kMaxInt)); | 678 CHECK_GE(current_offset, label->offset()); |
| 810 size_t abs_delta = bytecodes()->size() - label->offset(); | 679 CHECK_LE(current_offset, static_cast<size_t>(kMaxInt)); |
| 680 size_t abs_delta = current_offset - label->offset(); |
| 811 int delta = -static_cast<int>(abs_delta); | 681 int delta = -static_cast<int>(abs_delta); |
| 812 OperandSize operand_size = SizeForSignedOperand(delta); | 682 OperandSize operand_size = Bytecodes::SizeForSignedOperand(delta); |
| 813 if (operand_size > OperandSize::kByte) { | 683 if (operand_size > OperandSize::kByte) { |
| 814 // Adjust for scaling byte prefix for wide jump offset. | 684 // Adjust for scaling byte prefix for wide jump offset. |
| 815 DCHECK_LE(delta, 0); | 685 DCHECK_LE(delta, 0); |
| 816 delta -= 1; | 686 delta -= 1; |
| 817 } | 687 } |
| 818 OutputScaled(jump_bytecode, OperandSizesToScale(operand_size), | 688 OutputScaled(jump_bytecode, Bytecodes::OperandSizesToScale(operand_size), |
| 819 SignedOperand(delta, operand_size)); | 689 SignedOperand(delta, operand_size)); |
| 820 } else { | 690 } else { |
| 821 // The label has not yet been bound so this is a forward reference | 691 // The label has not yet been bound so this is a forward reference |
| 822 // that will be patched when the label is bound. We create a | 692 // that will be patched when the label is bound. We create a |
| 823 // reservation in the constant pool so the jump can be patched | 693 // reservation in the constant pool so the jump can be patched |
| 824 // when the label is bound. The reservation means the maximum size | 694 // when the label is bound. The reservation means the maximum size |
| 825 // of the operand for the constant is known and the jump can | 695 // of the operand for the constant is known and the jump can |
| 826 // be emitted into the bytecode stream with space for the operand. | 696 // be emitted into the bytecode stream with space for the operand. |
| 827 label->set_referrer(bytecodes()->size()); | |
| 828 unbound_jumps_++; | 697 unbound_jumps_++; |
| 829 OperandSize reserved_operand_size = | 698 OperandSize reserved_operand_size = |
| 830 constant_array_builder()->CreateReservedEntry(); | 699 constant_array_builder()->CreateReservedEntry(); |
| 831 OutputScaled(jump_bytecode, OperandSizesToScale(reserved_operand_size), 0); | 700 OutputScaled(jump_bytecode, |
| 701 Bytecodes::OperandSizesToScale(reserved_operand_size), 0); |
| 702 // Calculate label position after flushing for offset. |
| 703 size_t offset = pipeline()->FlushForOffset(); |
| 704 OperandScale operand_scale = |
| 705 Bytecodes::OperandSizesToScale(reserved_operand_size); |
| 706 offset -= Bytecodes::Size(jump_bytecode, operand_scale); |
| 707 if (Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale)) { |
| 708 offset -= 1; |
| 709 } |
| 710 label->set_referrer(offset); |
| 832 } | 711 } |
| 833 LeaveBasicBlock(); | 712 LeaveBasicBlock(); |
| 834 return *this; | 713 return *this; |
| 835 } | 714 } |
| 836 | 715 |
| 837 | |
| 838 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { | 716 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { |
| 839 return OutputJump(Bytecode::kJump, label); | 717 return OutputJump(Bytecode::kJump, label); |
| 840 } | 718 } |
| 841 | 719 |
| 842 | |
| 843 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { | 720 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { |
| 844 return OutputJump(Bytecode::kJumpIfTrue, label); | 721 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue |
| 722 // to JumpIfTrue. |
| 723 return OutputJump(Bytecode::kJumpIfToBooleanTrue, label); |
| 845 } | 724 } |
| 846 | 725 |
| 847 | |
| 848 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { | 726 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { |
| 849 return OutputJump(Bytecode::kJumpIfFalse, label); | 727 // The peephole optimizer attempts to simplify JumpIfToBooleanFalse |
| 728 // to JumpIfFalse. |
| 729 return OutputJump(Bytecode::kJumpIfToBooleanFalse, label); |
| 850 } | 730 } |
| 851 | 731 |
| 852 | |
| 853 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { | 732 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { |
| 854 return OutputJump(Bytecode::kJumpIfNull, label); | 733 return OutputJump(Bytecode::kJumpIfNull, label); |
| 855 } | 734 } |
| 856 | 735 |
| 857 | |
| 858 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( | 736 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( |
| 859 BytecodeLabel* label) { | 737 BytecodeLabel* label) { |
| 860 return OutputJump(Bytecode::kJumpIfUndefined, label); | 738 return OutputJump(Bytecode::kJumpIfUndefined, label); |
| 861 } | 739 } |
| 862 | 740 |
| 863 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { | 741 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { |
| 864 if (position != RelocInfo::kNoPosition) { | 742 if (position != RelocInfo::kNoPosition) { |
| 865 // We need to attach a non-breakable source position to a stack check, | 743 // We need to attach a non-breakable source position to a stack check, |
| 866 // so we simply add it as expression position. | 744 // so we simply add it as expression position. |
| 867 source_position_table_builder_.AddExpressionPosition(bytecodes_.size(), | 745 latest_source_info_.Update({position, false}); |
| 868 position); | |
| 869 } | 746 } |
| 870 Output(Bytecode::kStackCheck); | 747 Output(Bytecode::kStackCheck); |
| 871 return *this; | 748 return *this; |
| 872 } | 749 } |
| 873 | 750 |
| 874 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( | 751 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( |
| 875 BytecodeLabel* label) { | 752 BytecodeLabel* label) { |
| 876 return OutputJump(Bytecode::kJumpIfNotHole, label); | 753 return OutputJump(Bytecode::kJumpIfNotHole, label); |
| 877 } | 754 } |
| 878 | 755 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 903 } | 780 } |
| 904 | 781 |
| 905 BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() { | 782 BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() { |
| 906 Output(Bytecode::kDebugger); | 783 Output(Bytecode::kDebugger); |
| 907 return *this; | 784 return *this; |
| 908 } | 785 } |
| 909 | 786 |
| 910 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare( | 787 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare( |
| 911 Register cache_info_triple) { | 788 Register cache_info_triple) { |
| 912 OperandScale operand_scale = | 789 OperandScale operand_scale = |
| 913 OperandSizesToScale(cache_info_triple.SizeOfOperand()); | 790 Bytecodes::OperandSizesToScale(cache_info_triple.SizeOfOperand()); |
| 914 OutputScaled(Bytecode::kForInPrepare, operand_scale, | 791 OutputScaled(Bytecode::kForInPrepare, operand_scale, |
| 915 RegisterOperand(cache_info_triple)); | 792 RegisterOperand(cache_info_triple)); |
| 916 return *this; | 793 return *this; |
| 917 } | 794 } |
| 918 | 795 |
| 919 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index, | 796 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index, |
| 920 Register cache_length) { | 797 Register cache_length) { |
| 921 OperandScale operand_scale = | 798 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 922 OperandSizesToScale(index.SizeOfOperand(), cache_length.SizeOfOperand()); | 799 index.SizeOfOperand(), cache_length.SizeOfOperand()); |
| 923 OutputScaled(Bytecode::kForInDone, operand_scale, RegisterOperand(index), | 800 OutputScaled(Bytecode::kForInDone, operand_scale, RegisterOperand(index), |
| 924 RegisterOperand(cache_length)); | 801 RegisterOperand(cache_length)); |
| 925 return *this; | 802 return *this; |
| 926 } | 803 } |
| 927 | 804 |
| 928 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext( | 805 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext( |
| 929 Register receiver, Register index, Register cache_type_array_pair, | 806 Register receiver, Register index, Register cache_type_array_pair, |
| 930 int feedback_slot) { | 807 int feedback_slot) { |
| 931 OperandScale operand_scale = | 808 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 932 OperandSizesToScale(receiver.SizeOfOperand(), index.SizeOfOperand(), | 809 receiver.SizeOfOperand(), index.SizeOfOperand(), |
| 933 cache_type_array_pair.SizeOfOperand(), | 810 cache_type_array_pair.SizeOfOperand(), |
| 934 SizeForUnsignedOperand(feedback_slot)); | 811 Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
| 935 OutputScaled(Bytecode::kForInNext, operand_scale, RegisterOperand(receiver), | 812 OutputScaled(Bytecode::kForInNext, operand_scale, RegisterOperand(receiver), |
| 936 RegisterOperand(index), RegisterOperand(cache_type_array_pair), | 813 RegisterOperand(index), RegisterOperand(cache_type_array_pair), |
| 937 UnsignedOperand(feedback_slot)); | 814 UnsignedOperand(feedback_slot)); |
| 938 return *this; | 815 return *this; |
| 939 } | 816 } |
| 940 | 817 |
| 941 | 818 |
| 942 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) { | 819 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) { |
| 943 OperandScale operand_scale = OperandSizesToScale(index.SizeOfOperand()); | 820 OperandScale operand_scale = |
| 821 Bytecodes::OperandSizesToScale(index.SizeOfOperand()); |
| 944 OutputScaled(Bytecode::kForInStep, operand_scale, RegisterOperand(index)); | 822 OutputScaled(Bytecode::kForInStep, operand_scale, RegisterOperand(index)); |
| 945 return *this; | 823 return *this; |
| 946 } | 824 } |
| 947 | 825 |
| 948 | 826 |
| 949 BytecodeArrayBuilder& BytecodeArrayBuilder::SuspendGenerator( | 827 BytecodeArrayBuilder& BytecodeArrayBuilder::SuspendGenerator( |
| 950 Register generator) { | 828 Register generator) { |
| 951 OperandScale operand_scale = OperandSizesToScale(generator.SizeOfOperand()); | 829 OperandScale operand_scale = |
| 830 Bytecodes::OperandSizesToScale(generator.SizeOfOperand()); |
| 952 OutputScaled(Bytecode::kSuspendGenerator, operand_scale, | 831 OutputScaled(Bytecode::kSuspendGenerator, operand_scale, |
| 953 RegisterOperand(generator)); | 832 RegisterOperand(generator)); |
| 954 return *this; | 833 return *this; |
| 955 } | 834 } |
| 956 | 835 |
| 957 | 836 |
| 958 BytecodeArrayBuilder& BytecodeArrayBuilder::ResumeGenerator( | 837 BytecodeArrayBuilder& BytecodeArrayBuilder::ResumeGenerator( |
| 959 Register generator) { | 838 Register generator) { |
| 960 OperandScale operand_scale = OperandSizesToScale(generator.SizeOfOperand()); | 839 OperandScale operand_scale = |
| 840 Bytecodes::OperandSizesToScale(generator.SizeOfOperand()); |
| 961 OutputScaled(Bytecode::kResumeGenerator, operand_scale, | 841 OutputScaled(Bytecode::kResumeGenerator, operand_scale, |
| 962 RegisterOperand(generator)); | 842 RegisterOperand(generator)); |
| 963 return *this; | 843 return *this; |
| 964 } | 844 } |
| 965 | 845 |
| 966 | 846 |
| 967 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id, | 847 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id, |
| 968 bool will_catch) { | 848 bool will_catch) { |
| 969 handler_table_builder()->SetHandlerTarget(handler_id, bytecodes()->size()); | 849 size_t offset = pipeline()->FlushForOffset(); |
| 850 handler_table_builder()->SetHandlerTarget(handler_id, offset); |
| 970 handler_table_builder()->SetPrediction(handler_id, will_catch); | 851 handler_table_builder()->SetPrediction(handler_id, will_catch); |
| 971 return *this; | 852 return *this; |
| 972 } | 853 } |
| 973 | 854 |
| 974 | 855 |
| 975 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryBegin(int handler_id, | 856 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryBegin(int handler_id, |
| 976 Register context) { | 857 Register context) { |
| 977 handler_table_builder()->SetTryRegionStart(handler_id, bytecodes()->size()); | 858 size_t offset = pipeline()->FlushForOffset(); |
| 859 handler_table_builder()->SetTryRegionStart(handler_id, offset); |
| 978 handler_table_builder()->SetContextRegister(handler_id, context); | 860 handler_table_builder()->SetContextRegister(handler_id, context); |
| 979 return *this; | 861 return *this; |
| 980 } | 862 } |
| 981 | 863 |
| 982 | 864 |
| 983 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) { | 865 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) { |
| 984 handler_table_builder()->SetTryRegionEnd(handler_id, bytecodes()->size()); | 866 size_t offset = pipeline()->FlushForOffset(); |
| 867 handler_table_builder()->SetTryRegionEnd(handler_id, offset); |
| 985 return *this; | 868 return *this; |
| 986 } | 869 } |
| 987 | 870 |
| 988 | 871 |
| 989 void BytecodeArrayBuilder::LeaveBasicBlock() { | 872 void BytecodeArrayBuilder::LeaveBasicBlock() { |
| 990 last_block_end_ = bytecodes()->size(); | |
| 991 exit_seen_in_block_ = false; | 873 exit_seen_in_block_ = false; |
| 874 pipeline()->FlushBasicBlock(); |
| 992 } | 875 } |
| 993 | 876 |
| 994 void BytecodeArrayBuilder::EnsureReturn() { | 877 void BytecodeArrayBuilder::EnsureReturn() { |
| 995 if (!exit_seen_in_block_) { | 878 if (!exit_seen_in_block_) { |
| 996 LoadUndefined(); | 879 LoadUndefined(); |
| 997 Return(); | 880 Return(); |
| 998 } | 881 } |
| 999 DCHECK(exit_seen_in_block_); | 882 DCHECK(exit_seen_in_block_); |
| 1000 } | 883 } |
| 1001 | 884 |
| 1002 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, | 885 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, |
| 1003 Register receiver_args, | 886 Register receiver_args, |
| 1004 size_t receiver_args_count, | 887 size_t receiver_args_count, |
| 1005 int feedback_slot, | 888 int feedback_slot, |
| 1006 TailCallMode tail_call_mode) { | 889 TailCallMode tail_call_mode) { |
| 1007 Bytecode bytecode = BytecodeForCall(tail_call_mode); | 890 Bytecode bytecode = BytecodeForCall(tail_call_mode); |
| 1008 OperandScale operand_scale = OperandSizesToScale( | 891 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 1009 callable.SizeOfOperand(), receiver_args.SizeOfOperand(), | 892 callable.SizeOfOperand(), receiver_args.SizeOfOperand(), |
| 1010 SizeForUnsignedOperand(receiver_args_count), | 893 Bytecodes::SizeForUnsignedOperand(receiver_args_count), |
| 1011 SizeForUnsignedOperand(feedback_slot)); | 894 Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
| 1012 OutputScaled(bytecode, operand_scale, RegisterOperand(callable), | 895 OutputScaled(bytecode, operand_scale, RegisterOperand(callable), |
| 1013 RegisterOperand(receiver_args), | 896 RegisterOperand(receiver_args), |
| 1014 UnsignedOperand(receiver_args_count), | 897 UnsignedOperand(receiver_args_count), |
| 1015 UnsignedOperand(feedback_slot)); | 898 UnsignedOperand(feedback_slot)); |
| 1016 return *this; | 899 return *this; |
| 1017 } | 900 } |
| 1018 | 901 |
| 1019 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, | 902 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, |
| 1020 Register first_arg, | 903 Register first_arg, |
| 1021 size_t arg_count) { | 904 size_t arg_count) { |
| 1022 if (!first_arg.is_valid()) { | 905 if (!first_arg.is_valid()) { |
| 1023 DCHECK_EQ(0u, arg_count); | 906 DCHECK_EQ(0u, arg_count); |
| 1024 first_arg = Register(0); | 907 first_arg = Register(0); |
| 1025 } | 908 } |
| 1026 OperandScale operand_scale = OperandSizesToScale( | 909 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 1027 constructor.SizeOfOperand(), first_arg.SizeOfOperand(), | 910 constructor.SizeOfOperand(), first_arg.SizeOfOperand(), |
| 1028 SizeForUnsignedOperand(arg_count)); | 911 Bytecodes::SizeForUnsignedOperand(arg_count)); |
| 1029 OutputScaled(Bytecode::kNew, operand_scale, RegisterOperand(constructor), | 912 OutputScaled(Bytecode::kNew, operand_scale, RegisterOperand(constructor), |
| 1030 RegisterOperand(first_arg), UnsignedOperand(arg_count)); | 913 RegisterOperand(first_arg), UnsignedOperand(arg_count)); |
| 1031 return *this; | 914 return *this; |
| 1032 } | 915 } |
| 1033 | 916 |
| 1034 | 917 |
| 1035 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( | 918 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( |
| 1036 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { | 919 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { |
| 1037 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); | 920 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); |
| 1038 DCHECK(SizeForUnsignedOperand(function_id) <= OperandSize::kShort); | 921 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort); |
| 1039 if (!first_arg.is_valid()) { | 922 if (!first_arg.is_valid()) { |
| 1040 DCHECK_EQ(0u, arg_count); | 923 DCHECK_EQ(0u, arg_count); |
| 1041 first_arg = Register(0); | 924 first_arg = Register(0); |
| 1042 } | 925 } |
| 1043 Bytecode bytecode = IntrinsicsHelper::IsSupported(function_id) | 926 Bytecode bytecode = IntrinsicsHelper::IsSupported(function_id) |
| 1044 ? Bytecode::kInvokeIntrinsic | 927 ? Bytecode::kInvokeIntrinsic |
| 1045 : Bytecode::kCallRuntime; | 928 : Bytecode::kCallRuntime; |
| 1046 OperandScale operand_scale = OperandSizesToScale( | 929 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 1047 first_arg.SizeOfOperand(), SizeForUnsignedOperand(arg_count)); | 930 first_arg.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(arg_count)); |
| 1048 OutputScaled(bytecode, operand_scale, static_cast<uint16_t>(function_id), | 931 OutputScaled(bytecode, operand_scale, static_cast<uint16_t>(function_id), |
| 1049 RegisterOperand(first_arg), UnsignedOperand(arg_count)); | 932 RegisterOperand(first_arg), UnsignedOperand(arg_count)); |
| 1050 return *this; | 933 return *this; |
| 1051 } | 934 } |
| 1052 | 935 |
| 1053 | 936 |
| 1054 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( | 937 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( |
| 1055 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, | 938 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, |
| 1056 Register first_return) { | 939 Register first_return) { |
| 1057 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); | 940 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); |
| 1058 DCHECK(SizeForUnsignedOperand(function_id) <= OperandSize::kShort); | 941 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort); |
| 1059 if (!first_arg.is_valid()) { | 942 if (!first_arg.is_valid()) { |
| 1060 DCHECK_EQ(0u, arg_count); | 943 DCHECK_EQ(0u, arg_count); |
| 1061 first_arg = Register(0); | 944 first_arg = Register(0); |
| 1062 } | 945 } |
| 1063 OperandScale operand_scale = OperandSizesToScale( | 946 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 1064 first_arg.SizeOfOperand(), SizeForUnsignedOperand(arg_count), | 947 first_arg.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(arg_count), |
| 1065 first_return.SizeOfOperand()); | 948 first_return.SizeOfOperand()); |
| 1066 OutputScaled(Bytecode::kCallRuntimeForPair, operand_scale, | 949 OutputScaled(Bytecode::kCallRuntimeForPair, operand_scale, |
| 1067 static_cast<uint16_t>(function_id), RegisterOperand(first_arg), | 950 static_cast<uint16_t>(function_id), RegisterOperand(first_arg), |
| 1068 UnsignedOperand(arg_count), RegisterOperand(first_return)); | 951 UnsignedOperand(arg_count), RegisterOperand(first_return)); |
| 1069 return *this; | 952 return *this; |
| 1070 } | 953 } |
| 1071 | 954 |
| 1072 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( | 955 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( |
| 1073 int context_index, Register receiver_args, size_t receiver_args_count) { | 956 int context_index, Register receiver_args, size_t receiver_args_count) { |
| 1074 OperandScale operand_scale = OperandSizesToScale( | 957 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
| 1075 SizeForUnsignedOperand(context_index), receiver_args.SizeOfOperand(), | 958 Bytecodes::SizeForUnsignedOperand(context_index), |
| 1076 SizeForUnsignedOperand(receiver_args_count)); | 959 receiver_args.SizeOfOperand(), |
| 960 Bytecodes::SizeForUnsignedOperand(receiver_args_count)); |
| 1077 OutputScaled(Bytecode::kCallJSRuntime, operand_scale, | 961 OutputScaled(Bytecode::kCallJSRuntime, operand_scale, |
| 1078 UnsignedOperand(context_index), RegisterOperand(receiver_args), | 962 UnsignedOperand(context_index), RegisterOperand(receiver_args), |
| 1079 UnsignedOperand(receiver_args_count)); | 963 UnsignedOperand(receiver_args_count)); |
| 1080 return *this; | 964 return *this; |
| 1081 } | 965 } |
| 1082 | 966 |
| 1083 | 967 |
| 1084 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, | 968 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, |
| 1085 LanguageMode language_mode) { | 969 LanguageMode language_mode) { |
| 1086 OperandScale operand_scale = OperandSizesToScale(object.SizeOfOperand()); | 970 OperandScale operand_scale = |
| 971 Bytecodes::OperandSizesToScale(object.SizeOfOperand()); |
| 1087 OutputScaled(BytecodeForDelete(language_mode), operand_scale, | 972 OutputScaled(BytecodeForDelete(language_mode), operand_scale, |
| 1088 RegisterOperand(object)); | 973 RegisterOperand(object)); |
| 1089 return *this; | 974 return *this; |
| 1090 } | 975 } |
| 1091 | 976 |
| 1092 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { | 977 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { |
| 1093 return constant_array_builder()->Insert(object); | 978 return constant_array_builder()->Insert(object); |
| 1094 } | 979 } |
| 1095 | 980 |
| 1096 void BytecodeArrayBuilder::SetReturnPosition() { | 981 void BytecodeArrayBuilder::SetReturnPosition() { |
| 1097 if (return_position_ == RelocInfo::kNoPosition) return; | 982 if (return_position_ == RelocInfo::kNoPosition) return; |
| 1098 if (exit_seen_in_block_) return; | 983 if (exit_seen_in_block_) return; |
| 1099 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), | 984 latest_source_info_.Update({return_position_, true}); |
| 1100 return_position_); | |
| 1101 } | 985 } |
| 1102 | 986 |
| 1103 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { | 987 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { |
| 1104 if (stmt->position() == RelocInfo::kNoPosition) return; | 988 if (stmt->position() == RelocInfo::kNoPosition) return; |
| 1105 if (exit_seen_in_block_) return; | 989 if (exit_seen_in_block_) return; |
| 1106 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), | 990 latest_source_info_.Update({stmt->position(), true}); |
| 1107 stmt->position()); | |
| 1108 } | 991 } |
| 1109 | 992 |
| 1110 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { | 993 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { |
| 1111 if (expr->position() == RelocInfo::kNoPosition) return; | 994 if (expr->position() == RelocInfo::kNoPosition) return; |
| 1112 if (exit_seen_in_block_) return; | 995 if (exit_seen_in_block_) return; |
| 1113 source_position_table_builder_.AddExpressionPosition(bytecodes_.size(), | 996 latest_source_info_.Update({expr->position(), false}); |
| 1114 expr->position()); | |
| 1115 } | 997 } |
| 1116 | 998 |
| 1117 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) { | 999 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) { |
| 1118 if (expr->position() == RelocInfo::kNoPosition) return; | 1000 if (expr->position() == RelocInfo::kNoPosition) return; |
| 1119 if (exit_seen_in_block_) return; | 1001 if (exit_seen_in_block_) return; |
| 1120 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), | 1002 latest_source_info_.Update({expr->position(), true}); |
| 1121 expr->position()); | |
| 1122 } | 1003 } |
| 1123 | 1004 |
| 1124 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { | 1005 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { |
| 1125 return temporary_register_allocator()->RegisterIsLive(reg); | 1006 return temporary_register_allocator()->RegisterIsLive(reg); |
| 1126 } | 1007 } |
| 1127 | 1008 |
| 1128 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, | 1009 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, |
| 1129 OperandScale operand_scale, | 1010 OperandScale operand_scale, |
| 1130 int operand_index, | 1011 int operand_index, |
| 1131 uint32_t operand_value) const { | 1012 uint32_t operand_value) const { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1143 previous_operand_type != OperandType::kReg) { | 1024 previous_operand_type != OperandType::kReg) { |
| 1144 return false; | 1025 return false; |
| 1145 } | 1026 } |
| 1146 } | 1027 } |
| 1147 } // Fall-through | 1028 } // Fall-through |
| 1148 case OperandType::kFlag8: | 1029 case OperandType::kFlag8: |
| 1149 case OperandType::kIdx: | 1030 case OperandType::kIdx: |
| 1150 case OperandType::kRuntimeId: | 1031 case OperandType::kRuntimeId: |
| 1151 case OperandType::kImm: { | 1032 case OperandType::kImm: { |
| 1152 size_t unsigned_value = static_cast<size_t>(operand_value); | 1033 size_t unsigned_value = static_cast<size_t>(operand_value); |
| 1153 return SizeForUnsignedOperand(unsigned_value) <= operand_size; | 1034 return Bytecodes::SizeForUnsignedOperand(unsigned_value) <= operand_size; |
| 1154 } | 1035 } |
| 1155 case OperandType::kMaybeReg: | 1036 case OperandType::kMaybeReg: |
| 1156 if (RegisterFromOperand(operand_value) == Register(0)) { | 1037 if (RegisterFromOperand(operand_value) == Register(0)) { |
| 1157 return true; | 1038 return true; |
| 1158 } | 1039 } |
| 1159 // Fall-through to kReg case. | 1040 // Fall-through to kReg case. |
| 1160 case OperandType::kReg: | 1041 case OperandType::kReg: |
| 1161 case OperandType::kRegOut: { | 1042 case OperandType::kRegOut: { |
| 1162 Register reg = RegisterFromOperand(operand_value); | 1043 Register reg = RegisterFromOperand(operand_value); |
| 1163 return RegisterIsValid(reg, operand_size); | 1044 return RegisterIsValid(reg, operand_size); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1200 } else if (reg.is_parameter()) { | 1081 } else if (reg.is_parameter()) { |
| 1201 int parameter_index = reg.ToParameterIndex(parameter_count()); | 1082 int parameter_index = reg.ToParameterIndex(parameter_count()); |
| 1202 return parameter_index >= 0 && parameter_index < parameter_count(); | 1083 return parameter_index >= 0 && parameter_index < parameter_count(); |
| 1203 } else if (reg.index() < fixed_register_count()) { | 1084 } else if (reg.index() < fixed_register_count()) { |
| 1204 return true; | 1085 return true; |
| 1205 } else { | 1086 } else { |
| 1206 return TemporaryRegisterIsLive(reg); | 1087 return TemporaryRegisterIsLive(reg); |
| 1207 } | 1088 } |
| 1208 } | 1089 } |
| 1209 | 1090 |
| 1210 | |
| 1211 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { | |
| 1212 return last_bytecode_start_ < bytecodes()->size() && | |
| 1213 last_bytecode_start_ >= last_block_end_; | |
| 1214 } | |
| 1215 | |
| 1216 | |
| 1217 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) { | |
| 1218 if (LastBytecodeInSameBlock()) { | |
| 1219 PreviousBytecodeHelper previous_bytecode(*this); | |
| 1220 Bytecode bytecode = previous_bytecode.GetBytecode(); | |
| 1221 if (bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar) { | |
| 1222 return previous_bytecode.GetRegisterOperand(0) == reg; | |
| 1223 } | |
| 1224 } | |
| 1225 return false; | |
| 1226 } | |
| 1227 | |
| 1228 | |
| 1229 // static | 1091 // static |
| 1230 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { | 1092 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { |
| 1231 switch (op) { | 1093 switch (op) { |
| 1232 case Token::Value::ADD: | 1094 case Token::Value::ADD: |
| 1233 return Bytecode::kAdd; | 1095 return Bytecode::kAdd; |
| 1234 case Token::Value::SUB: | 1096 case Token::Value::SUB: |
| 1235 return Bytecode::kSub; | 1097 return Bytecode::kSub; |
| 1236 case Token::Value::MUL: | 1098 case Token::Value::MUL: |
| 1237 return Bytecode::kMul; | 1099 return Bytecode::kMul; |
| 1238 case Token::Value::DIV: | 1100 case Token::Value::DIV: |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1400 case TailCallMode::kDisallow: | 1262 case TailCallMode::kDisallow: |
| 1401 return Bytecode::kCall; | 1263 return Bytecode::kCall; |
| 1402 case TailCallMode::kAllow: | 1264 case TailCallMode::kAllow: |
| 1403 return Bytecode::kTailCall; | 1265 return Bytecode::kTailCall; |
| 1404 default: | 1266 default: |
| 1405 UNREACHABLE(); | 1267 UNREACHABLE(); |
| 1406 } | 1268 } |
| 1407 return Bytecode::kIllegal; | 1269 return Bytecode::kIllegal; |
| 1408 } | 1270 } |
| 1409 | 1271 |
| 1410 // static | |
| 1411 OperandSize BytecodeArrayBuilder::SizeForSignedOperand(int value) { | |
| 1412 if (kMinInt8 <= value && value <= kMaxInt8) { | |
| 1413 return OperandSize::kByte; | |
| 1414 } else if (kMinInt16 <= value && value <= kMaxInt16) { | |
| 1415 return OperandSize::kShort; | |
| 1416 } else { | |
| 1417 return OperandSize::kQuad; | |
| 1418 } | |
| 1419 } | |
| 1420 | |
| 1421 // static | |
| 1422 OperandSize BytecodeArrayBuilder::SizeForUnsignedOperand(int value) { | |
| 1423 DCHECK_GE(value, 0); | |
| 1424 if (value <= kMaxUInt8) { | |
| 1425 return OperandSize::kByte; | |
| 1426 } else if (value <= kMaxUInt16) { | |
| 1427 return OperandSize::kShort; | |
| 1428 } else { | |
| 1429 return OperandSize::kQuad; | |
| 1430 } | |
| 1431 } | |
| 1432 | |
| 1433 OperandSize BytecodeArrayBuilder::SizeForUnsignedOperand(size_t value) { | |
| 1434 if (value <= static_cast<size_t>(kMaxUInt8)) { | |
| 1435 return OperandSize::kByte; | |
| 1436 } else if (value <= static_cast<size_t>(kMaxUInt16)) { | |
| 1437 return OperandSize::kShort; | |
| 1438 } else if (value <= kMaxUInt32) { | |
| 1439 return OperandSize::kQuad; | |
| 1440 } else { | |
| 1441 UNREACHABLE(); | |
| 1442 return OperandSize::kQuad; | |
| 1443 } | |
| 1444 } | |
| 1445 | |
| 1446 OperandScale BytecodeArrayBuilder::OperandSizesToScale(OperandSize size0, | |
| 1447 OperandSize size1, | |
| 1448 OperandSize size2, | |
| 1449 OperandSize size3) { | |
| 1450 OperandSize upper = std::max(size0, size1); | |
| 1451 OperandSize lower = std::max(size2, size3); | |
| 1452 OperandSize result = std::max(upper, lower); | |
| 1453 // Operand sizes have been scaled before calling this function. | |
| 1454 // Currently all scalable operands are byte sized at | |
| 1455 // OperandScale::kSingle. | |
| 1456 STATIC_ASSERT(static_cast<int>(OperandSize::kByte) == | |
| 1457 static_cast<int>(OperandScale::kSingle) && | |
| 1458 static_cast<int>(OperandSize::kShort) == | |
| 1459 static_cast<int>(OperandScale::kDouble) && | |
| 1460 static_cast<int>(OperandSize::kQuad) == | |
| 1461 static_cast<int>(OperandScale::kQuadruple)); | |
| 1462 OperandScale operand_scale = static_cast<OperandScale>(result); | |
| 1463 DCHECK(operand_scale == OperandScale::kSingle || | |
| 1464 operand_scale == OperandScale::kDouble || | |
| 1465 operand_scale == OperandScale::kQuadruple); | |
| 1466 return operand_scale; | |
| 1467 } | |
| 1468 | |
| 1469 uint32_t BytecodeArrayBuilder::RegisterOperand(Register reg) { | 1272 uint32_t BytecodeArrayBuilder::RegisterOperand(Register reg) { |
| 1470 return static_cast<uint32_t>(reg.ToOperand()); | 1273 return static_cast<uint32_t>(reg.ToOperand()); |
| 1471 } | 1274 } |
| 1472 | 1275 |
| 1473 Register BytecodeArrayBuilder::RegisterFromOperand(uint32_t operand) { | 1276 Register BytecodeArrayBuilder::RegisterFromOperand(uint32_t operand) { |
| 1474 return Register::FromOperand(static_cast<int32_t>(operand)); | 1277 return Register::FromOperand(static_cast<int32_t>(operand)); |
| 1475 } | 1278 } |
| 1476 | 1279 |
| 1477 uint32_t BytecodeArrayBuilder::SignedOperand(int value, OperandSize size) { | 1280 uint32_t BytecodeArrayBuilder::SignedOperand(int value, OperandSize size) { |
| 1478 switch (size) { | 1281 switch (size) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1494 } | 1297 } |
| 1495 | 1298 |
| 1496 uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) { | 1299 uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) { |
| 1497 DCHECK_LE(value, kMaxUInt32); | 1300 DCHECK_LE(value, kMaxUInt32); |
| 1498 return static_cast<uint32_t>(value); | 1301 return static_cast<uint32_t>(value); |
| 1499 } | 1302 } |
| 1500 | 1303 |
| 1501 } // namespace interpreter | 1304 } // namespace interpreter |
| 1502 } // namespace internal | 1305 } // namespace internal |
| 1503 } // namespace v8 | 1306 } // namespace v8 |
| OLD | NEW |