| 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-array-writer.h" | 9 #include "src/interpreter/bytecode-array-writer.h" |
| 10 #include "src/interpreter/bytecode-register-allocator.h" | 10 #include "src/interpreter/bytecode-register-allocator.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 return context_register_count_; | 54 return context_register_count_; |
| 55 } | 55 } |
| 56 | 56 |
| 57 Register first_context_register() const; | 57 Register first_context_register() const; |
| 58 Register last_context_register() const; | 58 Register last_context_register() const; |
| 59 | 59 |
| 60 // Returns the number of fixed (non-temporary) registers. | 60 // Returns the number of fixed (non-temporary) registers. |
| 61 int fixed_register_count() const { return context_count() + locals_count(); } | 61 int fixed_register_count() const { return context_count() + locals_count(); } |
| 62 | 62 |
| 63 // Returns the number of fixed and temporary registers. | 63 // Returns the number of fixed and temporary registers. |
| 64 int fixed_and_temporary_register_count() const { | 64 int total_register_count() const { |
| 65 return fixed_register_count() + temporary_register_count(); | 65 DCHECK_LE(fixed_register_count(), |
| 66 } | 66 register_allocator()->maximum_register_count()); |
| 67 | 67 return register_allocator()->maximum_register_count(); |
| 68 int temporary_register_count() const { | |
| 69 return temporary_register_allocator()->allocation_count(); | |
| 70 } | 68 } |
| 71 | 69 |
| 72 Register Parameter(int parameter_index) const; | 70 Register Parameter(int parameter_index) const; |
| 73 | 71 |
| 74 // Return true if the register |reg| represents a parameter or a | |
| 75 // local. | |
| 76 bool RegisterIsParameterOrLocal(Register reg) const; | |
| 77 | |
| 78 // Returns true if the register |reg| is a live temporary register. | |
| 79 bool TemporaryRegisterIsLive(Register reg) const; | |
| 80 | |
| 81 // Constant loads to accumulator. | 72 // Constant loads to accumulator. |
| 82 BytecodeArrayBuilder& LoadConstantPoolEntry(size_t entry); | 73 BytecodeArrayBuilder& LoadConstantPoolEntry(size_t entry); |
| 83 BytecodeArrayBuilder& LoadLiteral(v8::internal::Smi* value); | 74 BytecodeArrayBuilder& LoadLiteral(v8::internal::Smi* value); |
| 84 BytecodeArrayBuilder& LoadLiteral(Handle<Object> object); | 75 BytecodeArrayBuilder& LoadLiteral(Handle<Object> object); |
| 85 BytecodeArrayBuilder& LoadUndefined(); | 76 BytecodeArrayBuilder& LoadUndefined(); |
| 86 BytecodeArrayBuilder& LoadNull(); | 77 BytecodeArrayBuilder& LoadNull(); |
| 87 BytecodeArrayBuilder& LoadTheHole(); | 78 BytecodeArrayBuilder& LoadTheHole(); |
| 88 BytecodeArrayBuilder& LoadTrue(); | 79 BytecodeArrayBuilder& LoadTrue(); |
| 89 BytecodeArrayBuilder& LoadFalse(); | 80 BytecodeArrayBuilder& LoadFalse(); |
| 90 | 81 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 Register output); | 175 Register output); |
| 185 | 176 |
| 186 // Push the context in accumulator as the new context, and store in register | 177 // Push the context in accumulator as the new context, and store in register |
| 187 // |context|. | 178 // |context|. |
| 188 BytecodeArrayBuilder& PushContext(Register context); | 179 BytecodeArrayBuilder& PushContext(Register context); |
| 189 | 180 |
| 190 // Pop the current context and replace with |context|. | 181 // Pop the current context and replace with |context|. |
| 191 BytecodeArrayBuilder& PopContext(Register context); | 182 BytecodeArrayBuilder& PopContext(Register context); |
| 192 | 183 |
| 193 // Call a JS function. The JSFunction or Callable to be called should be in | 184 // Call a JS function. The JSFunction or Callable to be called should be in |
| 194 // |callable|, the receiver should be in |receiver_args| and all subsequent | 185 // |callable|. The arguments should be in |args|, with the receiver in |
| 195 // arguments should be in registers <receiver_args + 1> to | 186 // |args[0]|. Type feedback is recorded in the |feedback_slot| in the type |
| 196 // <receiver_args + receiver_arg_count - 1>. Type feedback is recorded in | 187 // feedback vector. |
| 197 // the |feedback_slot| in the type feedback vector. | |
| 198 BytecodeArrayBuilder& Call( | 188 BytecodeArrayBuilder& Call( |
| 199 Register callable, Register receiver_args, size_t receiver_arg_count, | 189 Register callable, RegisterList args, int feedback_slot, |
| 200 int feedback_slot, TailCallMode tail_call_mode = TailCallMode::kDisallow); | 190 TailCallMode tail_call_mode = TailCallMode::kDisallow); |
| 201 | |
| 202 BytecodeArrayBuilder& TailCall(Register callable, Register receiver_args, | |
| 203 size_t receiver_arg_count, int feedback_slot) { | |
| 204 return Call(callable, receiver_args, receiver_arg_count, feedback_slot, | |
| 205 TailCallMode::kAllow); | |
| 206 } | |
| 207 | 191 |
| 208 // Call the new operator. The accumulator holds the |new_target|. | 192 // Call the new operator. The accumulator holds the |new_target|. |
| 209 // The |constructor| is in a register followed by |arg_count| | 193 // The |constructor| is in a register and arguments are in |args|. |
| 210 // consecutive arguments starting at |first_arg| for the constuctor | 194 BytecodeArrayBuilder& New(Register constructor, RegisterList args, |
| 211 // invocation. | 195 int feedback_slot); |
| 212 BytecodeArrayBuilder& New(Register constructor, Register first_arg, | |
| 213 size_t arg_count, int feedback_slot); | |
| 214 | 196 |
| 215 // Call the runtime function with |function_id|. The first argument should be | 197 // Call the runtime function with |function_id| and arguments |args|. |
| 216 // in |first_arg| and all subsequent arguments should be in registers | |
| 217 // <first_arg + 1> to <first_arg + arg_count - 1>. | |
| 218 BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id, | 198 BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id, |
| 219 Register first_arg, size_t arg_count); | 199 RegisterList args); |
| 200 // Call the runtime function with |function_id| with single argument |arg|. |
| 201 BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id, |
| 202 Register arg); |
| 203 // Call the runtime function with |function_id| with no arguments. |
| 204 BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id); |
| 220 | 205 |
| 221 // Call the runtime function with |function_id| that returns a pair of values. | 206 // Call the runtime function with |function_id| and arguments |args|, that |
| 222 // The first argument should be in |first_arg| and all subsequent arguments | 207 // returns a pair of values. The return values will be returned in |
| 223 // should be in registers <first_arg + 1> to <first_arg + arg_count - 1>. The | 208 // <first_return> and <first_return + 1>. |
| 224 // return values will be returned in <first_return> and <first_return + 1>. | |
| 225 BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id, | 209 BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id, |
| 226 Register first_arg, size_t arg_count, | 210 RegisterList args, |
| 227 Register first_return); | 211 Register first_return); |
| 212 // Call the runtime function with |function_id| with single argument |arg|. |
| 213 BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id, |
| 214 Register arg, Register first_return); |
| 228 | 215 |
| 229 // Call the JS runtime function with |context_index|. The the receiver should | 216 // Call the JS runtime function with |context_index| and arguments |args|. |
| 230 // be in |receiver_args| and all subsequent arguments should be in registers | 217 BytecodeArrayBuilder& CallJSRuntime(int context_index, RegisterList args); |
| 231 // <receiver + 1> to <receiver + receiver_args_count - 1>. | |
| 232 BytecodeArrayBuilder& CallJSRuntime(int context_index, Register receiver_args, | |
| 233 size_t receiver_args_count); | |
| 234 | 218 |
| 235 // Operators (register holds the lhs value, accumulator holds the rhs value). | 219 // Operators (register holds the lhs value, accumulator holds the rhs value). |
| 236 // Type feedback will be recorded in the |feedback_slot| | 220 // Type feedback will be recorded in the |feedback_slot| |
| 237 BytecodeArrayBuilder& BinaryOperation(Token::Value binop, Register reg, | 221 BytecodeArrayBuilder& BinaryOperation(Token::Value binop, Register reg, |
| 238 int feedback_slot); | 222 int feedback_slot); |
| 239 | 223 |
| 240 // Count Operators (value stored in accumulator). | 224 // Count Operators (value stored in accumulator). |
| 241 // Type feedback will be recorded in the |feedback_slot| | 225 // Type feedback will be recorded in the |feedback_slot| |
| 242 BytecodeArrayBuilder& CountOperation(Token::Value op, int feedback_slot); | 226 BytecodeArrayBuilder& CountOperation(Token::Value op, int feedback_slot); |
| 243 | 227 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 // latest value. | 305 // latest value. |
| 322 latest_source_info_.MakeExpressionPosition(expr->position()); | 306 latest_source_info_.MakeExpressionPosition(expr->position()); |
| 323 } | 307 } |
| 324 } | 308 } |
| 325 | 309 |
| 326 void SetExpressionAsStatementPosition(Expression* expr) { | 310 void SetExpressionAsStatementPosition(Expression* expr) { |
| 327 if (expr->position() == kNoSourcePosition) return; | 311 if (expr->position() == kNoSourcePosition) return; |
| 328 latest_source_info_.MakeStatementPosition(expr->position()); | 312 latest_source_info_.MakeStatementPosition(expr->position()); |
| 329 } | 313 } |
| 330 | 314 |
| 315 void EnsureReturn(); |
| 316 |
| 331 // Accessors | 317 // Accessors |
| 332 TemporaryRegisterAllocator* temporary_register_allocator() { | 318 BytecodeRegisterAllocator* register_allocator() { |
| 333 return &temporary_allocator_; | 319 return ®ister_allocator_; |
| 334 } | 320 } |
| 335 const TemporaryRegisterAllocator* temporary_register_allocator() const { | 321 const BytecodeRegisterAllocator* register_allocator() const { |
| 336 return &temporary_allocator_; | 322 return ®ister_allocator_; |
| 337 } | 323 } |
| 338 Zone* zone() const { return zone_; } | 324 Zone* zone() const { return zone_; } |
| 339 | 325 |
| 340 void EnsureReturn(); | |
| 341 | |
| 342 static uint32_t RegisterOperand(Register reg) { | |
| 343 return static_cast<uint32_t>(reg.ToOperand()); | |
| 344 } | |
| 345 | |
| 346 static uint32_t SignedOperand(int value) { | |
| 347 return static_cast<uint32_t>(value); | |
| 348 } | |
| 349 | |
| 350 static uint32_t UnsignedOperand(int value) { | |
| 351 DCHECK_GE(value, 0); | |
| 352 return static_cast<uint32_t>(value); | |
| 353 } | |
| 354 | |
| 355 static uint32_t UnsignedOperand(size_t value) { | |
| 356 DCHECK_LE(value, kMaxUInt32); | |
| 357 return static_cast<uint32_t>(value); | |
| 358 } | |
| 359 | |
| 360 private: | 326 private: |
| 361 friend class BytecodeRegisterAllocator; | 327 friend class BytecodeRegisterAllocator; |
| 362 | 328 |
| 363 INLINE(void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1, | 329 INLINE(void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
| 364 uint32_t operand2, uint32_t operand3)); | 330 uint32_t operand2, uint32_t operand3)); |
| 365 INLINE(void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1, | 331 INLINE(void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
| 366 uint32_t operand2)); | 332 uint32_t operand2)); |
| 367 INLINE(void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1)); | 333 INLINE(void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1)); |
| 368 INLINE(void Output(Bytecode bytecode, uint32_t operand0)); | 334 INLINE(void Output(Bytecode bytecode, uint32_t operand0)); |
| 369 INLINE(void Output(Bytecode bytecode)); | 335 INLINE(void Output(Bytecode bytecode)); |
| 370 | 336 |
| 371 INLINE(void OutputJump(Bytecode bytecode, BytecodeLabel* label)); | 337 INLINE(void OutputJump(Bytecode bytecode, BytecodeLabel* label)); |
| 372 INLINE(void OutputJump(Bytecode bytecode, uint32_t operand0, | 338 INLINE(void OutputJump(Bytecode bytecode, uint32_t operand0, |
| 373 BytecodeLabel* label)); | 339 BytecodeLabel* label)); |
| 374 | 340 |
| 375 bool RegisterIsValid(Register reg) const; | 341 bool RegisterIsValid(Register reg) const; |
| 376 bool OperandsAreValid(Bytecode bytecode, int operand_count, | 342 bool OperandsAreValid(Bytecode bytecode, int operand_count, |
| 377 uint32_t operand0 = 0, uint32_t operand1 = 0, | 343 uint32_t operand0 = 0, uint32_t operand1 = 0, |
| 378 uint32_t operand2 = 0, uint32_t operand3 = 0) const; | 344 uint32_t operand2 = 0, uint32_t operand3 = 0) const; |
| 379 | 345 |
| 346 static uint32_t RegisterOperand(Register reg) { |
| 347 return static_cast<uint32_t>(reg.ToOperand()); |
| 348 } |
| 349 |
| 350 static uint32_t SignedOperand(int value) { |
| 351 return static_cast<uint32_t>(value); |
| 352 } |
| 353 |
| 354 static uint32_t UnsignedOperand(int value) { |
| 355 DCHECK_GE(value, 0); |
| 356 return static_cast<uint32_t>(value); |
| 357 } |
| 358 |
| 359 static uint32_t UnsignedOperand(size_t value) { |
| 360 DCHECK_LE(value, kMaxUInt32); |
| 361 return static_cast<uint32_t>(value); |
| 362 } |
| 363 |
| 380 // Set position for return. | 364 // Set position for return. |
| 381 void SetReturnPosition(); | 365 void SetReturnPosition(); |
| 382 | 366 |
| 383 // Gets a constant pool entry for the |object|. | 367 // Gets a constant pool entry for the |object|. |
| 384 size_t GetConstantPoolEntry(Handle<Object> object); | 368 size_t GetConstantPoolEntry(Handle<Object> object); |
| 385 | 369 |
| 386 // Not implemented as the illegal bytecode is used inside internally | 370 // Not implemented as the illegal bytecode is used inside internally |
| 387 // to indicate a bytecode field is not valid or an error has occured | 371 // to indicate a bytecode field is not valid or an error has occured |
| 388 // during bytecode generation. | 372 // during bytecode generation. |
| 389 BytecodeArrayBuilder& Illegal(); | 373 BytecodeArrayBuilder& Illegal(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 406 | 390 |
| 407 Zone* zone_; | 391 Zone* zone_; |
| 408 bool bytecode_generated_; | 392 bool bytecode_generated_; |
| 409 ConstantArrayBuilder constant_array_builder_; | 393 ConstantArrayBuilder constant_array_builder_; |
| 410 HandlerTableBuilder handler_table_builder_; | 394 HandlerTableBuilder handler_table_builder_; |
| 411 bool return_seen_in_block_; | 395 bool return_seen_in_block_; |
| 412 int parameter_count_; | 396 int parameter_count_; |
| 413 int local_register_count_; | 397 int local_register_count_; |
| 414 int context_register_count_; | 398 int context_register_count_; |
| 415 int return_position_; | 399 int return_position_; |
| 416 TemporaryRegisterAllocator temporary_allocator_; | 400 BytecodeRegisterAllocator register_allocator_; |
| 417 BytecodeArrayWriter bytecode_array_writer_; | 401 BytecodeArrayWriter bytecode_array_writer_; |
| 418 BytecodePipelineStage* pipeline_; | 402 BytecodePipelineStage* pipeline_; |
| 419 BytecodeSourceInfo latest_source_info_; | 403 BytecodeSourceInfo latest_source_info_; |
| 420 | 404 |
| 421 static int const kNoFeedbackSlot = 0; | 405 static int const kNoFeedbackSlot = 0; |
| 422 | 406 |
| 423 DISALLOW_COPY_AND_ASSIGN(BytecodeArrayBuilder); | 407 DISALLOW_COPY_AND_ASSIGN(BytecodeArrayBuilder); |
| 424 }; | 408 }; |
| 425 | 409 |
| 426 } // namespace interpreter | 410 } // namespace interpreter |
| 427 } // namespace internal | 411 } // namespace internal |
| 428 } // namespace v8 | 412 } // namespace v8 |
| 429 | 413 |
| 430 #endif // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ | 414 #endif // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ |
| OLD | NEW |