summaryrefslogtreecommitdiff
path: root/deps/v8/src/interpreter/bytecode-array-builder.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/interpreter/bytecode-array-builder.h')
-rw-r--r--deps/v8/src/interpreter/bytecode-array-builder.h233
1 files changed, 120 insertions, 113 deletions
diff --git a/deps/v8/src/interpreter/bytecode-array-builder.h b/deps/v8/src/interpreter/bytecode-array-builder.h
index 51b61861c3..a9fa7a7bb5 100644
--- a/deps/v8/src/interpreter/bytecode-array-builder.h
+++ b/deps/v8/src/interpreter/bytecode-array-builder.h
@@ -12,7 +12,7 @@
#include "src/interpreter/bytecodes.h"
#include "src/interpreter/constant-array-builder.h"
#include "src/interpreter/handler-table-builder.h"
-#include "src/zone-containers.h"
+#include "src/zone/zone-containers.h"
namespace v8 {
namespace internal {
@@ -61,23 +61,14 @@ class BytecodeArrayBuilder final : public ZoneObject {
int fixed_register_count() const { return context_count() + locals_count(); }
// Returns the number of fixed and temporary registers.
- int fixed_and_temporary_register_count() const {
- return fixed_register_count() + temporary_register_count();
- }
-
- int temporary_register_count() const {
- return temporary_register_allocator()->allocation_count();
+ int total_register_count() const {
+ DCHECK_LE(fixed_register_count(),
+ register_allocator()->maximum_register_count());
+ return register_allocator()->maximum_register_count();
}
Register Parameter(int parameter_index) const;
- // Return true if the register |reg| represents a parameter or a
- // local.
- bool RegisterIsParameterOrLocal(Register reg) const;
-
- // Returns true if the register |reg| is a live temporary register.
- bool TemporaryRegisterIsLive(Register reg) const;
-
// Constant loads to accumulator.
BytecodeArrayBuilder& LoadConstantPoolEntry(size_t entry);
BytecodeArrayBuilder& LoadLiteral(v8::internal::Smi* value);
@@ -94,11 +85,15 @@ class BytecodeArrayBuilder final : public ZoneObject {
int feedback_slot,
LanguageMode language_mode);
- // Load the object at |slot_index| in |context| into the accumulator.
- BytecodeArrayBuilder& LoadContextSlot(Register context, int slot_index);
+ // Load the object at |slot_index| at |depth| in the context chain starting
+ // with |context| into the accumulator.
+ BytecodeArrayBuilder& LoadContextSlot(Register context, int slot_index,
+ int depth);
- // Stores the object in the accumulator into |slot_index| of |context|.
- BytecodeArrayBuilder& StoreContextSlot(Register context, int slot_index);
+ // Stores the object in the accumulator into |slot_index| at |depth| in the
+ // context chain starting with |context|.
+ BytecodeArrayBuilder& StoreContextSlot(Register context, int slot_index,
+ int depth);
// Register-accumulator transfers.
BytecodeArrayBuilder& LoadAccumulatorWithRegister(Register reg);
@@ -127,6 +122,20 @@ class BytecodeArrayBuilder final : public ZoneObject {
BytecodeArrayBuilder& LoadLookupSlot(const Handle<String> name,
TypeofMode typeof_mode);
+ // Lookup the variable with |name|, which is known to be at |slot_index| at
+ // |depth| in the context chain if not shadowed by a context extension
+ // somewhere in that context chain.
+ BytecodeArrayBuilder& LoadLookupContextSlot(const Handle<String> name,
+ TypeofMode typeof_mode,
+ int slot_index, int depth);
+
+ // Lookup the variable with |name|, which has its feedback in |feedback_slot|
+ // and is known to be global if not shadowed by a context extension somewhere
+ // up to |depth| in that context chain.
+ BytecodeArrayBuilder& LoadLookupGlobalSlot(const Handle<String> name,
+ TypeofMode typeof_mode,
+ int feedback_slot, int depth);
+
// Store value in the accumulator into the variable with |name|.
BytecodeArrayBuilder& StoreLookupSlot(const Handle<String> name,
LanguageMode language_mode);
@@ -139,17 +148,19 @@ class BytecodeArrayBuilder final : public ZoneObject {
// in the accumulator.
BytecodeArrayBuilder& CreateBlockContext(Handle<ScopeInfo> scope_info);
- // Create a new context for a catch block with |exception| and |name| and the
- // closure in the accumulator.
+ // Create a new context for a catch block with |exception|, |name|,
+ // |scope_info|, and the closure in the accumulator.
BytecodeArrayBuilder& CreateCatchContext(Register exception,
- Handle<String> name);
+ Handle<String> name,
+ Handle<ScopeInfo> scope_info);
// Create a new context with size |slots|.
BytecodeArrayBuilder& CreateFunctionContext(int slots);
- // Creates a new context for a with-statement with the |object| in a register
- // and the closure in the accumulator.
- BytecodeArrayBuilder& CreateWithContext(Register object);
+ // Creates a new context with the given |scope_info| for a with-statement
+ // with the |object| in a register and the closure in the accumulator.
+ BytecodeArrayBuilder& CreateWithContext(Register object,
+ Handle<ScopeInfo> scope_info);
// Create a new arguments object in the accumulator.
BytecodeArrayBuilder& CreateArguments(CreateArgumentsType type);
@@ -171,46 +182,42 @@ class BytecodeArrayBuilder final : public ZoneObject {
BytecodeArrayBuilder& PopContext(Register context);
// Call a JS function. The JSFunction or Callable to be called should be in
- // |callable|, the receiver should be in |receiver_args| and all subsequent
- // arguments should be in registers <receiver_args + 1> to
- // <receiver_args + receiver_arg_count - 1>. Type feedback is recorded in
- // the |feedback_slot| in the type feedback vector.
+ // |callable|. The arguments should be in |args|, with the receiver in
+ // |args[0]|. Type feedback is recorded in the |feedback_slot| in the type
+ // feedback vector.
BytecodeArrayBuilder& Call(
- Register callable, Register receiver_args, size_t receiver_arg_count,
- int feedback_slot, TailCallMode tail_call_mode = TailCallMode::kDisallow);
-
- BytecodeArrayBuilder& TailCall(Register callable, Register receiver_args,
- size_t receiver_arg_count, int feedback_slot) {
- return Call(callable, receiver_args, receiver_arg_count, feedback_slot,
- TailCallMode::kAllow);
- }
+ Register callable, RegisterList args, int feedback_slot,
+ TailCallMode tail_call_mode = TailCallMode::kDisallow);
// Call the new operator. The accumulator holds the |new_target|.
- // The |constructor| is in a register followed by |arg_count|
- // consecutive arguments starting at |first_arg| for the constuctor
- // invocation.
- BytecodeArrayBuilder& New(Register constructor, Register first_arg,
- size_t arg_count);
-
- // Call the runtime function with |function_id|. The first argument should be
- // in |first_arg| and all subsequent arguments should be in registers
- // <first_arg + 1> to <first_arg + arg_count - 1>.
+ // The |constructor| is in a register and arguments are in |args|.
+ BytecodeArrayBuilder& New(Register constructor, RegisterList args,
+ int feedback_slot);
+
+ // Call the runtime function with |function_id| and arguments |args|.
+ BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id,
+ RegisterList args);
+ // Call the runtime function with |function_id| with single argument |arg|.
BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id,
- Register first_arg, size_t arg_count);
+ Register arg);
+ // Call the runtime function with |function_id| with no arguments.
+ BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id);
- // Call the runtime function with |function_id| that returns a pair of values.
- // The first argument should be in |first_arg| and all subsequent arguments
- // should be in registers <first_arg + 1> to <first_arg + arg_count - 1>. The
- // return values will be returned in <first_return> and <first_return + 1>.
+ // Call the runtime function with |function_id| and arguments |args|, that
+ // returns a pair of values. The return values will be returned in
+ // |return_pair|.
BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id,
- Register first_arg, size_t arg_count,
- Register first_return);
+ RegisterList args,
+ RegisterList return_pair);
+ // Call the runtime function with |function_id| with single argument |arg|
+ // that returns a pair of values. The return values will be returned in
+ // |return_pair|.
+ BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id,
+ Register arg,
+ RegisterList return_pair);
- // Call the JS runtime function with |context_index|. The the receiver should
- // be in |receiver_args| and all subsequent arguments should be in registers
- // <receiver + 1> to <receiver + receiver_args_count - 1>.
- BytecodeArrayBuilder& CallJSRuntime(int context_index, Register receiver_args,
- size_t receiver_args_count);
+ // Call the JS runtime function with |context_index| and arguments |args|.
+ BytecodeArrayBuilder& CallJSRuntime(int context_index, RegisterList args);
// Operators (register holds the lhs value, accumulator holds the rhs value).
// Type feedback will be recorded in the |feedback_slot|
@@ -230,15 +237,13 @@ class BytecodeArrayBuilder final : public ZoneObject {
BytecodeArrayBuilder& Delete(Register object, LanguageMode language_mode);
// Tests.
- BytecodeArrayBuilder& CompareOperation(Token::Value op, Register reg);
-
- // Casts accumulator and stores result in accumulator.
- BytecodeArrayBuilder& CastAccumulatorToBoolean();
+ BytecodeArrayBuilder& CompareOperation(Token::Value op, Register reg,
+ int feedback_slot = kNoFeedbackSlot);
- // Casts accumulator and stores result in register |out|.
- BytecodeArrayBuilder& CastAccumulatorToJSObject(Register out);
- BytecodeArrayBuilder& CastAccumulatorToName(Register out);
- BytecodeArrayBuilder& CastAccumulatorToNumber(Register out);
+ // Converts accumulator and stores result in register |out|.
+ BytecodeArrayBuilder& ConvertAccumulatorToObject(Register out);
+ BytecodeArrayBuilder& ConvertAccumulatorToName(Register out);
+ BytecodeArrayBuilder& ConvertAccumulatorToNumber(Register out);
// Flow Control.
BytecodeArrayBuilder& Bind(BytecodeLabel* label);
@@ -250,11 +255,10 @@ class BytecodeArrayBuilder final : public ZoneObject {
BytecodeArrayBuilder& JumpIfNotHole(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfNull(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfUndefined(BytecodeLabel* label);
+ BytecodeArrayBuilder& JumpLoop(BytecodeLabel* label, int loop_depth);
BytecodeArrayBuilder& StackCheck(int position);
- BytecodeArrayBuilder& OsrPoll(int loop_depth);
-
BytecodeArrayBuilder& Throw();
BytecodeArrayBuilder& ReThrow();
BytecodeArrayBuilder& Return();
@@ -264,10 +268,10 @@ class BytecodeArrayBuilder final : public ZoneObject {
// Complex flow control.
BytecodeArrayBuilder& ForInPrepare(Register receiver,
- Register cache_info_triple);
- BytecodeArrayBuilder& ForInDone(Register index, Register cache_length);
+ RegisterList cache_info_triple);
+ BytecodeArrayBuilder& ForInContinue(Register index, Register cache_length);
BytecodeArrayBuilder& ForInNext(Register receiver, Register index,
- Register cache_type_array_pair,
+ RegisterList cache_type_array_pair,
int feedback_slot);
BytecodeArrayBuilder& ForInStep(Register index);
@@ -292,20 +296,55 @@ class BytecodeArrayBuilder final : public ZoneObject {
void InitializeReturnPosition(FunctionLiteral* literal);
- void SetStatementPosition(Statement* stmt);
- void SetExpressionPosition(Expression* expr);
- void SetExpressionAsStatementPosition(Expression* expr);
+ void SetStatementPosition(Statement* stmt) {
+ if (stmt->position() == kNoSourcePosition) return;
+ latest_source_info_.MakeStatementPosition(stmt->position());
+ }
+
+ void SetExpressionPosition(Expression* expr) {
+ if (expr->position() == kNoSourcePosition) return;
+ if (!latest_source_info_.is_statement()) {
+ // Ensure the current expression position is overwritten with the
+ // latest value.
+ latest_source_info_.MakeExpressionPosition(expr->position());
+ }
+ }
+
+ void SetExpressionAsStatementPosition(Expression* expr) {
+ if (expr->position() == kNoSourcePosition) return;
+ latest_source_info_.MakeStatementPosition(expr->position());
+ }
+
+ bool RequiresImplicitReturn() const { return !return_seen_in_block_; }
// Accessors
- TemporaryRegisterAllocator* temporary_register_allocator() {
- return &temporary_allocator_;
+ BytecodeRegisterAllocator* register_allocator() {
+ return &register_allocator_;
}
- const TemporaryRegisterAllocator* temporary_register_allocator() const {
- return &temporary_allocator_;
+ const BytecodeRegisterAllocator* register_allocator() const {
+ return &register_allocator_;
}
Zone* zone() const { return zone_; }
- void EnsureReturn();
+ private:
+ friend class BytecodeRegisterAllocator;
+
+ INLINE(void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1,
+ uint32_t operand2, uint32_t operand3));
+ INLINE(void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1,
+ uint32_t operand2));
+ INLINE(void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1));
+ INLINE(void Output(Bytecode bytecode, uint32_t operand0));
+ INLINE(void Output(Bytecode bytecode));
+
+ INLINE(void OutputJump(Bytecode bytecode, BytecodeLabel* label));
+ INLINE(void OutputJump(Bytecode bytecode, uint32_t operand0,
+ BytecodeLabel* label));
+
+ bool RegisterIsValid(Register reg) const;
+ bool OperandsAreValid(Bytecode bytecode, int operand_count,
+ uint32_t operand0 = 0, uint32_t operand1 = 0,
+ uint32_t operand2 = 0, uint32_t operand3 = 0) const;
static uint32_t RegisterOperand(Register reg) {
return static_cast<uint32_t>(reg.ToOperand());
@@ -325,40 +364,6 @@ class BytecodeArrayBuilder final : public ZoneObject {
return static_cast<uint32_t>(value);
}
- private:
- friend class BytecodeRegisterAllocator;
-
- static Bytecode BytecodeForBinaryOperation(Token::Value op);
- static Bytecode BytecodeForCountOperation(Token::Value op);
- static Bytecode BytecodeForCompareOperation(Token::Value op);
- static Bytecode BytecodeForStoreNamedProperty(LanguageMode language_mode);
- static Bytecode BytecodeForStoreKeyedProperty(LanguageMode language_mode);
- static Bytecode BytecodeForLoadGlobal(TypeofMode typeof_mode);
- static Bytecode BytecodeForStoreGlobal(LanguageMode language_mode);
- static Bytecode BytecodeForStoreLookupSlot(LanguageMode language_mode);
- static Bytecode BytecodeForCreateArguments(CreateArgumentsType type);
- static Bytecode BytecodeForDelete(LanguageMode language_mode);
- static Bytecode BytecodeForCall(TailCallMode tail_call_mode);
-
- void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1,
- uint32_t operand2, uint32_t operand3);
- void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1,
- uint32_t operand2);
- void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1);
- void Output(Bytecode bytecode, uint32_t operand0);
- void Output(Bytecode bytecode);
-
- BytecodeArrayBuilder& OutputJump(Bytecode jump_bytecode,
- BytecodeLabel* label);
-
- bool RegisterIsValid(Register reg) const;
- bool OperandsAreValid(Bytecode bytecode, int operand_count,
- uint32_t operand0 = 0, uint32_t operand1 = 0,
- uint32_t operand2 = 0, uint32_t operand3 = 0) const;
-
- // Attach latest source position to |node|.
- void AttachSourceInfo(BytecodeNode* node);
-
// Set position for return.
void SetReturnPosition();
@@ -395,11 +400,13 @@ class BytecodeArrayBuilder final : public ZoneObject {
int local_register_count_;
int context_register_count_;
int return_position_;
- TemporaryRegisterAllocator temporary_allocator_;
+ BytecodeRegisterAllocator register_allocator_;
BytecodeArrayWriter bytecode_array_writer_;
BytecodePipelineStage* pipeline_;
BytecodeSourceInfo latest_source_info_;
+ static int const kNoFeedbackSlot = 0;
+
DISALLOW_COPY_AND_ASSIGN(BytecodeArrayBuilder);
};