| 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 #include "src/compiler.h" | 7 #include "src/compiler.h" |
| 8 #include "src/interpreter/bytecode-array-writer.h" | 8 #include "src/interpreter/bytecode-array-writer.h" |
| 9 #include "src/interpreter/bytecode-label.h" | 9 #include "src/interpreter/bytecode-label.h" |
| 10 #include "src/interpreter/bytecode-peephole-optimizer.h" | 10 #include "src/interpreter/bytecode-peephole-optimizer.h" |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 // throw. Hence we only invalidate the existing source position | 98 // throw. Hence we only invalidate the existing source position |
| 99 // information if it is used. | 99 // information if it is used. |
| 100 if (latest_source_info_.is_statement() || | 100 if (latest_source_info_.is_statement() || |
| 101 ExpressionPositionIsNeeded(node->bytecode())) { | 101 ExpressionPositionIsNeeded(node->bytecode())) { |
| 102 node->source_info() = latest_source_info_; | 102 node->source_info() = latest_source_info_; |
| 103 latest_source_info_.set_invalid(); | 103 latest_source_info_.set_invalid(); |
| 104 } | 104 } |
| 105 } | 105 } |
| 106 } | 106 } |
| 107 | 107 |
| 108 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | 108 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
| 109 BytecodeNode node(bytecode); | 109 uint32_t operand1, uint32_t operand2, |
| 110 uint32_t operand3) { |
| 111 DCHECK(OperandsAreValid(bytecode, 4, operand0, operand1, operand2, operand3)); |
| 112 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3); |
| 110 AttachSourceInfo(&node); | 113 AttachSourceInfo(&node); |
| 111 pipeline()->Write(&node); | 114 pipeline()->Write(&node); |
| 112 } | 115 } |
| 113 | 116 |
| 114 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | 117 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
| 115 OperandScale operand_scale, | 118 uint32_t operand1, uint32_t operand2) { |
| 116 uint32_t operand0, uint32_t operand1, | 119 DCHECK(OperandsAreValid(bytecode, 3, operand0, operand1, operand2)); |
| 117 uint32_t operand2, uint32_t operand3) { | 120 BytecodeNode node(bytecode, operand0, operand1, operand2); |
| 118 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); | |
| 119 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1)); | |
| 120 DCHECK(OperandIsValid(bytecode, operand_scale, 2, operand2)); | |
| 121 DCHECK(OperandIsValid(bytecode, operand_scale, 3, operand3)); | |
| 122 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3, | |
| 123 operand_scale); | |
| 124 AttachSourceInfo(&node); | 121 AttachSourceInfo(&node); |
| 125 pipeline()->Write(&node); | 122 pipeline()->Write(&node); |
| 126 } | 123 } |
| 127 | 124 |
| 128 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | 125 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
| 129 OperandScale operand_scale, | 126 uint32_t operand1) { |
| 130 uint32_t operand0, uint32_t operand1, | 127 DCHECK(OperandsAreValid(bytecode, 2, operand0, operand1)); |
| 131 uint32_t operand2) { | 128 BytecodeNode node(bytecode, operand0, operand1); |
| 132 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); | |
| 133 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1)); | |
| 134 DCHECK(OperandIsValid(bytecode, operand_scale, 2, operand2)); | |
| 135 BytecodeNode node(bytecode, operand0, operand1, operand2, operand_scale); | |
| 136 AttachSourceInfo(&node); | 129 AttachSourceInfo(&node); |
| 137 pipeline()->Write(&node); | 130 pipeline()->Write(&node); |
| 138 } | 131 } |
| 139 | 132 |
| 140 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | 133 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { |
| 141 OperandScale operand_scale, | 134 DCHECK(OperandsAreValid(bytecode, 1, operand0)); |
| 142 uint32_t operand0, uint32_t operand1) { | 135 BytecodeNode node(bytecode, operand0); |
| 143 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); | |
| 144 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1)); | |
| 145 BytecodeNode node(bytecode, operand0, operand1, operand_scale); | |
| 146 AttachSourceInfo(&node); | 136 AttachSourceInfo(&node); |
| 147 pipeline()->Write(&node); | 137 pipeline()->Write(&node); |
| 148 } | 138 } |
| 149 | 139 |
| 150 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | 140 void BytecodeArrayBuilder::Output(Bytecode bytecode) { |
| 151 OperandScale operand_scale, | 141 DCHECK(OperandsAreValid(bytecode, 0)); |
| 152 uint32_t operand0) { | 142 BytecodeNode node(bytecode); |
| 153 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); | |
| 154 BytecodeNode node(bytecode, operand0, operand_scale); | |
| 155 AttachSourceInfo(&node); | 143 AttachSourceInfo(&node); |
| 156 pipeline()->Write(&node); | 144 pipeline()->Write(&node); |
| 157 } | 145 } |
| 158 | 146 |
| 159 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 147 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, |
| 160 Register reg) { | 148 Register reg) { |
| 161 OperandScale operand_scale = | 149 Output(BytecodeForBinaryOperation(op), RegisterOperand(reg)); |
| 162 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); | |
| 163 OutputScaled(BytecodeForBinaryOperation(op), operand_scale, | |
| 164 RegisterOperand(reg)); | |
| 165 return *this; | 150 return *this; |
| 166 } | 151 } |
| 167 | 152 |
| 168 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op) { | 153 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op) { |
| 169 Output(BytecodeForCountOperation(op)); | 154 Output(BytecodeForCountOperation(op)); |
| 170 return *this; | 155 return *this; |
| 171 } | 156 } |
| 172 | 157 |
| 173 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { | 158 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { |
| 174 Output(Bytecode::kToBooleanLogicalNot); | 159 Output(Bytecode::kToBooleanLogicalNot); |
| 175 return *this; | 160 return *this; |
| 176 } | 161 } |
| 177 | 162 |
| 178 | 163 |
| 179 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { | 164 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { |
| 180 Output(Bytecode::kTypeOf); | 165 Output(Bytecode::kTypeOf); |
| 181 return *this; | 166 return *this; |
| 182 } | 167 } |
| 183 | 168 |
| 184 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op, | 169 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op, |
| 185 Register reg) { | 170 Register reg) { |
| 186 OperandScale operand_scale = | 171 Output(BytecodeForCompareOperation(op), RegisterOperand(reg)); |
| 187 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); | |
| 188 OutputScaled(BytecodeForCompareOperation(op), operand_scale, | |
| 189 RegisterOperand(reg)); | |
| 190 return *this; | 172 return *this; |
| 191 } | 173 } |
| 192 | 174 |
| 193 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( | 175 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( |
| 194 v8::internal::Smi* smi) { | 176 v8::internal::Smi* smi) { |
| 195 int32_t raw_smi = smi->value(); | 177 int32_t raw_smi = smi->value(); |
| 196 if (raw_smi == 0) { | 178 if (raw_smi == 0) { |
| 197 Output(Bytecode::kLdaZero); | 179 Output(Bytecode::kLdaZero); |
| 198 } else { | 180 } else { |
| 199 OperandSize operand_size = Bytecodes::SizeForSignedOperand(raw_smi); | 181 Output(Bytecode::kLdaSmi, SignedOperand(raw_smi)); |
| 200 OperandScale operand_scale = Bytecodes::OperandSizesToScale(operand_size); | |
| 201 OutputScaled(Bytecode::kLdaSmi, operand_scale, | |
| 202 SignedOperand(raw_smi, operand_size)); | |
| 203 } | 182 } |
| 204 return *this; | 183 return *this; |
| 205 } | 184 } |
| 206 | 185 |
| 207 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) { | 186 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) { |
| 208 size_t entry = GetConstantPoolEntry(object); | 187 size_t entry = GetConstantPoolEntry(object); |
| 209 OperandScale operand_scale = | 188 Output(Bytecode::kLdaConstant, UnsignedOperand(entry)); |
| 210 Bytecodes::OperandSizesToScale(Bytecodes::SizeForUnsignedOperand(entry)); | |
| 211 OutputScaled(Bytecode::kLdaConstant, operand_scale, UnsignedOperand(entry)); | |
| 212 return *this; | 189 return *this; |
| 213 } | 190 } |
| 214 | 191 |
| 215 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() { | 192 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() { |
| 216 Output(Bytecode::kLdaUndefined); | 193 Output(Bytecode::kLdaUndefined); |
| 217 return *this; | 194 return *this; |
| 218 } | 195 } |
| 219 | 196 |
| 220 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNull() { | 197 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNull() { |
| 221 Output(Bytecode::kLdaNull); | 198 Output(Bytecode::kLdaNull); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 232 return *this; | 209 return *this; |
| 233 } | 210 } |
| 234 | 211 |
| 235 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { | 212 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { |
| 236 Output(Bytecode::kLdaFalse); | 213 Output(Bytecode::kLdaFalse); |
| 237 return *this; | 214 return *this; |
| 238 } | 215 } |
| 239 | 216 |
| 240 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( | 217 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( |
| 241 Register reg) { | 218 Register reg) { |
| 242 OperandScale operand_scale = | 219 Output(Bytecode::kLdar, RegisterOperand(reg)); |
| 243 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); | |
| 244 OutputScaled(Bytecode::kLdar, operand_scale, RegisterOperand(reg)); | |
| 245 return *this; | 220 return *this; |
| 246 } | 221 } |
| 247 | 222 |
| 248 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( | 223 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( |
| 249 Register reg) { | 224 Register reg) { |
| 250 OperandScale operand_scale = | 225 Output(Bytecode::kStar, RegisterOperand(reg)); |
| 251 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); | |
| 252 OutputScaled(Bytecode::kStar, operand_scale, RegisterOperand(reg)); | |
| 253 return *this; | 226 return *this; |
| 254 } | 227 } |
| 255 | 228 |
| 256 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, | 229 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, |
| 257 Register to) { | 230 Register to) { |
| 258 DCHECK(from != to); | 231 DCHECK(from != to); |
| 259 OperandScale operand_scale = | 232 Output(Bytecode::kMov, RegisterOperand(from), RegisterOperand(to)); |
| 260 Bytecodes::OperandSizesToScale(from.SizeOfOperand(), to.SizeOfOperand()); | |
| 261 OutputScaled(Bytecode::kMov, operand_scale, RegisterOperand(from), | |
| 262 RegisterOperand(to)); | |
| 263 return *this; | 233 return *this; |
| 264 } | 234 } |
| 265 | 235 |
| 266 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal( | 236 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal( |
| 267 const Handle<String> name, int feedback_slot, TypeofMode typeof_mode) { | 237 const Handle<String> name, int feedback_slot, TypeofMode typeof_mode) { |
| 268 // TODO(rmcilroy): Potentially store typeof information in an | 238 // TODO(rmcilroy): Potentially store typeof information in an |
| 269 // operand rather than having extra bytecodes. | 239 // operand rather than having extra bytecodes. |
| 270 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode); | 240 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode); |
| 271 size_t name_index = GetConstantPoolEntry(name); | 241 size_t name_index = GetConstantPoolEntry(name); |
| 272 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 242 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); |
| 273 Bytecodes::SizeForUnsignedOperand(name_index), | |
| 274 Bytecodes::SizeForUnsignedOperand(feedback_slot)); | |
| 275 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index), | |
| 276 UnsignedOperand(feedback_slot)); | |
| 277 return *this; | 243 return *this; |
| 278 } | 244 } |
| 279 | 245 |
| 280 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( | 246 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( |
| 281 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { | 247 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { |
| 282 Bytecode bytecode = BytecodeForStoreGlobal(language_mode); | 248 Bytecode bytecode = BytecodeForStoreGlobal(language_mode); |
| 283 size_t name_index = GetConstantPoolEntry(name); | 249 size_t name_index = GetConstantPoolEntry(name); |
| 284 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 250 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); |
| 285 Bytecodes::SizeForUnsignedOperand(name_index), | |
| 286 Bytecodes::SizeForUnsignedOperand(feedback_slot)); | |
| 287 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index), | |
| 288 UnsignedOperand(feedback_slot)); | |
| 289 return *this; | 251 return *this; |
| 290 } | 252 } |
| 291 | 253 |
| 292 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, | 254 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, |
| 293 int slot_index) { | 255 int slot_index) { |
| 294 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 256 Output(Bytecode::kLdaContextSlot, RegisterOperand(context), |
| 295 context.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(slot_index)); | 257 UnsignedOperand(slot_index)); |
| 296 OutputScaled(Bytecode::kLdaContextSlot, operand_scale, | |
| 297 RegisterOperand(context), UnsignedOperand(slot_index)); | |
| 298 return *this; | 258 return *this; |
| 299 } | 259 } |
| 300 | 260 |
| 301 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, | 261 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, |
| 302 int slot_index) { | 262 int slot_index) { |
| 303 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 263 Output(Bytecode::kStaContextSlot, RegisterOperand(context), |
| 304 context.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(slot_index)); | 264 UnsignedOperand(slot_index)); |
| 305 OutputScaled(Bytecode::kStaContextSlot, operand_scale, | |
| 306 RegisterOperand(context), UnsignedOperand(slot_index)); | |
| 307 return *this; | 265 return *this; |
| 308 } | 266 } |
| 309 | 267 |
| 310 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( | 268 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( |
| 311 const Handle<String> name, TypeofMode typeof_mode) { | 269 const Handle<String> name, TypeofMode typeof_mode) { |
| 312 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) | 270 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) |
| 313 ? Bytecode::kLdaLookupSlotInsideTypeof | 271 ? Bytecode::kLdaLookupSlotInsideTypeof |
| 314 : Bytecode::kLdaLookupSlot; | 272 : Bytecode::kLdaLookupSlot; |
| 315 size_t name_index = GetConstantPoolEntry(name); | 273 size_t name_index = GetConstantPoolEntry(name); |
| 316 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 274 Output(bytecode, UnsignedOperand(name_index)); |
| 317 Bytecodes::SizeForUnsignedOperand(name_index)); | |
| 318 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index)); | |
| 319 return *this; | 275 return *this; |
| 320 } | 276 } |
| 321 | 277 |
| 322 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( | 278 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( |
| 323 const Handle<String> name, LanguageMode language_mode) { | 279 const Handle<String> name, LanguageMode language_mode) { |
| 324 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode); | 280 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode); |
| 325 size_t name_index = GetConstantPoolEntry(name); | 281 size_t name_index = GetConstantPoolEntry(name); |
| 326 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 282 Output(bytecode, UnsignedOperand(name_index)); |
| 327 Bytecodes::SizeForUnsignedOperand(name_index)); | |
| 328 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index)); | |
| 329 return *this; | 283 return *this; |
| 330 } | 284 } |
| 331 | 285 |
| 332 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( | 286 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( |
| 333 Register object, const Handle<Name> name, int feedback_slot) { | 287 Register object, const Handle<Name> name, int feedback_slot) { |
| 334 size_t name_index = GetConstantPoolEntry(name); | 288 size_t name_index = GetConstantPoolEntry(name); |
| 335 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 289 Output(Bytecode::kLdaNamedProperty, RegisterOperand(object), |
| 336 object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(name_index), | 290 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); |
| 337 Bytecodes::SizeForUnsignedOperand(feedback_slot)); | |
| 338 OutputScaled(Bytecode::kLdaNamedProperty, operand_scale, | |
| 339 RegisterOperand(object), UnsignedOperand(name_index), | |
| 340 UnsignedOperand(feedback_slot)); | |
| 341 return *this; | 291 return *this; |
| 342 } | 292 } |
| 343 | 293 |
| 344 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( | 294 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( |
| 345 Register object, int feedback_slot) { | 295 Register object, int feedback_slot) { |
| 346 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 296 Output(Bytecode::kLdaKeyedProperty, RegisterOperand(object), |
| 347 object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(feedback_slot)); | 297 UnsignedOperand(feedback_slot)); |
| 348 OutputScaled(Bytecode::kLdaKeyedProperty, operand_scale, | |
| 349 RegisterOperand(object), UnsignedOperand(feedback_slot)); | |
| 350 return *this; | 298 return *this; |
| 351 } | 299 } |
| 352 | 300 |
| 353 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( | 301 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( |
| 354 Register object, const Handle<Name> name, int feedback_slot, | 302 Register object, const Handle<Name> name, int feedback_slot, |
| 355 LanguageMode language_mode) { | 303 LanguageMode language_mode) { |
| 356 Bytecode bytecode = BytecodeForStoreNamedProperty(language_mode); | 304 Bytecode bytecode = BytecodeForStoreNamedProperty(language_mode); |
| 357 size_t name_index = GetConstantPoolEntry(name); | 305 size_t name_index = GetConstantPoolEntry(name); |
| 358 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 306 Output(bytecode, RegisterOperand(object), UnsignedOperand(name_index), |
| 359 object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(name_index), | 307 UnsignedOperand(feedback_slot)); |
| 360 Bytecodes::SizeForUnsignedOperand(feedback_slot)); | |
| 361 OutputScaled(bytecode, operand_scale, RegisterOperand(object), | |
| 362 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | |
| 363 return *this; | 308 return *this; |
| 364 } | 309 } |
| 365 | 310 |
| 366 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( | 311 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( |
| 367 Register object, Register key, int feedback_slot, | 312 Register object, Register key, int feedback_slot, |
| 368 LanguageMode language_mode) { | 313 LanguageMode language_mode) { |
| 369 Bytecode bytecode = BytecodeForStoreKeyedProperty(language_mode); | 314 Bytecode bytecode = BytecodeForStoreKeyedProperty(language_mode); |
| 370 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 315 Output(bytecode, RegisterOperand(object), RegisterOperand(key), |
| 371 object.SizeOfOperand(), key.SizeOfOperand(), | 316 UnsignedOperand(feedback_slot)); |
| 372 Bytecodes::SizeForUnsignedOperand(feedback_slot)); | |
| 373 OutputScaled(bytecode, operand_scale, RegisterOperand(object), | |
| 374 RegisterOperand(key), UnsignedOperand(feedback_slot)); | |
| 375 return *this; | 317 return *this; |
| 376 } | 318 } |
| 377 | 319 |
| 378 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure( | 320 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure( |
| 379 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) { | 321 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) { |
| 380 size_t entry = GetConstantPoolEntry(shared_info); | 322 size_t entry = GetConstantPoolEntry(shared_info); |
| 381 OperandScale operand_scale = | 323 Output(Bytecode::kCreateClosure, UnsignedOperand(entry), |
| 382 Bytecodes::OperandSizesToScale(Bytecodes::SizeForUnsignedOperand(entry)); | 324 UnsignedOperand(static_cast<size_t>(tenured))); |
| 383 OutputScaled(Bytecode::kCreateClosure, operand_scale, UnsignedOperand(entry), | |
| 384 UnsignedOperand(static_cast<size_t>(tenured))); | |
| 385 return *this; | 325 return *this; |
| 386 } | 326 } |
| 387 | 327 |
| 388 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( | 328 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( |
| 389 CreateArgumentsType type) { | 329 CreateArgumentsType type) { |
| 390 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather | 330 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather |
| 391 // than having two different bytecodes once we have better support for | 331 // than having two different bytecodes once we have better support for |
| 392 // branches in the InterpreterAssembler. | 332 // branches in the InterpreterAssembler. |
| 393 Bytecode bytecode = BytecodeForCreateArguments(type); | 333 Bytecode bytecode = BytecodeForCreateArguments(type); |
| 394 Output(bytecode); | 334 Output(bytecode); |
| 395 return *this; | 335 return *this; |
| 396 } | 336 } |
| 397 | 337 |
| 398 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( | 338 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( |
| 399 Handle<String> pattern, int literal_index, int flags) { | 339 Handle<String> pattern, int literal_index, int flags) { |
| 400 size_t pattern_entry = GetConstantPoolEntry(pattern); | 340 size_t pattern_entry = GetConstantPoolEntry(pattern); |
| 401 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 341 Output(Bytecode::kCreateRegExpLiteral, UnsignedOperand(pattern_entry), |
| 402 Bytecodes::SizeForUnsignedOperand(pattern_entry), | 342 UnsignedOperand(literal_index), UnsignedOperand(flags)); |
| 403 Bytecodes::SizeForUnsignedOperand(literal_index), | |
| 404 Bytecodes::SizeForUnsignedOperand(flags)); | |
| 405 OutputScaled(Bytecode::kCreateRegExpLiteral, operand_scale, | |
| 406 UnsignedOperand(pattern_entry), UnsignedOperand(literal_index), | |
| 407 UnsignedOperand(flags)); | |
| 408 return *this; | 343 return *this; |
| 409 } | 344 } |
| 410 | 345 |
| 411 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral( | 346 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral( |
| 412 Handle<FixedArray> constant_elements, int literal_index, int flags) { | 347 Handle<FixedArray> constant_elements, int literal_index, int flags) { |
| 413 size_t constant_elements_entry = GetConstantPoolEntry(constant_elements); | 348 size_t constant_elements_entry = GetConstantPoolEntry(constant_elements); |
| 414 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 349 Output(Bytecode::kCreateArrayLiteral, |
| 415 Bytecodes::SizeForUnsignedOperand(constant_elements_entry), | 350 UnsignedOperand(constant_elements_entry), |
| 416 Bytecodes::SizeForUnsignedOperand(literal_index), | 351 UnsignedOperand(literal_index), UnsignedOperand(flags)); |
| 417 Bytecodes::SizeForUnsignedOperand(flags)); | |
| 418 OutputScaled(Bytecode::kCreateArrayLiteral, operand_scale, | |
| 419 UnsignedOperand(constant_elements_entry), | |
| 420 UnsignedOperand(literal_index), UnsignedOperand(flags)); | |
| 421 return *this; | 352 return *this; |
| 422 } | 353 } |
| 423 | 354 |
| 424 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral( | 355 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral( |
| 425 Handle<FixedArray> constant_properties, int literal_index, int flags) { | 356 Handle<FixedArray> constant_properties, int literal_index, int flags) { |
| 426 size_t constant_properties_entry = GetConstantPoolEntry(constant_properties); | 357 size_t constant_properties_entry = GetConstantPoolEntry(constant_properties); |
| 427 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 358 Output(Bytecode::kCreateObjectLiteral, |
| 428 Bytecodes::SizeForUnsignedOperand(constant_properties_entry), | 359 UnsignedOperand(constant_properties_entry), |
| 429 Bytecodes::SizeForUnsignedOperand(literal_index), | 360 UnsignedOperand(literal_index), UnsignedOperand(flags)); |
| 430 Bytecodes::SizeForUnsignedOperand(flags)); | |
| 431 OutputScaled(Bytecode::kCreateObjectLiteral, operand_scale, | |
| 432 UnsignedOperand(constant_properties_entry), | |
| 433 UnsignedOperand(literal_index), UnsignedOperand(flags)); | |
| 434 return *this; | 361 return *this; |
| 435 } | 362 } |
| 436 | 363 |
| 437 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) { | 364 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) { |
| 438 OperandScale operand_scale = | 365 Output(Bytecode::kPushContext, RegisterOperand(context)); |
| 439 Bytecodes::OperandSizesToScale(context.SizeOfOperand()); | |
| 440 OutputScaled(Bytecode::kPushContext, operand_scale, RegisterOperand(context)); | |
| 441 return *this; | 366 return *this; |
| 442 } | 367 } |
| 443 | 368 |
| 444 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { | 369 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { |
| 445 OperandScale operand_scale = | 370 Output(Bytecode::kPopContext, RegisterOperand(context)); |
| 446 Bytecodes::OperandSizesToScale(context.SizeOfOperand()); | |
| 447 OutputScaled(Bytecode::kPopContext, operand_scale, RegisterOperand(context)); | |
| 448 return *this; | 371 return *this; |
| 449 } | 372 } |
| 450 | 373 |
| 451 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() { | 374 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() { |
| 452 Output(Bytecode::kToObject); | 375 Output(Bytecode::kToObject); |
| 453 return *this; | 376 return *this; |
| 454 } | 377 } |
| 455 | 378 |
| 456 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() { | 379 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() { |
| 457 Output(Bytecode::kToName); | 380 Output(Bytecode::kToName); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 471 | 394 |
| 472 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, | 395 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, |
| 473 BytecodeLabel* label) { | 396 BytecodeLabel* label) { |
| 474 pipeline_->BindLabel(target, label); | 397 pipeline_->BindLabel(target, label); |
| 475 LeaveBasicBlock(); | 398 LeaveBasicBlock(); |
| 476 return *this; | 399 return *this; |
| 477 } | 400 } |
| 478 | 401 |
| 479 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, | 402 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, |
| 480 BytecodeLabel* label) { | 403 BytecodeLabel* label) { |
| 481 BytecodeNode node(jump_bytecode, 0, OperandScale::kSingle); | 404 BytecodeNode node(jump_bytecode, 0); |
| 482 AttachSourceInfo(&node); | 405 AttachSourceInfo(&node); |
| 483 pipeline_->WriteJump(&node, label); | 406 pipeline_->WriteJump(&node, label); |
| 484 LeaveBasicBlock(); | 407 LeaveBasicBlock(); |
| 485 return *this; | 408 return *this; |
| 486 } | 409 } |
| 487 | 410 |
| 488 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { | 411 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { |
| 489 return OutputJump(Bytecode::kJump, label); | 412 return OutputJump(Bytecode::kJump, label); |
| 490 } | 413 } |
| 491 | 414 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 return *this; | 464 return *this; |
| 542 } | 465 } |
| 543 | 466 |
| 544 BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() { | 467 BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() { |
| 545 Output(Bytecode::kDebugger); | 468 Output(Bytecode::kDebugger); |
| 546 return *this; | 469 return *this; |
| 547 } | 470 } |
| 548 | 471 |
| 549 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare( | 472 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare( |
| 550 Register cache_info_triple) { | 473 Register cache_info_triple) { |
| 551 OperandScale operand_scale = | 474 Output(Bytecode::kForInPrepare, RegisterOperand(cache_info_triple)); |
| 552 Bytecodes::OperandSizesToScale(cache_info_triple.SizeOfOperand()); | |
| 553 OutputScaled(Bytecode::kForInPrepare, operand_scale, | |
| 554 RegisterOperand(cache_info_triple)); | |
| 555 return *this; | 475 return *this; |
| 556 } | 476 } |
| 557 | 477 |
| 558 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index, | 478 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index, |
| 559 Register cache_length) { | 479 Register cache_length) { |
| 560 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 480 Output(Bytecode::kForInDone, RegisterOperand(index), |
| 561 index.SizeOfOperand(), cache_length.SizeOfOperand()); | 481 RegisterOperand(cache_length)); |
| 562 OutputScaled(Bytecode::kForInDone, operand_scale, RegisterOperand(index), | |
| 563 RegisterOperand(cache_length)); | |
| 564 return *this; | 482 return *this; |
| 565 } | 483 } |
| 566 | 484 |
| 567 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext( | 485 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext( |
| 568 Register receiver, Register index, Register cache_type_array_pair, | 486 Register receiver, Register index, Register cache_type_array_pair, |
| 569 int feedback_slot) { | 487 int feedback_slot) { |
| 570 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 488 Output(Bytecode::kForInNext, RegisterOperand(receiver), |
| 571 receiver.SizeOfOperand(), index.SizeOfOperand(), | 489 RegisterOperand(index), RegisterOperand(cache_type_array_pair), |
| 572 cache_type_array_pair.SizeOfOperand(), | 490 UnsignedOperand(feedback_slot)); |
| 573 Bytecodes::SizeForUnsignedOperand(feedback_slot)); | |
| 574 OutputScaled(Bytecode::kForInNext, operand_scale, RegisterOperand(receiver), | |
| 575 RegisterOperand(index), RegisterOperand(cache_type_array_pair), | |
| 576 UnsignedOperand(feedback_slot)); | |
| 577 return *this; | 491 return *this; |
| 578 } | 492 } |
| 579 | 493 |
| 580 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) { | 494 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) { |
| 581 OperandScale operand_scale = | 495 Output(Bytecode::kForInStep, RegisterOperand(index)); |
| 582 Bytecodes::OperandSizesToScale(index.SizeOfOperand()); | |
| 583 OutputScaled(Bytecode::kForInStep, operand_scale, RegisterOperand(index)); | |
| 584 return *this; | 496 return *this; |
| 585 } | 497 } |
| 586 | 498 |
| 587 BytecodeArrayBuilder& BytecodeArrayBuilder::SuspendGenerator( | 499 BytecodeArrayBuilder& BytecodeArrayBuilder::SuspendGenerator( |
| 588 Register generator) { | 500 Register generator) { |
| 589 OperandScale operand_scale = | 501 Output(Bytecode::kSuspendGenerator, RegisterOperand(generator)); |
| 590 Bytecodes::OperandSizesToScale(generator.SizeOfOperand()); | |
| 591 OutputScaled(Bytecode::kSuspendGenerator, operand_scale, | |
| 592 RegisterOperand(generator)); | |
| 593 return *this; | 502 return *this; |
| 594 } | 503 } |
| 595 | 504 |
| 596 BytecodeArrayBuilder& BytecodeArrayBuilder::ResumeGenerator( | 505 BytecodeArrayBuilder& BytecodeArrayBuilder::ResumeGenerator( |
| 597 Register generator) { | 506 Register generator) { |
| 598 OperandScale operand_scale = | 507 Output(Bytecode::kResumeGenerator, RegisterOperand(generator)); |
| 599 Bytecodes::OperandSizesToScale(generator.SizeOfOperand()); | |
| 600 OutputScaled(Bytecode::kResumeGenerator, operand_scale, | |
| 601 RegisterOperand(generator)); | |
| 602 return *this; | 508 return *this; |
| 603 } | 509 } |
| 604 | 510 |
| 605 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id, | 511 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id, |
| 606 bool will_catch) { | 512 bool will_catch) { |
| 607 BytecodeLabel handler; | 513 BytecodeLabel handler; |
| 608 Bind(&handler); | 514 Bind(&handler); |
| 609 handler_table_builder()->SetHandlerTarget(handler_id, handler.offset()); | 515 handler_table_builder()->SetHandlerTarget(handler_id, handler.offset()); |
| 610 handler_table_builder()->SetPrediction(handler_id, will_catch); | 516 handler_table_builder()->SetPrediction(handler_id, will_catch); |
| 611 return *this; | 517 return *this; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 635 } | 541 } |
| 636 DCHECK(return_seen_in_block_); | 542 DCHECK(return_seen_in_block_); |
| 637 } | 543 } |
| 638 | 544 |
| 639 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, | 545 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, |
| 640 Register receiver_args, | 546 Register receiver_args, |
| 641 size_t receiver_args_count, | 547 size_t receiver_args_count, |
| 642 int feedback_slot, | 548 int feedback_slot, |
| 643 TailCallMode tail_call_mode) { | 549 TailCallMode tail_call_mode) { |
| 644 Bytecode bytecode = BytecodeForCall(tail_call_mode); | 550 Bytecode bytecode = BytecodeForCall(tail_call_mode); |
| 645 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 551 Output(bytecode, RegisterOperand(callable), RegisterOperand(receiver_args), |
| 646 callable.SizeOfOperand(), receiver_args.SizeOfOperand(), | 552 UnsignedOperand(receiver_args_count), UnsignedOperand(feedback_slot)); |
| 647 Bytecodes::SizeForUnsignedOperand(receiver_args_count), | |
| 648 Bytecodes::SizeForUnsignedOperand(feedback_slot)); | |
| 649 OutputScaled(bytecode, operand_scale, RegisterOperand(callable), | |
| 650 RegisterOperand(receiver_args), | |
| 651 UnsignedOperand(receiver_args_count), | |
| 652 UnsignedOperand(feedback_slot)); | |
| 653 return *this; | 553 return *this; |
| 654 } | 554 } |
| 655 | 555 |
| 656 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, | 556 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, |
| 657 Register first_arg, | 557 Register first_arg, |
| 658 size_t arg_count) { | 558 size_t arg_count) { |
| 659 if (!first_arg.is_valid()) { | 559 if (!first_arg.is_valid()) { |
| 660 DCHECK_EQ(0u, arg_count); | 560 DCHECK_EQ(0u, arg_count); |
| 661 first_arg = Register(0); | 561 first_arg = Register(0); |
| 662 } | 562 } |
| 663 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 563 Output(Bytecode::kNew, RegisterOperand(constructor), |
| 664 constructor.SizeOfOperand(), first_arg.SizeOfOperand(), | 564 RegisterOperand(first_arg), UnsignedOperand(arg_count)); |
| 665 Bytecodes::SizeForUnsignedOperand(arg_count)); | |
| 666 OutputScaled(Bytecode::kNew, operand_scale, RegisterOperand(constructor), | |
| 667 RegisterOperand(first_arg), UnsignedOperand(arg_count)); | |
| 668 return *this; | 565 return *this; |
| 669 } | 566 } |
| 670 | 567 |
| 671 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( | 568 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( |
| 672 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { | 569 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { |
| 673 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); | 570 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); |
| 674 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort); | 571 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort); |
| 675 if (!first_arg.is_valid()) { | 572 if (!first_arg.is_valid()) { |
| 676 DCHECK_EQ(0u, arg_count); | 573 DCHECK_EQ(0u, arg_count); |
| 677 first_arg = Register(0); | 574 first_arg = Register(0); |
| 678 } | 575 } |
| 679 Bytecode bytecode = IntrinsicsHelper::IsSupported(function_id) | 576 Bytecode bytecode = IntrinsicsHelper::IsSupported(function_id) |
| 680 ? Bytecode::kInvokeIntrinsic | 577 ? Bytecode::kInvokeIntrinsic |
| 681 : Bytecode::kCallRuntime; | 578 : Bytecode::kCallRuntime; |
| 682 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 579 Output(bytecode, static_cast<uint16_t>(function_id), |
| 683 first_arg.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(arg_count)); | 580 RegisterOperand(first_arg), UnsignedOperand(arg_count)); |
| 684 OutputScaled(bytecode, operand_scale, static_cast<uint16_t>(function_id), | |
| 685 RegisterOperand(first_arg), UnsignedOperand(arg_count)); | |
| 686 return *this; | 581 return *this; |
| 687 } | 582 } |
| 688 | 583 |
| 689 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( | 584 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( |
| 690 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, | 585 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, |
| 691 Register first_return) { | 586 Register first_return) { |
| 692 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); | 587 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); |
| 693 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort); | 588 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort); |
| 694 if (!first_arg.is_valid()) { | 589 if (!first_arg.is_valid()) { |
| 695 DCHECK_EQ(0u, arg_count); | 590 DCHECK_EQ(0u, arg_count); |
| 696 first_arg = Register(0); | 591 first_arg = Register(0); |
| 697 } | 592 } |
| 698 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 593 Output(Bytecode::kCallRuntimeForPair, static_cast<uint16_t>(function_id), |
| 699 first_arg.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(arg_count), | 594 RegisterOperand(first_arg), UnsignedOperand(arg_count), |
| 700 first_return.SizeOfOperand()); | 595 RegisterOperand(first_return)); |
| 701 OutputScaled(Bytecode::kCallRuntimeForPair, operand_scale, | |
| 702 static_cast<uint16_t>(function_id), RegisterOperand(first_arg), | |
| 703 UnsignedOperand(arg_count), RegisterOperand(first_return)); | |
| 704 return *this; | 596 return *this; |
| 705 } | 597 } |
| 706 | 598 |
| 707 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( | 599 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( |
| 708 int context_index, Register receiver_args, size_t receiver_args_count) { | 600 int context_index, Register receiver_args, size_t receiver_args_count) { |
| 709 OperandScale operand_scale = Bytecodes::OperandSizesToScale( | 601 Output(Bytecode::kCallJSRuntime, UnsignedOperand(context_index), |
| 710 Bytecodes::SizeForUnsignedOperand(context_index), | 602 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count)); |
| 711 receiver_args.SizeOfOperand(), | |
| 712 Bytecodes::SizeForUnsignedOperand(receiver_args_count)); | |
| 713 OutputScaled(Bytecode::kCallJSRuntime, operand_scale, | |
| 714 UnsignedOperand(context_index), RegisterOperand(receiver_args), | |
| 715 UnsignedOperand(receiver_args_count)); | |
| 716 return *this; | 603 return *this; |
| 717 } | 604 } |
| 718 | 605 |
| 719 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, | 606 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, |
| 720 LanguageMode language_mode) { | 607 LanguageMode language_mode) { |
| 721 OperandScale operand_scale = | 608 Output(BytecodeForDelete(language_mode), RegisterOperand(object)); |
| 722 Bytecodes::OperandSizesToScale(object.SizeOfOperand()); | |
| 723 OutputScaled(BytecodeForDelete(language_mode), operand_scale, | |
| 724 RegisterOperand(object)); | |
| 725 return *this; | 609 return *this; |
| 726 } | 610 } |
| 727 | 611 |
| 728 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { | 612 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { |
| 729 return constant_array_builder()->Insert(object); | 613 return constant_array_builder()->Insert(object); |
| 730 } | 614 } |
| 731 | 615 |
| 732 void BytecodeArrayBuilder::SetReturnPosition() { | 616 void BytecodeArrayBuilder::SetReturnPosition() { |
| 733 if (return_position_ == RelocInfo::kNoPosition) return; | 617 if (return_position_ == RelocInfo::kNoPosition) return; |
| 734 latest_source_info_.Update({return_position_, true}); | 618 latest_source_info_.Update({return_position_, true}); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 755 | 639 |
| 756 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) { | 640 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) { |
| 757 if (expr->position() == RelocInfo::kNoPosition) return; | 641 if (expr->position() == RelocInfo::kNoPosition) return; |
| 758 latest_source_info_.Update({expr->position(), true}); | 642 latest_source_info_.Update({expr->position(), true}); |
| 759 } | 643 } |
| 760 | 644 |
| 761 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { | 645 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { |
| 762 return temporary_register_allocator()->RegisterIsLive(reg); | 646 return temporary_register_allocator()->RegisterIsLive(reg); |
| 763 } | 647 } |
| 764 | 648 |
| 765 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, | 649 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const { |
| 766 OperandScale operand_scale, | |
| 767 int operand_index, | |
| 768 uint32_t operand_value) const { | |
| 769 OperandSize operand_size = | |
| 770 Bytecodes::GetOperandSize(bytecode, operand_index, operand_scale); | |
| 771 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); | |
| 772 switch (operand_type) { | |
| 773 case OperandType::kNone: | |
| 774 return false; | |
| 775 case OperandType::kRegCount: { | |
| 776 if (operand_index > 0) { | |
| 777 OperandType previous_operand_type = | |
| 778 Bytecodes::GetOperandType(bytecode, operand_index - 1); | |
| 779 if (previous_operand_type != OperandType::kMaybeReg && | |
| 780 previous_operand_type != OperandType::kReg) { | |
| 781 return false; | |
| 782 } | |
| 783 } | |
| 784 } // Fall-through | |
| 785 case OperandType::kFlag8: | |
| 786 case OperandType::kIdx: | |
| 787 case OperandType::kRuntimeId: | |
| 788 case OperandType::kImm: { | |
| 789 size_t unsigned_value = static_cast<size_t>(operand_value); | |
| 790 return Bytecodes::SizeForUnsignedOperand(unsigned_value) <= operand_size; | |
| 791 } | |
| 792 case OperandType::kMaybeReg: | |
| 793 if (RegisterFromOperand(operand_value) == Register(0)) { | |
| 794 return true; | |
| 795 } | |
| 796 // Fall-through to kReg case. | |
| 797 case OperandType::kReg: | |
| 798 case OperandType::kRegOut: { | |
| 799 Register reg = RegisterFromOperand(operand_value); | |
| 800 return RegisterIsValid(reg, operand_size); | |
| 801 } | |
| 802 case OperandType::kRegOutPair: | |
| 803 case OperandType::kRegPair: { | |
| 804 Register reg0 = RegisterFromOperand(operand_value); | |
| 805 Register reg1 = Register(reg0.index() + 1); | |
| 806 // The size of reg1 is immaterial. | |
| 807 return RegisterIsValid(reg0, operand_size) && | |
| 808 RegisterIsValid(reg1, OperandSize::kQuad); | |
| 809 } | |
| 810 case OperandType::kRegOutTriple: { | |
| 811 Register reg0 = RegisterFromOperand(operand_value); | |
| 812 Register reg1 = Register(reg0.index() + 1); | |
| 813 Register reg2 = Register(reg0.index() + 2); | |
| 814 // The size of reg1 and reg2 is immaterial. | |
| 815 return RegisterIsValid(reg0, operand_size) && | |
| 816 RegisterIsValid(reg1, OperandSize::kQuad) && | |
| 817 RegisterIsValid(reg2, OperandSize::kQuad); | |
| 818 } | |
| 819 } | |
| 820 UNREACHABLE(); | |
| 821 return false; | |
| 822 } | |
| 823 | |
| 824 bool BytecodeArrayBuilder::RegisterIsValid(Register reg, | |
| 825 OperandSize reg_size) const { | |
| 826 if (!reg.is_valid()) { | 650 if (!reg.is_valid()) { |
| 827 return false; | 651 return false; |
| 828 } | 652 } |
| 829 | 653 |
| 830 if (reg.SizeOfOperand() > reg_size) { | |
| 831 return false; | |
| 832 } | |
| 833 | |
| 834 if (reg.is_current_context() || reg.is_function_closure() || | 654 if (reg.is_current_context() || reg.is_function_closure() || |
| 835 reg.is_new_target()) { | 655 reg.is_new_target()) { |
| 836 return true; | 656 return true; |
| 837 } else if (reg.is_parameter()) { | 657 } else if (reg.is_parameter()) { |
| 838 int parameter_index = reg.ToParameterIndex(parameter_count()); | 658 int parameter_index = reg.ToParameterIndex(parameter_count()); |
| 839 return parameter_index >= 0 && parameter_index < parameter_count(); | 659 return parameter_index >= 0 && parameter_index < parameter_count(); |
| 840 } else if (reg.index() < fixed_register_count()) { | 660 } else if (reg.index() < fixed_register_count()) { |
| 841 return true; | 661 return true; |
| 842 } else { | 662 } else { |
| 843 return TemporaryRegisterIsLive(reg); | 663 return TemporaryRegisterIsLive(reg); |
| 844 } | 664 } |
| 845 } | 665 } |
| 846 | 666 |
| 667 bool BytecodeArrayBuilder::OperandsAreValid( |
| 668 Bytecode bytecode, int operand_count, uint32_t operand0, uint32_t operand1, |
| 669 uint32_t operand2, uint32_t operand3) const { |
| 670 if (Bytecodes::NumberOfOperands(bytecode) != operand_count) { |
| 671 return false; |
| 672 } |
| 673 |
| 674 uint32_t operands[] = {operand0, operand1, operand2, operand3}; |
| 675 const OperandType* operand_types = Bytecodes::GetOperandTypes(bytecode); |
| 676 for (int i = 0; i < operand_count; ++i) { |
| 677 switch (operand_types[i]) { |
| 678 case OperandType::kNone: |
| 679 return false; |
| 680 case OperandType::kRegCount: { |
| 681 CHECK_NE(i, 0); |
| 682 CHECK(operand_types[i - 1] == OperandType::kMaybeReg || |
| 683 operand_types[i - 1] == OperandType::kReg); |
| 684 if (operands[i] > 0) { |
| 685 Register start = Register::FromOperand(operands[i - 1]); |
| 686 Register end(start.index() + static_cast<int>(operands[i]) - 1); |
| 687 if (!RegisterIsValid(start) || !RegisterIsValid(end) || start > end) { |
| 688 return false; |
| 689 } |
| 690 } |
| 691 break; |
| 692 } |
| 693 case OperandType::kFlag8: |
| 694 if (Bytecodes::SizeForUnsignedOperand(operands[i]) > |
| 695 OperandSize::kByte) { |
| 696 return false; |
| 697 } |
| 698 break; |
| 699 case OperandType::kRuntimeId: |
| 700 if (Bytecodes::SizeForUnsignedOperand(operands[i]) > |
| 701 OperandSize::kShort) { |
| 702 return false; |
| 703 } |
| 704 break; |
| 705 case OperandType::kIdx: |
| 706 // TODO(oth): Consider splitting OperandType::kIdx into two |
| 707 // operand types. One which is a constant pool index that can |
| 708 // be checked, and the other is an unsigned value. |
| 709 break; |
| 710 case OperandType::kImm: |
| 711 break; |
| 712 case OperandType::kMaybeReg: |
| 713 if (Register::FromOperand(operands[i]) == Register(0)) { |
| 714 break; |
| 715 } |
| 716 // Fall-through to kReg case. |
| 717 case OperandType::kReg: |
| 718 case OperandType::kRegOut: { |
| 719 Register reg = Register::FromOperand(operands[i]); |
| 720 if (!RegisterIsValid(reg)) { |
| 721 return false; |
| 722 } |
| 723 break; |
| 724 } |
| 725 case OperandType::kRegOutPair: |
| 726 case OperandType::kRegPair: { |
| 727 Register reg0 = Register::FromOperand(operands[i]); |
| 728 Register reg1 = Register(reg0.index() + 1); |
| 729 if (!RegisterIsValid(reg0) || !RegisterIsValid(reg1)) { |
| 730 return false; |
| 731 } |
| 732 break; |
| 733 } |
| 734 case OperandType::kRegOutTriple: { |
| 735 Register reg0 = Register::FromOperand(operands[i]); |
| 736 Register reg1 = Register(reg0.index() + 1); |
| 737 Register reg2 = Register(reg0.index() + 2); |
| 738 if (!RegisterIsValid(reg0) || !RegisterIsValid(reg1) || |
| 739 !RegisterIsValid(reg2)) { |
| 740 return false; |
| 741 } |
| 742 break; |
| 743 } |
| 744 } |
| 745 } |
| 746 |
| 747 return true; |
| 748 } |
| 749 |
| 847 // static | 750 // static |
| 848 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { | 751 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { |
| 849 switch (op) { | 752 switch (op) { |
| 850 case Token::Value::ADD: | 753 case Token::Value::ADD: |
| 851 return Bytecode::kAdd; | 754 return Bytecode::kAdd; |
| 852 case Token::Value::SUB: | 755 case Token::Value::SUB: |
| 853 return Bytecode::kSub; | 756 return Bytecode::kSub; |
| 854 case Token::Value::MUL: | 757 case Token::Value::MUL: |
| 855 return Bytecode::kMul; | 758 return Bytecode::kMul; |
| 856 case Token::Value::DIV: | 759 case Token::Value::DIV: |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 case TailCallMode::kDisallow: | 914 case TailCallMode::kDisallow: |
| 1012 return Bytecode::kCall; | 915 return Bytecode::kCall; |
| 1013 case TailCallMode::kAllow: | 916 case TailCallMode::kAllow: |
| 1014 return Bytecode::kTailCall; | 917 return Bytecode::kTailCall; |
| 1015 default: | 918 default: |
| 1016 UNREACHABLE(); | 919 UNREACHABLE(); |
| 1017 } | 920 } |
| 1018 return Bytecode::kIllegal; | 921 return Bytecode::kIllegal; |
| 1019 } | 922 } |
| 1020 | 923 |
| 1021 uint32_t BytecodeArrayBuilder::RegisterOperand(Register reg) { | |
| 1022 return static_cast<uint32_t>(reg.ToOperand()); | |
| 1023 } | |
| 1024 | |
| 1025 Register BytecodeArrayBuilder::RegisterFromOperand(uint32_t operand) { | |
| 1026 return Register::FromOperand(static_cast<int32_t>(operand)); | |
| 1027 } | |
| 1028 | |
| 1029 uint32_t BytecodeArrayBuilder::SignedOperand(int value, OperandSize size) { | |
| 1030 switch (size) { | |
| 1031 case OperandSize::kByte: | |
| 1032 return static_cast<uint8_t>(value & 0xff); | |
| 1033 case OperandSize::kShort: | |
| 1034 return static_cast<uint16_t>(value & 0xffff); | |
| 1035 case OperandSize::kQuad: | |
| 1036 return static_cast<uint32_t>(value); | |
| 1037 case OperandSize::kNone: | |
| 1038 UNREACHABLE(); | |
| 1039 } | |
| 1040 return 0; | |
| 1041 } | |
| 1042 | |
| 1043 uint32_t BytecodeArrayBuilder::UnsignedOperand(int value) { | |
| 1044 DCHECK_GE(value, 0); | |
| 1045 return static_cast<uint32_t>(value); | |
| 1046 } | |
| 1047 | |
| 1048 uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) { | |
| 1049 DCHECK_LE(value, kMaxUInt32); | |
| 1050 return static_cast<uint32_t>(value); | |
| 1051 } | |
| 1052 | |
| 1053 } // namespace interpreter | 924 } // namespace interpreter |
| 1054 } // namespace internal | 925 } // namespace internal |
| 1055 } // namespace v8 | 926 } // namespace v8 |
| OLD | NEW |