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 #ifndef V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ | 5 #ifndef V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ |
6 #define V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ | 6 #define V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ |
7 | 7 |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/interpreter/bytecode-register-allocator.h" | 9 #include "src/interpreter/bytecode-register-allocator.h" |
10 #include "src/interpreter/bytecodes.h" | 10 #include "src/interpreter/bytecodes.h" |
11 #include "src/interpreter/constant-array-builder.h" | 11 #include "src/interpreter/constant-array-builder.h" |
12 #include "src/interpreter/handler-table-builder.h" | 12 #include "src/interpreter/handler-table-builder.h" |
13 #include "src/interpreter/register-translator.h" | |
14 #include "src/interpreter/source-position-table.h" | 13 #include "src/interpreter/source-position-table.h" |
15 #include "src/zone-containers.h" | 14 #include "src/zone-containers.h" |
16 | 15 |
17 namespace v8 { | 16 namespace v8 { |
18 namespace internal { | 17 namespace internal { |
19 | 18 |
20 class Isolate; | 19 class Isolate; |
21 | 20 |
22 namespace interpreter { | 21 namespace interpreter { |
23 | 22 |
24 class BytecodeLabel; | 23 class BytecodeLabel; |
25 class Register; | 24 class Register; |
26 | 25 |
27 class BytecodeArrayBuilder final : public ZoneObject, private RegisterMover { | 26 class BytecodeArrayBuilder final : public ZoneObject { |
28 public: | 27 public: |
29 BytecodeArrayBuilder(Isolate* isolate, Zone* zone, int parameter_count, | 28 BytecodeArrayBuilder(Isolate* isolate, Zone* zone, int parameter_count, |
30 int context_count, int locals_count, | 29 int context_count, int locals_count, |
31 FunctionLiteral* literal = nullptr); | 30 FunctionLiteral* literal = nullptr); |
32 ~BytecodeArrayBuilder(); | 31 ~BytecodeArrayBuilder(); |
33 | 32 |
34 Handle<BytecodeArray> ToBytecodeArray(); | 33 Handle<BytecodeArray> ToBytecodeArray(); |
35 | 34 |
36 // Get the number of parameters expected by function. | 35 // Get the number of parameters expected by function. |
37 int parameter_count() const { | 36 int parameter_count() const { |
(...skipping 21 matching lines...) Expand all Loading... | |
59 | 58 |
60 // Returns the number of fixed and temporary registers. | 59 // Returns the number of fixed and temporary registers. |
61 int fixed_and_temporary_register_count() const { | 60 int fixed_and_temporary_register_count() const { |
62 return fixed_register_count() + temporary_register_count(); | 61 return fixed_register_count() + temporary_register_count(); |
63 } | 62 } |
64 | 63 |
65 int temporary_register_count() const { | 64 int temporary_register_count() const { |
66 return temporary_register_allocator()->allocation_count(); | 65 return temporary_register_allocator()->allocation_count(); |
67 } | 66 } |
68 | 67 |
69 // Returns the number of registers used for translating wide | |
70 // register operands into byte sized register operands. | |
71 int translation_register_count() const { | |
72 return RegisterTranslator::RegisterCountAdjustment( | |
73 fixed_and_temporary_register_count(), parameter_count()); | |
74 } | |
75 | |
76 Register Parameter(int parameter_index) const; | 68 Register Parameter(int parameter_index) const; |
77 | 69 |
78 // Return true if the register |reg| represents a parameter or a | 70 // Return true if the register |reg| represents a parameter or a |
79 // local. | 71 // local. |
80 bool RegisterIsParameterOrLocal(Register reg) const; | 72 bool RegisterIsParameterOrLocal(Register reg) const; |
81 | 73 |
82 // Returns true if the register |reg| is a live temporary register. | 74 // Returns true if the register |reg| is a live temporary register. |
83 bool TemporaryRegisterIsLive(Register reg) const; | 75 bool TemporaryRegisterIsLive(Register reg) const; |
84 | 76 |
85 // Constant loads to accumulator. | 77 // Constant loads to accumulator. |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
269 Zone* zone() const { return zone_; } | 261 Zone* zone() const { return zone_; } |
270 TemporaryRegisterAllocator* temporary_register_allocator() { | 262 TemporaryRegisterAllocator* temporary_register_allocator() { |
271 return &temporary_allocator_; | 263 return &temporary_allocator_; |
272 } | 264 } |
273 const TemporaryRegisterAllocator* temporary_register_allocator() const { | 265 const TemporaryRegisterAllocator* temporary_register_allocator() const { |
274 return &temporary_allocator_; | 266 return &temporary_allocator_; |
275 } | 267 } |
276 | 268 |
277 void EnsureReturn(); | 269 void EnsureReturn(); |
278 | 270 |
271 static OperandScale OperandSizesToScale( | |
272 OperandSize size0, OperandSize size1 = OperandSize::kByte, | |
273 OperandSize size2 = OperandSize::kByte, | |
274 OperandSize size3 = OperandSize::kByte); | |
275 static OperandSize SizeForRegisterOperand(Register reg); | |
rmcilroy
2016/03/17 17:30:49
nit - newline above
oth
2016/03/21 09:16:53
Done.
| |
276 static OperandSize SizeForSignedOperand(int value); | |
277 static OperandSize SizeForUnsignedOperand(int value); | |
278 static OperandSize SizeForUnsignedOperand(size_t value); | |
279 static uint32_t RegisterOperand(Register reg); | |
rmcilroy
2016/03/17 17:30:49
nit - newline above. Also, can these all be privat
oth
2016/03/21 09:16:53
Done newline. Unittests check these work. The size
| |
280 static Register RegisterFromOperand(uint32_t operand); | |
281 static uint32_t SignedOperand(int value, OperandSize size); | |
282 static uint32_t UnsignedOperand(int value); | |
283 static uint32_t UnsignedOperand(size_t value); | |
284 | |
279 private: | 285 private: |
280 class PreviousBytecodeHelper; | 286 class PreviousBytecodeHelper; |
281 friend class BytecodeRegisterAllocator; | 287 friend class BytecodeRegisterAllocator; |
282 | 288 |
283 static Bytecode BytecodeForBinaryOperation(Token::Value op); | 289 static Bytecode BytecodeForBinaryOperation(Token::Value op); |
284 static Bytecode BytecodeForCountOperation(Token::Value op); | 290 static Bytecode BytecodeForCountOperation(Token::Value op); |
285 static Bytecode BytecodeForCompareOperation(Token::Value op); | 291 static Bytecode BytecodeForCompareOperation(Token::Value op); |
286 static Bytecode BytecodeForWideOperands(Bytecode bytecode); | |
287 static Bytecode BytecodeForStoreIC(LanguageMode language_mode); | 292 static Bytecode BytecodeForStoreIC(LanguageMode language_mode); |
288 static Bytecode BytecodeForKeyedStoreIC(LanguageMode language_mode); | 293 static Bytecode BytecodeForKeyedStoreIC(LanguageMode language_mode); |
289 static Bytecode BytecodeForLoadGlobal(TypeofMode typeof_mode); | 294 static Bytecode BytecodeForLoadGlobal(TypeofMode typeof_mode); |
290 static Bytecode BytecodeForStoreGlobal(LanguageMode language_mode); | 295 static Bytecode BytecodeForStoreGlobal(LanguageMode language_mode); |
291 static Bytecode BytecodeForStoreLookupSlot(LanguageMode language_mode); | 296 static Bytecode BytecodeForStoreLookupSlot(LanguageMode language_mode); |
292 static Bytecode BytecodeForCreateArguments(CreateArgumentsType type); | 297 static Bytecode BytecodeForCreateArguments(CreateArgumentsType type); |
293 static Bytecode BytecodeForDelete(LanguageMode language_mode); | 298 static Bytecode BytecodeForDelete(LanguageMode language_mode); |
294 static Bytecode BytecodeForCall(TailCallMode tail_call_mode); | 299 static Bytecode BytecodeForCall(TailCallMode tail_call_mode); |
295 | 300 |
296 static bool FitsInIdx8Operand(int value); | |
297 static bool FitsInIdx8Operand(size_t value); | |
298 static bool FitsInImm8Operand(int value); | |
299 static bool FitsInIdx16Operand(int value); | |
300 static bool FitsInIdx16Operand(size_t value); | |
301 static bool FitsInReg8Operand(Register value); | |
302 static bool FitsInReg8OperandUntranslated(Register value); | |
303 static bool FitsInReg16Operand(Register value); | |
304 static bool FitsInReg16OperandUntranslated(Register value); | |
305 | |
306 // RegisterMover interface. | |
307 void MoveRegisterUntranslated(Register from, Register to) override; | |
308 | |
309 static Bytecode GetJumpWithConstantOperand(Bytecode jump_smi8_operand); | 301 static Bytecode GetJumpWithConstantOperand(Bytecode jump_smi8_operand); |
310 static Bytecode GetJumpWithConstantWideOperand(Bytecode jump_smi8_operand); | |
311 static Bytecode GetJumpWithToBoolean(Bytecode jump_smi8_operand); | 302 static Bytecode GetJumpWithToBoolean(Bytecode jump_smi8_operand); |
312 | 303 |
313 template <size_t N> | 304 template <size_t N> |
314 INLINE(void Output(Bytecode bytecode, uint32_t(&operands)[N])); | 305 INLINE(void Output(Bytecode bytecode, uint32_t (&operands)[N], |
315 void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1, | 306 OperandScale operand_scale = OperandScale::k1X)); |
316 uint32_t operand2, uint32_t operand3); | |
317 void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1, | |
318 uint32_t operand2); | |
319 void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1); | |
320 void Output(Bytecode bytecode, uint32_t operand0); | |
321 void Output(Bytecode bytecode); | 307 void Output(Bytecode bytecode); |
308 void OutputScaled(Bytecode bytecode, OperandScale operand_scale, | |
309 uint32_t operand0, uint32_t operand1, uint32_t operand2, | |
310 uint32_t operand3); | |
311 void OutputScaled(Bytecode bytecode, OperandScale operand_scale, | |
312 uint32_t operand0, uint32_t operand1, uint32_t operand2); | |
313 void OutputScaled(Bytecode bytecode, OperandScale operand_scale, | |
314 uint32_t operand0, uint32_t operand1); | |
315 void OutputScaled(Bytecode bytecode, OperandScale operand_scale, | |
316 uint32_t operand0); | |
322 | 317 |
323 BytecodeArrayBuilder& OutputJump(Bytecode jump_bytecode, | 318 BytecodeArrayBuilder& OutputJump(Bytecode jump_bytecode, |
324 BytecodeLabel* label); | 319 BytecodeLabel* label); |
325 void PatchJump(const ZoneVector<uint8_t>::iterator& jump_target, | 320 void PatchJump(const ZoneVector<uint8_t>::iterator& jump_target, |
326 const ZoneVector<uint8_t>::iterator& jump_location); | 321 const ZoneVector<uint8_t>::iterator& jump_location); |
327 void PatchIndirectJumpWith8BitOperand( | 322 void PatchIndirectJumpWith8BitOperand( |
328 const ZoneVector<uint8_t>::iterator& jump_location, int delta); | 323 const ZoneVector<uint8_t>::iterator& jump_location, int delta); |
329 void PatchIndirectJumpWith16BitOperand( | 324 void PatchIndirectJumpWith16BitOperand( |
330 const ZoneVector<uint8_t>::iterator& jump_location, int delta); | 325 const ZoneVector<uint8_t>::iterator& jump_location, int delta); |
326 void PatchIndirectJumpWith32BitOperand( | |
327 const ZoneVector<uint8_t>::iterator& jump_location, int delta); | |
331 | 328 |
332 void LeaveBasicBlock(); | 329 void LeaveBasicBlock(); |
333 | 330 |
334 bool OperandIsValid(Bytecode bytecode, int operand_index, | 331 bool OperandIsValid(Bytecode bytecode, OperandScale operand_scale, |
335 uint32_t operand_value) const; | 332 int operand_index, uint32_t operand_value) const; |
336 bool RegisterIsValid(Register reg, OperandType reg_type) const; | 333 bool RegisterIsValid(Register reg, OperandSize reg_size) const; |
337 | 334 |
338 bool LastBytecodeInSameBlock() const; | 335 bool LastBytecodeInSameBlock() const; |
339 bool NeedToBooleanCast(); | 336 bool NeedToBooleanCast(); |
340 bool IsRegisterInAccumulator(Register reg); | 337 bool IsRegisterInAccumulator(Register reg); |
341 | 338 |
342 // Set position for return. | 339 // Set position for return. |
343 void SetReturnPosition(); | 340 void SetReturnPosition(); |
344 | 341 |
345 // Gets a constant pool entry for the |object|. | 342 // Gets a constant pool entry for the |object|. |
346 size_t GetConstantPoolEntry(Handle<Object> object); | 343 size_t GetConstantPoolEntry(Handle<Object> object); |
347 | 344 |
348 ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; } | 345 ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; } |
349 const ZoneVector<uint8_t>* bytecodes() const { return &bytecodes_; } | 346 const ZoneVector<uint8_t>* bytecodes() const { return &bytecodes_; } |
350 Isolate* isolate() const { return isolate_; } | 347 Isolate* isolate() const { return isolate_; } |
351 ConstantArrayBuilder* constant_array_builder() { | 348 ConstantArrayBuilder* constant_array_builder() { |
352 return &constant_array_builder_; | 349 return &constant_array_builder_; |
353 } | 350 } |
354 const ConstantArrayBuilder* constant_array_builder() const { | 351 const ConstantArrayBuilder* constant_array_builder() const { |
355 return &constant_array_builder_; | 352 return &constant_array_builder_; |
356 } | 353 } |
357 HandlerTableBuilder* handler_table_builder() { | 354 HandlerTableBuilder* handler_table_builder() { |
358 return &handler_table_builder_; | 355 return &handler_table_builder_; |
359 } | 356 } |
360 SourcePositionTableBuilder* source_position_table_builder() { | 357 SourcePositionTableBuilder* source_position_table_builder() { |
361 return &source_position_table_builder_; | 358 return &source_position_table_builder_; |
362 } | 359 } |
363 RegisterTranslator* register_translator() { return ®ister_translator_; } | |
364 | 360 |
365 Isolate* isolate_; | 361 Isolate* isolate_; |
366 Zone* zone_; | 362 Zone* zone_; |
367 ZoneVector<uint8_t> bytecodes_; | 363 ZoneVector<uint8_t> bytecodes_; |
368 bool bytecode_generated_; | 364 bool bytecode_generated_; |
369 ConstantArrayBuilder constant_array_builder_; | 365 ConstantArrayBuilder constant_array_builder_; |
370 HandlerTableBuilder handler_table_builder_; | 366 HandlerTableBuilder handler_table_builder_; |
371 SourcePositionTableBuilder source_position_table_builder_; | 367 SourcePositionTableBuilder source_position_table_builder_; |
372 size_t last_block_end_; | 368 size_t last_block_end_; |
373 size_t last_bytecode_start_; | 369 size_t last_bytecode_start_; |
374 bool exit_seen_in_block_; | 370 bool exit_seen_in_block_; |
375 int unbound_jumps_; | 371 int unbound_jumps_; |
376 int parameter_count_; | 372 int parameter_count_; |
377 int local_register_count_; | 373 int local_register_count_; |
378 int context_register_count_; | 374 int context_register_count_; |
379 int return_position_; | 375 int return_position_; |
380 TemporaryRegisterAllocator temporary_allocator_; | 376 TemporaryRegisterAllocator temporary_allocator_; |
381 RegisterTranslator register_translator_; | |
382 | 377 |
383 DISALLOW_COPY_AND_ASSIGN(BytecodeArrayBuilder); | 378 DISALLOW_COPY_AND_ASSIGN(BytecodeArrayBuilder); |
384 }; | 379 }; |
385 | 380 |
386 | 381 |
387 // A label representing a branch target in a bytecode array. When a | 382 // A label representing a branch target in a bytecode array. When a |
388 // label is bound, it represents a known position in the bytecode | 383 // label is bound, it represents a known position in the bytecode |
389 // array. For labels that are forward references there can be at most | 384 // array. For labels that are forward references there can be at most |
390 // one reference whilst it is unbound. | 385 // one reference whilst it is unbound. |
391 class BytecodeLabel final { | 386 class BytecodeLabel final { |
(...skipping 30 matching lines...) Expand all Loading... | |
422 size_t offset_; | 417 size_t offset_; |
423 | 418 |
424 friend class BytecodeArrayBuilder; | 419 friend class BytecodeArrayBuilder; |
425 }; | 420 }; |
426 | 421 |
427 } // namespace interpreter | 422 } // namespace interpreter |
428 } // namespace internal | 423 } // namespace internal |
429 } // namespace v8 | 424 } // namespace v8 |
430 | 425 |
431 #endif // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ | 426 #endif // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ |
OLD | NEW |