Chromium Code Reviews| 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 |
| 7 namespace v8 { | 7 namespace v8 { |
| 8 namespace internal { | 8 namespace internal { |
| 9 namespace interpreter { | 9 namespace interpreter { |
| 10 | 10 |
| 11 class BytecodeArrayBuilder::PreviousBytecodeHelper { | 11 class BytecodeArrayBuilder::PreviousBytecodeHelper BASE_EMBEDDED { |
| 12 public: | 12 public: |
| 13 explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder) | 13 explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder) |
| 14 : array_builder_(array_builder), | 14 : array_builder_(array_builder), |
| 15 previous_bytecode_start_(array_builder_.last_bytecode_start_) { | 15 previous_bytecode_start_(array_builder_.last_bytecode_start_) { |
| 16 // This helper is expected to be instantiated only when the last bytecode is | 16 // This helper is expected to be instantiated only when the last bytecode is |
| 17 // in the same basic block. | 17 // in the same basic block. |
| 18 DCHECK(array_builder_.LastBytecodeInSameBlock()); | 18 DCHECK(array_builder_.LastBytecodeInSameBlock()); |
| 19 } | 19 } |
| 20 | 20 |
| 21 // Returns the previous bytecode in the same basic block. | 21 // Returns the previous bytecode in the same basic block. |
| 22 MUST_USE_RESULT Bytecode GetBytecode() const { | 22 MUST_USE_RESULT Bytecode GetBytecode() const { |
| 23 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); | 23 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); |
| 24 return Bytecodes::FromByte( | 24 return Bytecodes::FromByte( |
| 25 array_builder_.bytecodes()->at(previous_bytecode_start_)); | 25 array_builder_.bytecodes()->at(previous_bytecode_start_)); |
| 26 } | 26 } |
| 27 | 27 |
| 28 // Returns the operand at operand_index for the previous bytecode in the | 28 // Returns the operand at operand_index for the previous bytecode in the |
| 29 // same basic block. | 29 // same basic block. |
| 30 MUST_USE_RESULT uint32_t GetOperand(int operand_index) const { | 30 MUST_USE_RESULT uint32_t GetOperand(int operand_index) const { |
| 31 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); | 31 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); |
| 32 Bytecode bytecode = GetBytecode(); | 32 Bytecode bytecode = GetBytecode(); |
| 33 DCHECK_GE(operand_index, 0); | 33 DCHECK_GE(operand_index, 0); |
| 34 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode)); | 34 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode)); |
| 35 size_t operand_offset = | 35 size_t operand_offset = |
| 36 previous_bytecode_start_ + | 36 previous_bytecode_start_ + |
| 37 Bytecodes::GetOperandOffset(bytecode, operand_index); | 37 Bytecodes::GetOperandOffset(bytecode, operand_index); |
| 38 OperandSize size = Bytecodes::GetOperandSize(bytecode, operand_index); | 38 OperandSize size = Bytecodes::GetOperandSize(bytecode, operand_index); |
| 39 switch (size) { | 39 switch (size) { |
| 40 default: | |
| 41 case OperandSize::kNone: | 40 case OperandSize::kNone: |
| 42 UNREACHABLE(); | 41 UNREACHABLE(); |
| 42 break; | |
| 43 case OperandSize::kByte: | 43 case OperandSize::kByte: |
| 44 return static_cast<uint32_t>( | 44 return static_cast<uint32_t>( |
| 45 array_builder_.bytecodes()->at(operand_offset)); | 45 array_builder_.bytecodes()->at(operand_offset)); |
| 46 case OperandSize::kShort: | 46 case OperandSize::kShort: |
| 47 uint16_t operand = | 47 uint16_t operand = |
| 48 (array_builder_.bytecodes()->at(operand_offset) << 8) + | 48 (array_builder_.bytecodes()->at(operand_offset) << 8) + |
| 49 array_builder_.bytecodes()->at(operand_offset + 1); | 49 array_builder_.bytecodes()->at(operand_offset + 1); |
| 50 return static_cast<uint32_t>(operand); | 50 return static_cast<uint32_t>(operand); |
| 51 } | 51 } |
| 52 return 0; | |
| 52 } | 53 } |
| 53 | 54 |
| 54 Handle<Object> GetConstantForIndexOperand(int operand_index) const { | 55 Handle<Object> GetConstantForIndexOperand(int operand_index) const { |
| 55 return array_builder_.constant_array_builder()->At( | 56 return array_builder_.constant_array_builder()->At( |
| 56 GetOperand(operand_index)); | 57 GetOperand(operand_index)); |
| 57 } | 58 } |
| 58 | 59 |
| 59 private: | 60 private: |
| 60 const BytecodeArrayBuilder& array_builder_; | 61 const BytecodeArrayBuilder& array_builder_; |
| 61 size_t previous_bytecode_start_; | 62 size_t previous_bytecode_start_; |
| 62 | 63 |
| 63 DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper); | 64 DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper); |
| 64 }; | 65 }; |
| 65 | 66 |
| 66 | 67 |
| 68 class BytecodeArrayBuilder::RegisterTranslationScope BASE_EMBEDDED { | |
| 69 public: | |
| 70 static const Bytecode kInvalidBytecode = static_cast<Bytecode>(-1); | |
| 71 | |
| 72 RegisterTranslationScope(BytecodeArrayBuilder* builder, | |
| 73 Bytecode bytecode = kInvalidBytecode) | |
| 74 : builder_(builder), bytecode_(bytecode) { | |
| 75 builder->set_register_translation_scope(this); | |
|
rmcilroy
2016/01/22 17:50:56
DCHECK_EQ(nullptr, builder()->register_translation
| |
| 76 } | |
| 77 | |
| 78 ~RegisterTranslationScope() { | |
| 79 translator()->CompleteTranslations(); | |
| 80 builder()->set_register_translation_scope(nullptr); | |
| 81 } | |
| 82 | |
| 83 Register Translate(Register reg) { | |
| 84 return translator()->Translate(bytecode(), reg); | |
| 85 } | |
| 86 | |
| 87 void set_bytecode(Bytecode bytecode) { bytecode_ = bytecode; } | |
| 88 Bytecode bytecode() const { return bytecode_; } | |
| 89 | |
| 90 private: | |
| 91 BytecodeArrayBuilder* builder() const { return builder_; } | |
| 92 RegisterTranslator* translator() { return builder()->register_translator(); } | |
| 93 | |
| 94 BytecodeArrayBuilder* builder_; | |
| 95 Bytecode bytecode_; | |
| 96 | |
| 97 DISALLOW_COPY_AND_ASSIGN(RegisterTranslationScope); | |
| 98 }; | |
| 99 | |
| 100 | |
| 67 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone) | 101 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone) |
| 68 : isolate_(isolate), | 102 : isolate_(isolate), |
| 69 zone_(zone), | 103 zone_(zone), |
| 70 bytecodes_(zone), | 104 bytecodes_(zone), |
| 71 bytecode_generated_(false), | 105 bytecode_generated_(false), |
| 72 constant_array_builder_(isolate, zone), | 106 constant_array_builder_(isolate, zone), |
| 73 handler_table_builder_(isolate, zone), | 107 handler_table_builder_(isolate, zone), |
| 74 last_block_end_(0), | 108 last_block_end_(0), |
| 75 last_bytecode_start_(~0), | 109 last_bytecode_start_(~0), |
| 76 exit_seen_in_block_(false), | 110 exit_seen_in_block_(false), |
| 77 unbound_jumps_(0), | 111 unbound_jumps_(0), |
| 78 parameter_count_(-1), | 112 parameter_count_(-1), |
| 79 local_register_count_(-1), | 113 local_register_count_(-1), |
| 80 context_register_count_(-1), | 114 context_register_count_(-1), |
| 81 temporary_register_count_(0), | 115 temporary_register_count_(0), |
| 82 free_temporaries_(zone) {} | 116 free_temporaries_(zone), |
| 117 register_translator_(this), | |
| 118 register_translation_scope_(nullptr) {} | |
| 83 | 119 |
| 84 | 120 |
| 85 BytecodeArrayBuilder::~BytecodeArrayBuilder() { DCHECK_EQ(0, unbound_jumps_); } | 121 BytecodeArrayBuilder::~BytecodeArrayBuilder() { DCHECK_EQ(0, unbound_jumps_); } |
| 86 | 122 |
| 87 | 123 |
| 88 void BytecodeArrayBuilder::set_locals_count(int number_of_locals) { | 124 void BytecodeArrayBuilder::set_locals_count(int number_of_locals) { |
| 89 local_register_count_ = number_of_locals; | 125 local_register_count_ = number_of_locals; |
| 90 DCHECK_LE(context_register_count_, 0); | 126 DCHECK_LE(context_register_count_, 0); |
| 91 } | 127 } |
| 92 | 128 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 141 return temporary_register_count_ > 0 && first_temporary_register() <= reg && | 177 return temporary_register_count_ > 0 && first_temporary_register() <= reg && |
| 142 reg <= last_temporary_register(); | 178 reg <= last_temporary_register(); |
| 143 } | 179 } |
| 144 | 180 |
| 145 | 181 |
| 146 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { | 182 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { |
| 147 DCHECK_EQ(bytecode_generated_, false); | 183 DCHECK_EQ(bytecode_generated_, false); |
| 148 EnsureReturn(); | 184 EnsureReturn(); |
| 149 | 185 |
| 150 int bytecode_size = static_cast<int>(bytecodes_.size()); | 186 int bytecode_size = static_cast<int>(bytecodes_.size()); |
| 151 int register_count = fixed_register_count() + temporary_register_count_; | 187 int register_count = |
| 188 fixed_and_temporary_register_count() + translation_register_count(); | |
| 152 int frame_size = register_count * kPointerSize; | 189 int frame_size = register_count * kPointerSize; |
| 153 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray(); | 190 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray(); |
| 154 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); | 191 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); |
| 155 Handle<BytecodeArray> output = isolate_->factory()->NewBytecodeArray( | 192 Handle<BytecodeArray> output = isolate_->factory()->NewBytecodeArray( |
| 156 bytecode_size, &bytecodes_.front(), frame_size, parameter_count(), | 193 bytecode_size, &bytecodes_.front(), frame_size, parameter_count(), |
| 157 constant_pool); | 194 constant_pool); |
| 158 output->set_handler_table(*handler_table); | 195 output->set_handler_table(*handler_table); |
| 159 bytecode_generated_ = true; | 196 bytecode_generated_ = true; |
| 160 return output; | 197 return output; |
| 161 } | 198 } |
| 162 | 199 |
| 163 | 200 |
| 164 template <size_t N> | 201 template <size_t N> |
| 165 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) { | 202 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) { |
| 166 // Don't output dead code. | 203 // Don't output dead code. |
| 167 if (exit_seen_in_block_) return; | 204 if (exit_seen_in_block_) return; |
| 168 | 205 |
| 169 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), static_cast<int>(N)); | 206 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), static_cast<int>(N)); |
| 207 DCHECK((register_translation_scope() == nullptr && | |
| 208 Bytecodes::NumberOfRegisterOperands(bytecode) == 0) || | |
| 209 (register_translation_scope() != nullptr && | |
| 210 Bytecodes::NumberOfRegisterOperands(bytecode) > 0)); | |
| 211 DCHECK(register_translator()->RegisterOperandsValid(bytecode, operands, | |
| 212 static_cast<int>(N))); | |
| 213 | |
| 170 last_bytecode_start_ = bytecodes()->size(); | 214 last_bytecode_start_ = bytecodes()->size(); |
| 171 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | 215 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); |
| 172 for (int i = 0; i < static_cast<int>(N); i++) { | 216 for (int i = 0; i < static_cast<int>(N); i++) { |
| 173 DCHECK(OperandIsValid(bytecode, i, operands[i])); | 217 DCHECK(OperandIsValid(bytecode, i, operands[i])); |
| 174 switch (Bytecodes::GetOperandSize(bytecode, i)) { | 218 switch (Bytecodes::GetOperandSize(bytecode, i)) { |
| 175 case OperandSize::kNone: | 219 case OperandSize::kNone: |
| 176 UNREACHABLE(); | 220 UNREACHABLE(); |
| 221 break; | |
| 177 case OperandSize::kByte: | 222 case OperandSize::kByte: |
| 178 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); | 223 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); |
| 179 break; | 224 break; |
| 180 case OperandSize::kShort: { | 225 case OperandSize::kShort: { |
| 181 uint8_t operand_bytes[2]; | 226 uint8_t operand_bytes[2]; |
| 182 WriteUnalignedUInt16(operand_bytes, operands[i]); | 227 WriteUnalignedUInt16(operand_bytes, operands[i]); |
| 183 bytecodes()->insert(bytecodes()->end(), operand_bytes, | 228 bytecodes()->insert(bytecodes()->end(), operand_bytes, |
| 184 operand_bytes + 2); | 229 operand_bytes + 2); |
| 185 break; | 230 break; |
| 186 } | 231 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 } | 272 } |
| 228 | 273 |
| 229 | 274 |
| 230 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 275 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, |
| 231 Register reg, | 276 Register reg, |
| 232 Strength strength) { | 277 Strength strength) { |
| 233 if (is_strong(strength)) { | 278 if (is_strong(strength)) { |
| 234 UNIMPLEMENTED(); | 279 UNIMPLEMENTED(); |
| 235 } | 280 } |
| 236 | 281 |
| 237 Output(BytecodeForBinaryOperation(op), reg.ToRawOperand()); | 282 RegisterTranslationScope translator(this, BytecodeForBinaryOperation(op)); |
| 283 reg = translator.Translate(reg); | |
| 284 Output(translator.bytecode(), reg.ToRawOperand()); | |
|
rmcilroy
2016/01/22 17:50:56
To avoid the extra translate call, could we write
| |
| 238 return *this; | 285 return *this; |
| 239 } | 286 } |
| 240 | 287 |
| 241 | 288 |
| 242 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op, | 289 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op, |
| 243 Strength strength) { | 290 Strength strength) { |
| 244 if (is_strong(strength)) { | 291 if (is_strong(strength)) { |
| 245 UNIMPLEMENTED(); | 292 UNIMPLEMENTED(); |
| 246 } | 293 } |
| 247 | 294 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 261 return *this; | 308 return *this; |
| 262 } | 309 } |
| 263 | 310 |
| 264 | 311 |
| 265 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation( | 312 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation( |
| 266 Token::Value op, Register reg, Strength strength) { | 313 Token::Value op, Register reg, Strength strength) { |
| 267 if (is_strong(strength)) { | 314 if (is_strong(strength)) { |
| 268 UNIMPLEMENTED(); | 315 UNIMPLEMENTED(); |
| 269 } | 316 } |
| 270 | 317 |
| 271 Output(BytecodeForCompareOperation(op), reg.ToRawOperand()); | 318 RegisterTranslationScope translator(this, BytecodeForCompareOperation(op)); |
| 319 reg = translator.Translate(reg); | |
| 320 Output(translator.bytecode(), reg.ToRawOperand()); | |
| 272 return *this; | 321 return *this; |
| 273 } | 322 } |
| 274 | 323 |
| 275 | 324 |
| 276 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( | 325 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( |
| 277 v8::internal::Smi* smi) { | 326 v8::internal::Smi* smi) { |
| 278 int32_t raw_smi = smi->value(); | 327 int32_t raw_smi = smi->value(); |
| 279 if (raw_smi == 0) { | 328 if (raw_smi == 0) { |
| 280 Output(Bytecode::kLdaZero); | 329 Output(Bytecode::kLdaZero); |
| 281 } else if (raw_smi >= -128 && raw_smi <= 127) { | 330 } else if (raw_smi >= -128 && raw_smi <= 127) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 335 LoadTrue(); | 384 LoadTrue(); |
| 336 } else { | 385 } else { |
| 337 LoadFalse(); | 386 LoadFalse(); |
| 338 } | 387 } |
| 339 return *this; | 388 return *this; |
| 340 } | 389 } |
| 341 | 390 |
| 342 | 391 |
| 343 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( | 392 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( |
| 344 Register reg) { | 393 Register reg) { |
| 394 RegisterTranslationScope translator(this, Bytecode::kLdar); | |
| 395 reg = translator.Translate(reg); | |
| 345 if (!IsRegisterInAccumulator(reg)) { | 396 if (!IsRegisterInAccumulator(reg)) { |
| 346 Output(Bytecode::kLdar, reg.ToRawOperand()); | 397 Output(translator.bytecode(), reg.ToRawOperand()); |
| 347 } | 398 } |
| 348 return *this; | 399 return *this; |
| 349 } | 400 } |
| 350 | 401 |
| 351 | 402 |
| 352 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( | 403 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( |
| 353 Register reg) { | 404 Register reg) { |
| 405 RegisterTranslationScope translator(this, Bytecode::kStar); | |
| 406 reg = translator.Translate(reg); | |
| 354 if (!IsRegisterInAccumulator(reg)) { | 407 if (!IsRegisterInAccumulator(reg)) { |
| 355 Output(Bytecode::kStar, reg.ToRawOperand()); | 408 Output(translator.bytecode(), reg.ToRawOperand()); |
| 356 } | 409 } |
| 357 return *this; | 410 return *this; |
| 358 } | 411 } |
| 359 | 412 |
| 360 | 413 |
| 361 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, | 414 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, |
| 362 Register to) { | 415 Register to) { |
| 363 DCHECK(from != to); | 416 DCHECK(from != to); |
| 364 if (FitsInReg8Operand(to) && FitsInReg8Operand(from)) { | 417 RegisterTranslationScope translator(this); |
|
rmcilroy
2016/01/22 17:50:56
Personally I would prefer that the RegisterTransla
| |
| 365 Output(Bytecode::kMov, from.ToRawOperand(), to.ToRawOperand()); | 418 if (FitsInReg8Operand(from) && FitsInReg8Operand(to)) { |
| 366 } else if (FitsInReg16Operand(to) && FitsInReg16Operand(from)) { | 419 translator.set_bytecode(Bytecode::kMov); |
| 367 Output(Bytecode::kMovWide, from.ToRawOperand(), to.ToRawOperand()); | 420 } else if (FitsInReg16Operand(from) && FitsInReg16Operand(to)) { |
| 421 translator.set_bytecode(Bytecode::kMovWide); | |
| 368 } else { | 422 } else { |
| 369 UNIMPLEMENTED(); | 423 UNIMPLEMENTED(); |
| 370 } | 424 } |
| 425 from = translator.Translate(from); | |
| 426 to = translator.Translate(to); | |
| 427 Output(translator.bytecode(), from.ToRawOperand(), to.ToRawOperand()); | |
| 371 return *this; | 428 return *this; |
| 372 } | 429 } |
| 373 | 430 |
| 374 | 431 |
| 432 bool BytecodeArrayBuilder::MoveRegisterUntranslated(Register from, | |
| 433 Register to) { | |
| 434 if (!from.is_valid() || !to.is_valid()) { | |
|
rmcilroy
2016/01/22 17:50:56
Just DCHECK(from.is_valid() && to.is_valid)) ?
| |
| 435 UNIMPLEMENTED(); | |
| 436 return false; | |
| 437 } | |
| 438 | |
| 439 DCHECK(FitsInReg8OperandUntranslated(from) || | |
| 440 FitsInReg8OperandUntranslated(to)); | |
| 441 DCHECK(from != to); | |
| 442 if (FitsInReg16OperandUntranslated(from) && | |
| 443 FitsInReg16OperandUntranslated(to)) { | |
| 444 Output(Bytecode::kMovWide, from.ToRawOperand(), to.ToRawOperand()); | |
| 445 return true; | |
| 446 } else { | |
| 447 UNIMPLEMENTED(); | |
| 448 return false; | |
| 449 } | |
| 450 } | |
| 451 | |
| 452 | |
| 375 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal( | 453 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal( |
| 376 const Handle<String> name, int feedback_slot, LanguageMode language_mode, | 454 const Handle<String> name, int feedback_slot, LanguageMode language_mode, |
| 377 TypeofMode typeof_mode) { | 455 TypeofMode typeof_mode) { |
| 378 // TODO(rmcilroy): Potentially store language and typeof information in an | 456 // TODO(rmcilroy): Potentially store language and typeof information in an |
| 379 // operand rather than having extra bytecodes. | 457 // operand rather than having extra bytecodes. |
| 380 Bytecode bytecode = BytecodeForLoadGlobal(language_mode, typeof_mode); | 458 Bytecode bytecode = BytecodeForLoadGlobal(language_mode, typeof_mode); |
| 381 size_t name_index = GetConstantPoolEntry(name); | 459 size_t name_index = GetConstantPoolEntry(name); |
| 382 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { | 460 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { |
| 383 Output(bytecode, static_cast<uint8_t>(name_index), | 461 Output(bytecode, static_cast<uint8_t>(name_index), |
| 384 static_cast<uint8_t>(feedback_slot)); | 462 static_cast<uint8_t>(feedback_slot)); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 407 } else { | 485 } else { |
| 408 UNIMPLEMENTED(); | 486 UNIMPLEMENTED(); |
| 409 } | 487 } |
| 410 return *this; | 488 return *this; |
| 411 } | 489 } |
| 412 | 490 |
| 413 | 491 |
| 414 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, | 492 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, |
| 415 int slot_index) { | 493 int slot_index) { |
| 416 DCHECK(slot_index >= 0); | 494 DCHECK(slot_index >= 0); |
| 495 RegisterTranslationScope translator(this); | |
| 417 if (FitsInIdx8Operand(slot_index)) { | 496 if (FitsInIdx8Operand(slot_index)) { |
| 418 Output(Bytecode::kLdaContextSlot, context.ToRawOperand(), | 497 translator.set_bytecode(Bytecode::kLdaContextSlot); |
| 419 static_cast<uint8_t>(slot_index)); | |
| 420 } else if (FitsInIdx16Operand(slot_index)) { | 498 } else if (FitsInIdx16Operand(slot_index)) { |
| 421 Output(Bytecode::kLdaContextSlotWide, context.ToRawOperand(), | 499 translator.set_bytecode(Bytecode::kLdaContextSlotWide); |
| 422 static_cast<uint16_t>(slot_index)); | |
| 423 } else { | 500 } else { |
| 424 UNIMPLEMENTED(); | 501 UNIMPLEMENTED(); |
| 425 } | 502 } |
| 503 context = translator.Translate(context); | |
| 504 Output(translator.bytecode(), context.ToRawOperand(), | |
| 505 static_cast<uint16_t>(slot_index)); | |
| 426 return *this; | 506 return *this; |
| 427 } | 507 } |
| 428 | 508 |
| 429 | 509 |
| 430 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, | 510 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, |
| 431 int slot_index) { | 511 int slot_index) { |
| 432 DCHECK(slot_index >= 0); | 512 DCHECK(slot_index >= 0); |
| 513 RegisterTranslationScope translator(this); | |
| 433 if (FitsInIdx8Operand(slot_index)) { | 514 if (FitsInIdx8Operand(slot_index)) { |
| 434 Output(Bytecode::kStaContextSlot, context.ToRawOperand(), | 515 translator.set_bytecode(Bytecode::kStaContextSlot); |
| 435 static_cast<uint8_t>(slot_index)); | |
| 436 } else if (FitsInIdx16Operand(slot_index)) { | 516 } else if (FitsInIdx16Operand(slot_index)) { |
| 437 Output(Bytecode::kStaContextSlotWide, context.ToRawOperand(), | 517 translator.set_bytecode(Bytecode::kStaContextSlotWide); |
| 438 static_cast<uint16_t>(slot_index)); | |
| 439 } else { | 518 } else { |
| 440 UNIMPLEMENTED(); | 519 UNIMPLEMENTED(); |
| 441 } | 520 } |
| 521 context = translator.Translate(context); | |
| 522 Output(translator.bytecode(), context.ToRawOperand(), | |
| 523 static_cast<uint16_t>(slot_index)); | |
| 442 return *this; | 524 return *this; |
| 443 } | 525 } |
| 444 | 526 |
| 445 | 527 |
| 446 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( | 528 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( |
| 447 const Handle<String> name, TypeofMode typeof_mode) { | 529 const Handle<String> name, TypeofMode typeof_mode) { |
| 448 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) | 530 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) |
| 449 ? Bytecode::kLdaLookupSlotInsideTypeof | 531 ? Bytecode::kLdaLookupSlotInsideTypeof |
| 450 : Bytecode::kLdaLookupSlot; | 532 : Bytecode::kLdaLookupSlot; |
| 451 size_t name_index = GetConstantPoolEntry(name); | 533 size_t name_index = GetConstantPoolEntry(name); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 473 } else { | 555 } else { |
| 474 UNIMPLEMENTED(); | 556 UNIMPLEMENTED(); |
| 475 } | 557 } |
| 476 return *this; | 558 return *this; |
| 477 } | 559 } |
| 478 | 560 |
| 479 | 561 |
| 480 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( | 562 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( |
| 481 Register object, const Handle<String> name, int feedback_slot, | 563 Register object, const Handle<String> name, int feedback_slot, |
| 482 LanguageMode language_mode) { | 564 LanguageMode language_mode) { |
| 483 Bytecode bytecode = BytecodeForLoadIC(language_mode); | 565 RegisterTranslationScope translator(this); |
| 484 size_t name_index = GetConstantPoolEntry(name); | 566 size_t name_index = GetConstantPoolEntry(name); |
| 485 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { | 567 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { |
| 486 Output(bytecode, object.ToRawOperand(), static_cast<uint8_t>(name_index), | 568 translator.set_bytecode(BytecodeForLoadIC(language_mode)); |
| 487 static_cast<uint8_t>(feedback_slot)); | |
| 488 } else if (FitsInIdx16Operand(name_index) && | 569 } else if (FitsInIdx16Operand(name_index) && |
| 489 FitsInIdx16Operand(feedback_slot)) { | 570 FitsInIdx16Operand(feedback_slot)) { |
| 490 Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(), | 571 translator.set_bytecode( |
| 491 static_cast<uint16_t>(name_index), | 572 BytecodeForWideOperands(BytecodeForLoadIC(language_mode))); |
| 492 static_cast<uint16_t>(feedback_slot)); | |
| 493 } else { | 573 } else { |
| 494 UNIMPLEMENTED(); | 574 UNIMPLEMENTED(); |
| 495 } | 575 } |
| 576 object = translator.Translate(object); | |
| 577 Output(translator.bytecode(), object.ToRawOperand(), | |
| 578 static_cast<uint16_t>(name_index), | |
| 579 static_cast<uint16_t>(feedback_slot)); | |
|
rmcilroy
2016/01/22 17:50:56
Maybe just cast directly to uint32_t now so that w
| |
| 496 return *this; | 580 return *this; |
| 497 } | 581 } |
| 498 | 582 |
| 499 | 583 |
| 500 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( | 584 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( |
| 501 Register object, int feedback_slot, LanguageMode language_mode) { | 585 Register object, int feedback_slot, LanguageMode language_mode) { |
| 502 Bytecode bytecode = BytecodeForKeyedLoadIC(language_mode); | 586 RegisterTranslationScope translator(this); |
| 503 if (FitsInIdx8Operand(feedback_slot)) { | 587 if (FitsInIdx8Operand(feedback_slot)) { |
| 504 Output(bytecode, object.ToRawOperand(), | 588 translator.set_bytecode(BytecodeForKeyedLoadIC(language_mode)); |
| 505 static_cast<uint8_t>(feedback_slot)); | |
| 506 } else if (FitsInIdx16Operand(feedback_slot)) { | 589 } else if (FitsInIdx16Operand(feedback_slot)) { |
| 507 Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(), | 590 translator.set_bytecode( |
| 508 static_cast<uint16_t>(feedback_slot)); | 591 BytecodeForWideOperands(BytecodeForKeyedLoadIC(language_mode))); |
| 509 } else { | 592 } else { |
| 510 UNIMPLEMENTED(); | 593 UNIMPLEMENTED(); |
| 511 } | 594 } |
| 595 object = translator.Translate(object); | |
| 596 Output(translator.bytecode(), object.ToRawOperand(), | |
| 597 static_cast<uint16_t>(feedback_slot)); | |
| 512 return *this; | 598 return *this; |
| 513 } | 599 } |
| 514 | 600 |
| 515 | 601 |
| 516 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( | 602 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( |
| 517 Register object, const Handle<String> name, int feedback_slot, | 603 Register object, const Handle<String> name, int feedback_slot, |
| 518 LanguageMode language_mode) { | 604 LanguageMode language_mode) { |
| 519 Bytecode bytecode = BytecodeForStoreIC(language_mode); | |
| 520 size_t name_index = GetConstantPoolEntry(name); | 605 size_t name_index = GetConstantPoolEntry(name); |
| 606 RegisterTranslationScope translator(this); | |
| 521 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { | 607 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { |
| 522 Output(bytecode, object.ToRawOperand(), static_cast<uint8_t>(name_index), | 608 translator.set_bytecode(BytecodeForStoreIC(language_mode)); |
| 523 static_cast<uint8_t>(feedback_slot)); | |
| 524 } else if (FitsInIdx16Operand(name_index) && | 609 } else if (FitsInIdx16Operand(name_index) && |
| 525 FitsInIdx16Operand(feedback_slot)) { | 610 FitsInIdx16Operand(feedback_slot)) { |
| 526 Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(), | 611 translator.set_bytecode( |
| 527 static_cast<uint16_t>(name_index), | 612 BytecodeForWideOperands(BytecodeForStoreIC(language_mode))); |
| 528 static_cast<uint16_t>(feedback_slot)); | |
| 529 } else { | 613 } else { |
| 530 UNIMPLEMENTED(); | 614 UNIMPLEMENTED(); |
| 531 } | 615 } |
| 616 object = translator.Translate(object); | |
| 617 Output(translator.bytecode(), object.ToRawOperand(), | |
| 618 static_cast<uint16_t>(name_index), | |
| 619 static_cast<uint16_t>(feedback_slot)); | |
| 532 return *this; | 620 return *this; |
| 533 } | 621 } |
| 534 | 622 |
| 535 | 623 |
| 536 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( | 624 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( |
| 537 Register object, Register key, int feedback_slot, | 625 Register object, Register key, int feedback_slot, |
| 538 LanguageMode language_mode) { | 626 LanguageMode language_mode) { |
| 539 Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode); | 627 RegisterTranslationScope translator(this); |
| 540 if (FitsInIdx8Operand(feedback_slot)) { | 628 if (FitsInIdx8Operand(feedback_slot)) { |
| 541 Output(bytecode, object.ToRawOperand(), key.ToRawOperand(), | 629 translator.set_bytecode(BytecodeForKeyedStoreIC(language_mode)); |
| 542 static_cast<uint8_t>(feedback_slot)); | |
| 543 } else if (FitsInIdx16Operand(feedback_slot)) { | 630 } else if (FitsInIdx16Operand(feedback_slot)) { |
| 544 Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(), | 631 translator.set_bytecode( |
| 545 key.ToRawOperand(), static_cast<uint16_t>(feedback_slot)); | 632 BytecodeForWideOperands(BytecodeForKeyedStoreIC(language_mode))); |
| 546 } else { | 633 } else { |
| 547 UNIMPLEMENTED(); | 634 UNIMPLEMENTED(); |
| 548 } | 635 } |
| 636 object = translator.Translate(object); | |
| 637 key = translator.Translate(key); | |
| 638 Output(translator.bytecode(), object.ToRawOperand(), key.ToRawOperand(), | |
| 639 static_cast<uint16_t>(feedback_slot)); | |
| 549 return *this; | 640 return *this; |
| 550 } | 641 } |
| 551 | 642 |
| 552 | 643 |
| 553 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure( | 644 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure( |
| 554 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) { | 645 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) { |
| 555 size_t entry = GetConstantPoolEntry(shared_info); | 646 size_t entry = GetConstantPoolEntry(shared_info); |
| 556 DCHECK(FitsInImm8Operand(tenured)); | 647 DCHECK(FitsInImm8Operand(tenured)); |
| 557 if (FitsInIdx8Operand(entry)) { | 648 if (FitsInIdx8Operand(entry)) { |
| 558 Output(Bytecode::kCreateClosure, static_cast<uint8_t>(entry), | 649 Output(Bytecode::kCreateClosure, static_cast<uint8_t>(entry), |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 633 static_cast<uint16_t>(constant_properties_entry), | 724 static_cast<uint16_t>(constant_properties_entry), |
| 634 static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags)); | 725 static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags)); |
| 635 } else { | 726 } else { |
| 636 UNIMPLEMENTED(); | 727 UNIMPLEMENTED(); |
| 637 } | 728 } |
| 638 return *this; | 729 return *this; |
| 639 } | 730 } |
| 640 | 731 |
| 641 | 732 |
| 642 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) { | 733 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) { |
| 643 Output(Bytecode::kPushContext, context.ToRawOperand()); | 734 RegisterTranslationScope translator(this, Bytecode::kPushContext); |
| 735 context = translator.Translate(context); | |
| 736 Output(translator.bytecode(), context.ToRawOperand()); | |
| 644 return *this; | 737 return *this; |
| 645 } | 738 } |
| 646 | 739 |
| 647 | 740 |
| 648 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { | 741 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { |
| 649 Output(Bytecode::kPopContext, context.ToRawOperand()); | 742 RegisterTranslationScope translator(this, Bytecode::kPopContext); |
| 743 context = translator.Translate(context); | |
| 744 Output(translator.bytecode(), context.ToRawOperand()); | |
| 650 return *this; | 745 return *this; |
| 651 } | 746 } |
| 652 | 747 |
| 653 | 748 |
| 654 bool BytecodeArrayBuilder::NeedToBooleanCast() { | 749 bool BytecodeArrayBuilder::NeedToBooleanCast() { |
| 655 if (!LastBytecodeInSameBlock()) { | 750 if (!LastBytecodeInSameBlock()) { |
| 656 return true; | 751 return true; |
| 657 } | 752 } |
| 658 PreviousBytecodeHelper previous_bytecode(*this); | 753 PreviousBytecodeHelper previous_bytecode(*this); |
| 659 switch (previous_bytecode.GetBytecode()) { | 754 switch (previous_bytecode.GetBytecode()) { |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 962 | 1057 |
| 963 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { | 1058 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { |
| 964 Output(Bytecode::kReturn); | 1059 Output(Bytecode::kReturn); |
| 965 exit_seen_in_block_ = true; | 1060 exit_seen_in_block_ = true; |
| 966 return *this; | 1061 return *this; |
| 967 } | 1062 } |
| 968 | 1063 |
| 969 | 1064 |
| 970 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare( | 1065 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare( |
| 971 Register cache_info_triple) { | 1066 Register cache_info_triple) { |
| 1067 RegisterTranslationScope translator(this); | |
| 972 if (FitsInReg8Operand(cache_info_triple)) { | 1068 if (FitsInReg8Operand(cache_info_triple)) { |
| 973 Output(Bytecode::kForInPrepare, cache_info_triple.ToRawOperand()); | 1069 translator.set_bytecode(Bytecode::kForInPrepare); |
| 974 } else if (FitsInReg16Operand(cache_info_triple)) { | 1070 } else if (FitsInReg16Operand(cache_info_triple)) { |
| 975 Output(Bytecode::kForInPrepareWide, cache_info_triple.ToRawOperand()); | 1071 translator.set_bytecode(Bytecode::kForInPrepareWide); |
| 976 } else { | 1072 } else { |
| 977 UNIMPLEMENTED(); | 1073 UNIMPLEMENTED(); |
| 978 } | 1074 } |
| 1075 cache_info_triple = translator.Translate(cache_info_triple); | |
| 1076 Output(translator.bytecode(), cache_info_triple.ToRawOperand()); | |
| 979 return *this; | 1077 return *this; |
| 980 } | 1078 } |
| 981 | 1079 |
| 982 | 1080 |
| 983 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index, | 1081 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index, |
| 984 Register cache_length) { | 1082 Register cache_length) { |
| 985 Output(Bytecode::kForInDone, index.ToRawOperand(), | 1083 RegisterTranslationScope translator(this, Bytecode::kForInDone); |
| 1084 index = translator.Translate(index); | |
| 1085 cache_length = translator.Translate(cache_length); | |
| 1086 Output(translator.bytecode(), index.ToRawOperand(), | |
| 986 cache_length.ToRawOperand()); | 1087 cache_length.ToRawOperand()); |
| 987 return *this; | 1088 return *this; |
| 988 } | 1089 } |
| 989 | 1090 |
| 990 | 1091 |
| 991 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext( | 1092 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext( |
| 992 Register receiver, Register index, Register cache_type_array_pair) { | 1093 Register receiver, Register index, Register cache_type_array_pair) { |
| 1094 RegisterTranslationScope translator(this); | |
| 993 if (FitsInReg8Operand(receiver) && FitsInReg8Operand(index) && | 1095 if (FitsInReg8Operand(receiver) && FitsInReg8Operand(index) && |
| 994 FitsInReg8Operand(cache_type_array_pair)) { | 1096 FitsInReg8Operand(cache_type_array_pair)) { |
| 995 Output(Bytecode::kForInNext, receiver.ToRawOperand(), index.ToRawOperand(), | 1097 translator.set_bytecode(Bytecode::kForInNext); |
| 996 cache_type_array_pair.ToRawOperand()); | |
| 997 } else if (FitsInReg16Operand(receiver) && FitsInReg16Operand(index) && | 1098 } else if (FitsInReg16Operand(receiver) && FitsInReg16Operand(index) && |
| 998 FitsInReg16Operand(cache_type_array_pair)) { | 1099 FitsInReg16Operand(cache_type_array_pair)) { |
| 999 Output(Bytecode::kForInNextWide, receiver.ToRawOperand(), | 1100 translator.set_bytecode(Bytecode::kForInNextWide); |
| 1000 index.ToRawOperand(), cache_type_array_pair.ToRawOperand()); | |
| 1001 } else { | 1101 } else { |
| 1002 UNIMPLEMENTED(); | 1102 UNIMPLEMENTED(); |
| 1003 } | 1103 } |
| 1104 receiver = translator.Translate(receiver); | |
| 1105 index = translator.Translate(index); | |
| 1106 cache_type_array_pair = translator.Translate(cache_type_array_pair); | |
| 1107 Output(translator.bytecode(), receiver.ToRawOperand(), index.ToRawOperand(), | |
| 1108 cache_type_array_pair.ToRawOperand()); | |
| 1004 return *this; | 1109 return *this; |
| 1005 } | 1110 } |
| 1006 | 1111 |
| 1007 | 1112 |
| 1008 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) { | 1113 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) { |
| 1009 Output(Bytecode::kForInStep, index.ToRawOperand()); | 1114 RegisterTranslationScope translator(this, Bytecode::kForInStep); |
| 1115 index = translator.Translate(index); | |
| 1116 Output(translator.bytecode(), index.ToRawOperand()); | |
| 1010 return *this; | 1117 return *this; |
| 1011 } | 1118 } |
| 1012 | 1119 |
| 1013 | 1120 |
| 1014 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id, | 1121 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id, |
| 1015 bool will_catch) { | 1122 bool will_catch) { |
| 1016 handler_table_builder()->SetHandlerTarget(handler_id, bytecodes()->size()); | 1123 handler_table_builder()->SetHandlerTarget(handler_id, bytecodes()->size()); |
| 1017 handler_table_builder()->SetPrediction(handler_id, will_catch); | 1124 handler_table_builder()->SetPrediction(handler_id, will_catch); |
| 1018 return *this; | 1125 return *this; |
| 1019 } | 1126 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1044 LoadUndefined(); | 1151 LoadUndefined(); |
| 1045 Return(); | 1152 Return(); |
| 1046 } | 1153 } |
| 1047 } | 1154 } |
| 1048 | 1155 |
| 1049 | 1156 |
| 1050 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, | 1157 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, |
| 1051 Register receiver, | 1158 Register receiver, |
| 1052 size_t arg_count, | 1159 size_t arg_count, |
| 1053 int feedback_slot) { | 1160 int feedback_slot) { |
| 1161 RegisterTranslationScope translator(this); | |
| 1054 if (FitsInReg8Operand(callable) && FitsInReg8Operand(receiver) && | 1162 if (FitsInReg8Operand(callable) && FitsInReg8Operand(receiver) && |
| 1055 FitsInIdx8Operand(arg_count) && FitsInIdx8Operand(feedback_slot)) { | 1163 FitsInIdx8Operand(arg_count) && FitsInIdx8Operand(feedback_slot)) { |
| 1056 Output(Bytecode::kCall, callable.ToRawOperand(), receiver.ToRawOperand(), | 1164 translator.set_bytecode(Bytecode::kCall); |
| 1057 static_cast<uint8_t>(arg_count), | |
| 1058 static_cast<uint8_t>(feedback_slot)); | |
| 1059 } else if (FitsInReg16Operand(callable) && FitsInReg16Operand(receiver) && | 1165 } else if (FitsInReg16Operand(callable) && FitsInReg16Operand(receiver) && |
| 1060 FitsInIdx16Operand(arg_count) && | 1166 FitsInIdx16Operand(arg_count) && |
| 1061 FitsInIdx16Operand(feedback_slot)) { | 1167 FitsInIdx16Operand(feedback_slot)) { |
| 1062 Output(Bytecode::kCallWide, callable.ToRawOperand(), | 1168 translator.set_bytecode(Bytecode::kCallWide); |
| 1063 receiver.ToRawOperand(), static_cast<uint16_t>(arg_count), | |
| 1064 static_cast<uint16_t>(feedback_slot)); | |
| 1065 } else { | 1169 } else { |
| 1066 UNIMPLEMENTED(); | 1170 UNIMPLEMENTED(); |
| 1067 } | 1171 } |
| 1172 callable = translator.Translate(callable); | |
| 1173 receiver = translator.Translate(receiver); | |
| 1174 Output(translator.bytecode(), callable.ToRawOperand(), | |
| 1175 receiver.ToRawOperand(), static_cast<uint16_t>(arg_count), | |
| 1176 static_cast<uint16_t>(feedback_slot)); | |
| 1068 return *this; | 1177 return *this; |
| 1069 } | 1178 } |
| 1070 | 1179 |
| 1071 | 1180 |
| 1072 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, | 1181 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, |
| 1073 Register first_arg, | 1182 Register first_arg, |
| 1074 size_t arg_count) { | 1183 size_t arg_count) { |
| 1075 if (!first_arg.is_valid()) { | 1184 if (!first_arg.is_valid()) { |
| 1076 DCHECK_EQ(0u, arg_count); | 1185 DCHECK_EQ(0u, arg_count); |
| 1077 first_arg = Register(0); | 1186 first_arg = Register(0); |
| 1078 } | 1187 } |
| 1079 | 1188 |
| 1189 RegisterTranslationScope translator(this); | |
| 1080 if (FitsInReg8Operand(constructor) && FitsInReg8Operand(first_arg) && | 1190 if (FitsInReg8Operand(constructor) && FitsInReg8Operand(first_arg) && |
| 1081 FitsInIdx8Operand(arg_count)) { | 1191 FitsInIdx8Operand(arg_count)) { |
| 1082 Output(Bytecode::kNew, constructor.ToRawOperand(), first_arg.ToRawOperand(), | 1192 translator.set_bytecode(Bytecode::kNew); |
| 1083 static_cast<uint8_t>(arg_count)); | |
| 1084 } else if (FitsInReg16Operand(constructor) && FitsInReg16Operand(first_arg) && | 1193 } else if (FitsInReg16Operand(constructor) && FitsInReg16Operand(first_arg) && |
| 1085 FitsInIdx16Operand(arg_count)) { | 1194 FitsInIdx16Operand(arg_count)) { |
| 1086 Output(Bytecode::kNewWide, constructor.ToRawOperand(), | 1195 translator.set_bytecode(Bytecode::kNewWide); |
| 1087 first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count)); | |
| 1088 } else { | 1196 } else { |
| 1089 UNIMPLEMENTED(); | 1197 UNIMPLEMENTED(); |
| 1090 } | 1198 } |
| 1199 constructor = translator.Translate(constructor); | |
| 1200 first_arg = translator.Translate(first_arg); | |
| 1201 Output(translator.bytecode(), constructor.ToRawOperand(), | |
| 1202 first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count)); | |
| 1091 return *this; | 1203 return *this; |
| 1092 } | 1204 } |
| 1093 | 1205 |
| 1094 | 1206 |
| 1095 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( | 1207 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( |
| 1096 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { | 1208 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { |
| 1097 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); | 1209 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); |
| 1098 DCHECK(FitsInIdx16Operand(function_id)); | 1210 DCHECK(FitsInIdx16Operand(function_id)); |
| 1099 if (!first_arg.is_valid()) { | 1211 if (!first_arg.is_valid()) { |
| 1100 DCHECK_EQ(0u, arg_count); | 1212 DCHECK_EQ(0u, arg_count); |
| 1101 first_arg = Register(0); | 1213 first_arg = Register(0); |
| 1102 } | 1214 } |
| 1215 | |
| 1216 RegisterTranslationScope translator(this); | |
| 1103 if (FitsInReg8Operand(first_arg) && FitsInIdx8Operand(arg_count)) { | 1217 if (FitsInReg8Operand(first_arg) && FitsInIdx8Operand(arg_count)) { |
| 1104 Output(Bytecode::kCallRuntime, static_cast<uint16_t>(function_id), | 1218 translator.set_bytecode(Bytecode::kCallRuntime); |
| 1105 first_arg.ToRawOperand(), static_cast<uint8_t>(arg_count)); | |
| 1106 } else if (FitsInReg16Operand(first_arg) && FitsInIdx16Operand(arg_count)) { | 1219 } else if (FitsInReg16Operand(first_arg) && FitsInIdx16Operand(arg_count)) { |
| 1107 Output(Bytecode::kCallRuntimeWide, static_cast<uint16_t>(function_id), | 1220 translator.set_bytecode(Bytecode::kCallRuntimeWide); |
| 1108 first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count)); | |
| 1109 } else { | 1221 } else { |
| 1110 UNIMPLEMENTED(); | 1222 UNIMPLEMENTED(); |
| 1111 } | 1223 } |
| 1224 first_arg = translator.Translate(first_arg); | |
| 1225 Output(translator.bytecode(), static_cast<uint16_t>(function_id), | |
| 1226 first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count)); | |
| 1112 return *this; | 1227 return *this; |
| 1113 } | 1228 } |
| 1114 | 1229 |
| 1115 | 1230 |
| 1116 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( | 1231 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( |
| 1117 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, | 1232 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, |
| 1118 Register first_return) { | 1233 Register first_return) { |
| 1119 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); | 1234 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); |
| 1120 DCHECK(FitsInIdx16Operand(function_id)); | 1235 DCHECK(FitsInIdx16Operand(function_id)); |
| 1121 if (!first_arg.is_valid()) { | 1236 if (!first_arg.is_valid()) { |
| 1122 DCHECK_EQ(0u, arg_count); | 1237 DCHECK_EQ(0u, arg_count); |
| 1123 first_arg = Register(0); | 1238 first_arg = Register(0); |
| 1124 } | 1239 } |
| 1240 | |
| 1241 RegisterTranslationScope translator(this); | |
| 1125 if (FitsInReg8Operand(first_arg) && FitsInIdx8Operand(arg_count) && | 1242 if (FitsInReg8Operand(first_arg) && FitsInIdx8Operand(arg_count) && |
| 1126 FitsInReg8Operand(first_return)) { | 1243 FitsInReg8Operand(first_return)) { |
| 1127 Output(Bytecode::kCallRuntimeForPair, static_cast<uint16_t>(function_id), | 1244 translator.set_bytecode(Bytecode::kCallRuntimeForPair); |
| 1128 first_arg.ToRawOperand(), static_cast<uint8_t>(arg_count), | |
| 1129 first_return.ToRawOperand()); | |
| 1130 } else if (FitsInReg16Operand(first_arg) && FitsInIdx16Operand(arg_count) && | 1245 } else if (FitsInReg16Operand(first_arg) && FitsInIdx16Operand(arg_count) && |
| 1131 FitsInReg16Operand(first_return)) { | 1246 FitsInReg16Operand(first_return)) { |
| 1132 Output(Bytecode::kCallRuntimeForPairWide, | 1247 translator.set_bytecode(Bytecode::kCallRuntimeForPairWide); |
| 1133 static_cast<uint16_t>(function_id), first_arg.ToRawOperand(), | |
| 1134 static_cast<uint16_t>(arg_count), first_return.ToRawOperand()); | |
| 1135 } else { | 1248 } else { |
| 1136 UNIMPLEMENTED(); | 1249 UNIMPLEMENTED(); |
| 1137 } | 1250 } |
| 1251 first_arg = translator.Translate(first_arg); | |
| 1252 first_return = translator.Translate(first_return); | |
| 1253 Output(translator.bytecode(), static_cast<uint16_t>(function_id), | |
| 1254 first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count), | |
| 1255 first_return.ToRawOperand()); | |
| 1138 return *this; | 1256 return *this; |
| 1139 } | 1257 } |
| 1140 | 1258 |
| 1141 | 1259 |
| 1142 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(int context_index, | 1260 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(int context_index, |
| 1143 Register receiver, | 1261 Register receiver, |
| 1144 size_t arg_count) { | 1262 size_t arg_count) { |
| 1145 DCHECK(FitsInIdx16Operand(context_index)); | 1263 DCHECK(FitsInIdx16Operand(context_index)); |
| 1264 | |
| 1265 RegisterTranslationScope translator(this); | |
| 1146 if (FitsInReg8Operand(receiver) && FitsInIdx8Operand(arg_count)) { | 1266 if (FitsInReg8Operand(receiver) && FitsInIdx8Operand(arg_count)) { |
| 1147 Output(Bytecode::kCallJSRuntime, static_cast<uint16_t>(context_index), | 1267 translator.set_bytecode(Bytecode::kCallJSRuntime); |
| 1148 receiver.ToRawOperand(), static_cast<uint8_t>(arg_count)); | |
| 1149 } else if (FitsInReg16Operand(receiver) && FitsInIdx16Operand(arg_count)) { | 1268 } else if (FitsInReg16Operand(receiver) && FitsInIdx16Operand(arg_count)) { |
| 1150 Output(Bytecode::kCallJSRuntimeWide, static_cast<uint16_t>(context_index), | 1269 translator.set_bytecode(Bytecode::kCallJSRuntimeWide); |
| 1151 receiver.ToRawOperand(), static_cast<uint16_t>(arg_count)); | |
| 1152 } else { | 1270 } else { |
| 1153 UNIMPLEMENTED(); | 1271 UNIMPLEMENTED(); |
| 1154 } | 1272 } |
| 1273 receiver = translator.Translate(receiver); | |
| 1274 Output(translator.bytecode(), static_cast<uint16_t>(context_index), | |
| 1275 receiver.ToRawOperand(), static_cast<uint16_t>(arg_count)); | |
| 1155 return *this; | 1276 return *this; |
| 1156 } | 1277 } |
| 1157 | 1278 |
| 1158 | 1279 |
| 1159 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, | 1280 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, |
| 1160 LanguageMode language_mode) { | 1281 LanguageMode language_mode) { |
| 1161 Output(BytecodeForDelete(language_mode), object.ToRawOperand()); | 1282 RegisterTranslationScope translator(this, BytecodeForDelete(language_mode)); |
| 1283 object = translator.Translate(object); | |
| 1284 Output(translator.bytecode(), object.ToRawOperand()); | |
| 1162 return *this; | 1285 return *this; |
| 1163 } | 1286 } |
| 1164 | 1287 |
| 1165 | 1288 |
| 1166 BytecodeArrayBuilder& BytecodeArrayBuilder::DeleteLookupSlot() { | 1289 BytecodeArrayBuilder& BytecodeArrayBuilder::DeleteLookupSlot() { |
| 1167 Output(Bytecode::kDeleteLookupSlot); | 1290 Output(Bytecode::kDeleteLookupSlot); |
| 1168 return *this; | 1291 return *this; |
| 1169 } | 1292 } |
| 1170 | 1293 |
| 1171 | 1294 |
| 1172 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { | 1295 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { |
| 1173 return constant_array_builder()->Insert(object); | 1296 return constant_array_builder()->Insert(object); |
| 1174 } | 1297 } |
| 1175 | 1298 |
| 1176 | 1299 |
| 1300 void BytecodeArrayBuilder::ForgeTemporaryRegister() { | |
| 1301 temporary_register_count_++; | |
| 1302 } | |
| 1303 | |
| 1304 | |
| 1177 int BytecodeArrayBuilder::BorrowTemporaryRegister() { | 1305 int BytecodeArrayBuilder::BorrowTemporaryRegister() { |
| 1178 if (free_temporaries_.empty()) { | 1306 if (free_temporaries_.empty()) { |
| 1179 temporary_register_count_ += 1; | 1307 ForgeTemporaryRegister(); |
| 1180 return last_temporary_register().index(); | 1308 return last_temporary_register().index(); |
| 1181 } else { | 1309 } else { |
| 1182 auto pos = free_temporaries_.begin(); | 1310 auto pos = free_temporaries_.begin(); |
| 1183 int retval = *pos; | 1311 int retval = *pos; |
| 1184 free_temporaries_.erase(pos); | 1312 free_temporaries_.erase(pos); |
| 1185 return retval; | 1313 return retval; |
| 1186 } | 1314 } |
| 1187 } | 1315 } |
| 1188 | 1316 |
| 1189 | 1317 |
| 1190 int BytecodeArrayBuilder::BorrowTemporaryRegisterNotInRange(int start_index, | 1318 int BytecodeArrayBuilder::BorrowTemporaryRegisterNotInRange(int start_index, |
| 1191 int end_index) { | 1319 int end_index) { |
| 1192 auto index = free_temporaries_.lower_bound(start_index); | 1320 auto index = free_temporaries_.lower_bound(start_index); |
| 1193 if (index == free_temporaries_.begin()) { | 1321 if (index == free_temporaries_.begin()) { |
| 1194 // If start_index is the first free register, check for a register | 1322 // If start_index is the first free register, check for a register |
| 1195 // greater than end_index. | 1323 // greater than end_index. |
| 1196 index = free_temporaries_.upper_bound(end_index); | 1324 index = free_temporaries_.upper_bound(end_index); |
| 1197 if (index == free_temporaries_.end()) { | 1325 if (index == free_temporaries_.end()) { |
| 1198 temporary_register_count_ += 1; | 1326 ForgeTemporaryRegister(); |
| 1199 return last_temporary_register().index(); | 1327 return last_temporary_register().index(); |
| 1200 } | 1328 } |
| 1201 } else { | 1329 } else { |
| 1202 // If there is a free register < start_index | 1330 // If there is a free register < start_index |
| 1203 index--; | 1331 index--; |
| 1204 } | 1332 } |
| 1205 | 1333 |
| 1206 int retval = *index; | 1334 int retval = *index; |
| 1207 free_temporaries_.erase(index); | 1335 free_temporaries_.erase(index); |
| 1208 return retval; | 1336 return retval; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1220 free_temporaries_.insert(reg_index); | 1348 free_temporaries_.insert(reg_index); |
| 1221 } | 1349 } |
| 1222 | 1350 |
| 1223 | 1351 |
| 1224 int BytecodeArrayBuilder::PrepareForConsecutiveTemporaryRegisters( | 1352 int BytecodeArrayBuilder::PrepareForConsecutiveTemporaryRegisters( |
| 1225 size_t count) { | 1353 size_t count) { |
| 1226 if (count == 0) { | 1354 if (count == 0) { |
| 1227 return -1; | 1355 return -1; |
| 1228 } | 1356 } |
| 1229 | 1357 |
| 1358 // TODO(oth): replace use of set<> here for free_temporaries with a | |
| 1359 // more efficient structure. And/or partition into two searches - | |
| 1360 // one before the translation window and one after. | |
| 1361 if (free_temporaries_.empty()) { | |
|
rmcilroy
2016/01/22 17:50:56
Please add a comment on why you are having to forg
| |
| 1362 ForgeTemporaryRegister(); | |
| 1363 free_temporaries_.insert(last_temporary_register().index()); | |
| 1364 } | |
| 1365 | |
| 1230 // Search within existing temporaries for a run. | 1366 // Search within existing temporaries for a run. |
| 1231 auto start = free_temporaries_.begin(); | 1367 auto start = free_temporaries_.begin(); |
| 1232 size_t run_length = 0; | 1368 size_t run_length = 0; |
| 1233 for (auto run_end = start; run_end != free_temporaries_.end(); run_end++) { | 1369 for (auto run_end = start; run_end != free_temporaries_.end(); run_end++) { |
| 1234 if (*run_end != *start + static_cast<int>(run_length)) { | 1370 int expected = *start + static_cast<int>(run_length); |
| 1371 if (*run_end != expected) { | |
| 1235 start = run_end; | 1372 start = run_end; |
| 1236 run_length = 0; | 1373 run_length = 0; |
| 1237 } | 1374 } |
| 1375 Register reg_start(*start); | |
| 1376 Register reg_expected(expected); | |
| 1377 if (RegisterTranslator::DistanceToTranslationWindow(reg_start) > 0 && | |
| 1378 RegisterTranslator::DistanceToTranslationWindow(reg_expected) <= 0) { | |
| 1379 // Run straddles the translation window boundary where there is | |
| 1380 // a hidden discontinuity. | |
|
rmcilroy
2016/01/22 17:50:56
/s/discontinuity/hole in allocatable registers ?
| |
| 1381 start = run_end; | |
| 1382 run_length = 0; | |
| 1383 } | |
| 1238 if (++run_length == count) { | 1384 if (++run_length == count) { |
| 1239 return *start; | 1385 return *start; |
| 1240 } | 1386 } |
| 1241 } | 1387 } |
| 1242 | 1388 |
| 1243 // Continue run if possible across existing last temporary. | 1389 // Continue run if possible across existing last temporary. |
| 1244 if (temporary_register_count_ > 0 && | 1390 if (temporary_register_count_ > 0 && |
| 1245 (start == free_temporaries_.end() || | 1391 (start == free_temporaries_.end() || |
| 1246 *start + static_cast<int>(run_length) != | 1392 *start + static_cast<int>(run_length) != |
| 1247 last_temporary_register().index() + 1)) { | 1393 last_temporary_register().index() + 1)) { |
| 1248 run_length = 0; | 1394 run_length = 0; |
| 1249 } | 1395 } |
| 1250 | 1396 |
| 1397 // Pad temporaries if extended run would cross translation boundary. | |
| 1398 Register reg_first(*start); | |
| 1399 Register reg_last(*start + static_cast<int>(count) - 1); | |
| 1400 DCHECK_GT(RegisterTranslator::DistanceToTranslationWindow(reg_first), | |
| 1401 RegisterTranslator::DistanceToTranslationWindow(reg_last)); | |
| 1402 while (RegisterTranslator::DistanceToTranslationWindow(reg_first) > 0 && | |
| 1403 RegisterTranslator::DistanceToTranslationWindow(reg_last) <= 0) { | |
| 1404 ForgeTemporaryRegister(); | |
| 1405 free_temporaries_.insert(last_temporary_register().index()); | |
| 1406 start = --free_temporaries_.end(); | |
| 1407 reg_first = Register(*start); | |
| 1408 reg_last = Register(*start + static_cast<int>(count) - 1); | |
| 1409 run_length = 0; | |
| 1410 } | |
| 1411 | |
| 1251 // Ensure enough registers for run. | 1412 // Ensure enough registers for run. |
| 1252 while (run_length++ < count) { | 1413 while (run_length++ < count) { |
| 1253 temporary_register_count_++; | 1414 ForgeTemporaryRegister(); |
| 1254 free_temporaries_.insert(last_temporary_register().index()); | 1415 free_temporaries_.insert(last_temporary_register().index()); |
| 1255 } | 1416 } |
| 1256 return last_temporary_register().index() - static_cast<int>(count) + 1; | 1417 |
| 1418 int run_start = | |
| 1419 last_temporary_register().index() - static_cast<int>(count) + 1; | |
| 1420 DCHECK(RegisterTranslator::DistanceToTranslationWindow(Register(run_start)) <= | |
| 1421 0 || | |
| 1422 RegisterTranslator::DistanceToTranslationWindow( | |
| 1423 Register(run_start + static_cast<int>(count) - 1)) > 0); | |
| 1424 return run_start; | |
| 1257 } | 1425 } |
| 1258 | 1426 |
| 1259 | 1427 |
| 1260 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { | 1428 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { |
| 1261 if (temporary_register_count_ > 0) { | 1429 if (temporary_register_count_ > 0) { |
| 1262 DCHECK(reg.index() >= first_temporary_register().index() && | 1430 DCHECK(reg.index() >= first_temporary_register().index() && |
| 1263 reg.index() <= last_temporary_register().index()); | 1431 reg.index() <= last_temporary_register().index()); |
| 1264 return free_temporaries_.find(reg.index()) == free_temporaries_.end(); | 1432 return free_temporaries_.find(reg.index()) == free_temporaries_.end(); |
| 1265 } else { | 1433 } else { |
| 1266 return false; | 1434 return false; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1317 } | 1485 } |
| 1318 UNREACHABLE(); | 1486 UNREACHABLE(); |
| 1319 return false; | 1487 return false; |
| 1320 } | 1488 } |
| 1321 | 1489 |
| 1322 | 1490 |
| 1323 bool BytecodeArrayBuilder::RegisterIsValid(Register reg, | 1491 bool BytecodeArrayBuilder::RegisterIsValid(Register reg, |
| 1324 OperandType reg_type) const { | 1492 OperandType reg_type) const { |
| 1325 switch (Bytecodes::SizeOfOperand(reg_type)) { | 1493 switch (Bytecodes::SizeOfOperand(reg_type)) { |
| 1326 case OperandSize::kByte: | 1494 case OperandSize::kByte: |
| 1327 if (!FitsInReg8Operand(reg)) { return false; } | 1495 if (!FitsInReg8OperandUntranslated(reg)) { |
| 1496 return false; | |
| 1497 } | |
| 1328 break; | 1498 break; |
| 1329 case OperandSize::kShort: | 1499 case OperandSize::kShort: |
| 1330 if (!FitsInReg16Operand(reg)) { return false; } | 1500 if (!FitsInReg16OperandUntranslated(reg)) { |
| 1501 return false; | |
| 1502 } | |
| 1331 break; | 1503 break; |
| 1332 case OperandSize::kNone: | 1504 case OperandSize::kNone: |
| 1333 UNREACHABLE(); | 1505 UNREACHABLE(); |
| 1334 return false; | 1506 return false; |
| 1335 } | 1507 } |
| 1336 | 1508 |
| 1337 if (reg.is_function_context() || reg.is_function_closure() || | 1509 if (reg.is_function_context() || reg.is_function_closure() || |
| 1338 reg.is_new_target()) { | 1510 reg.is_new_target()) { |
| 1339 return true; | 1511 return true; |
| 1340 } else if (reg.is_parameter()) { | 1512 } else if (reg.is_parameter()) { |
| 1341 int parameter_index = reg.ToParameterIndex(parameter_count_); | 1513 int parameter_index = reg.ToParameterIndex(parameter_count_); |
| 1342 return parameter_index >= 0 && parameter_index < parameter_count_; | 1514 return parameter_index >= 0 && parameter_index < parameter_count_; |
| 1343 } else if (reg.index() < fixed_register_count()) { | 1515 } else if (translation_register_count() == 0) { |
| 1344 return true; | 1516 if (reg.index() < fixed_register_count()) { |
| 1517 return true; | |
| 1518 } else { | |
| 1519 return TemporaryRegisterIsLive(reg); | |
| 1520 } | |
| 1345 } else { | 1521 } else { |
| 1346 return TemporaryRegisterIsLive(reg); | 1522 return reg.index() < (fixed_and_temporary_register_count() + |
| 1523 translation_register_count()); | |
|
rmcilroy
2016/01/22 17:50:56
Does this not check for the temp being live. Could
| |
| 1347 } | 1524 } |
| 1348 } | 1525 } |
| 1349 | 1526 |
| 1350 | 1527 |
| 1351 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { | 1528 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { |
| 1352 return last_bytecode_start_ < bytecodes()->size() && | 1529 return last_bytecode_start_ < bytecodes()->size() && |
| 1353 last_bytecode_start_ >= last_block_end_; | 1530 last_bytecode_start_ >= last_block_end_; |
| 1354 } | 1531 } |
| 1355 | 1532 |
| 1356 | 1533 |
| 1357 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) { | 1534 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) { |
| 1358 if (LastBytecodeInSameBlock()) { | 1535 if (LastBytecodeInSameBlock()) { |
| 1359 PreviousBytecodeHelper previous_bytecode(*this); | 1536 PreviousBytecodeHelper previous_bytecode(*this); |
| 1360 Bytecode bytecode = previous_bytecode.GetBytecode(); | 1537 Bytecode bytecode = previous_bytecode.GetBytecode(); |
| 1361 if ((bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar) && | 1538 if (bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar) { |
| 1362 (reg == Register::FromOperand(previous_bytecode.GetOperand(0)))) { | 1539 Register previous = |
|
rmcilroy
2016/01/22 17:50:56
nit - previous_reg
| |
| 1363 return true; | 1540 Register::FromOperand(previous_bytecode.GetOperand(0)); |
| 1541 return previous == reg; | |
| 1364 } | 1542 } |
| 1365 } | 1543 } |
| 1366 return false; | 1544 return false; |
| 1367 } | 1545 } |
| 1368 | 1546 |
| 1369 | 1547 |
| 1370 // static | 1548 // static |
| 1371 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { | 1549 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { |
| 1372 switch (op) { | 1550 switch (op) { |
| 1373 case Token::Value::ADD: | 1551 case Token::Value::ADD: |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1666 | 1844 |
| 1667 | 1845 |
| 1668 // static | 1846 // static |
| 1669 bool BytecodeArrayBuilder::FitsInIdx16Operand(size_t value) { | 1847 bool BytecodeArrayBuilder::FitsInIdx16Operand(size_t value) { |
| 1670 return value <= static_cast<size_t>(kMaxUInt16); | 1848 return value <= static_cast<size_t>(kMaxUInt16); |
| 1671 } | 1849 } |
| 1672 | 1850 |
| 1673 | 1851 |
| 1674 // static | 1852 // static |
| 1675 bool BytecodeArrayBuilder::FitsInReg8Operand(Register value) { | 1853 bool BytecodeArrayBuilder::FitsInReg8Operand(Register value) { |
| 1676 return kMinInt8 <= value.index() && value.index() <= kMaxInt8; | 1854 return RegisterTranslator::FitsInReg8Operand(value); |
| 1855 } | |
| 1856 | |
| 1857 | |
| 1858 // static | |
| 1859 bool BytecodeArrayBuilder::FitsInReg8OperandUntranslated(Register value) { | |
| 1860 return value.is_byte_operand(); | |
| 1677 } | 1861 } |
| 1678 | 1862 |
| 1679 | 1863 |
| 1680 // static | 1864 // static |
| 1681 bool BytecodeArrayBuilder::FitsInReg16Operand(Register value) { | 1865 bool BytecodeArrayBuilder::FitsInReg16Operand(Register value) { |
| 1682 return kMinInt16 <= value.index() && value.index() <= kMaxInt16; | 1866 return RegisterTranslator::FitsInReg16Operand(value); |
| 1867 } | |
| 1868 | |
| 1869 | |
| 1870 // static | |
| 1871 bool BytecodeArrayBuilder::FitsInReg16OperandUntranslated(Register value) { | |
| 1872 return value.is_short_operand(); | |
| 1683 } | 1873 } |
| 1684 | 1874 |
| 1685 } // namespace interpreter | 1875 } // namespace interpreter |
| 1686 } // namespace internal | 1876 } // namespace internal |
| 1687 } // namespace v8 | 1877 } // namespace v8 |
| OLD | NEW |