Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE
This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.
FPIIM-449
Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/src/interpreter/bytecode-array-builder.h b/src/interpreter/bytecode-array-builder.h
index 7c23dc3..fe69337 100644
--- a/src/interpreter/bytecode-array-builder.h
+++ b/src/interpreter/bytecode-array-builder.h
@@ -6,8 +6,12 @@
#define V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_
#include "src/ast/ast.h"
+#include "src/interpreter/bytecode-register-allocator.h"
#include "src/interpreter/bytecodes.h"
#include "src/interpreter/constant-array-builder.h"
+#include "src/interpreter/handler-table-builder.h"
+#include "src/interpreter/register-translator.h"
+#include "src/interpreter/source-position-table.h"
#include "src/zone-containers.h"
namespace v8 {
@@ -18,36 +22,29 @@
namespace interpreter {
class BytecodeLabel;
-class ConstantArrayBuilder;
class Register;
-// TODO(rmcilroy): Unify this with CreateArgumentsParameters::Type in Turbofan
-// when rest parameters implementation has settled down.
-enum class CreateArgumentsType { kMappedArguments, kUnmappedArguments };
-
-class BytecodeArrayBuilder final {
+class BytecodeArrayBuilder final : public ZoneObject, private RegisterMover {
public:
- BytecodeArrayBuilder(Isolate* isolate, Zone* zone);
+ BytecodeArrayBuilder(Isolate* isolate, Zone* zone, int parameter_count,
+ int context_count, int locals_count);
~BytecodeArrayBuilder();
Handle<BytecodeArray> ToBytecodeArray();
- // Set the number of parameters expected by function.
- void set_parameter_count(int number_of_params);
+ // Get the number of parameters expected by function.
int parameter_count() const {
DCHECK_GE(parameter_count_, 0);
return parameter_count_;
}
- // Set the number of locals required for bytecode array.
- void set_locals_count(int number_of_locals);
+ // Get the number of locals required for bytecode array.
int locals_count() const {
DCHECK_GE(local_register_count_, 0);
return local_register_count_;
}
- // Set number of contexts required for bytecode array.
- void set_context_count(int number_of_contexts);
+ // Get number of contexts required for bytecode array.
int context_count() const {
DCHECK_GE(context_register_count_, 0);
return context_register_count_;
@@ -59,14 +56,30 @@
// Returns the number of fixed (non-temporary) registers.
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();
+ }
+
+ // Returns the number of registers used for translating wide
+ // register operands into byte sized register operands.
+ int translation_register_count() const {
+ return RegisterTranslator::RegisterCountAdjustment(
+ fixed_and_temporary_register_count(), parameter_count());
+ }
+
Register Parameter(int parameter_index) const;
// Return true if the register |reg| represents a parameter or a
// local.
bool RegisterIsParameterOrLocal(Register reg) const;
- // Return true if the register |reg| represents a temporary register.
- bool RegisterIsTemporary(Register reg) const;
+ // Returns true if the register |reg| is a live temporary register.
+ bool TemporaryRegisterIsLive(Register reg) const;
// Constant loads to accumulator.
BytecodeArrayBuilder& LoadLiteral(v8::internal::Smi* value);
@@ -80,7 +93,6 @@
// Global loads to the accumulator and stores from the accumulator.
BytecodeArrayBuilder& LoadGlobal(const Handle<String> name, int feedback_slot,
- LanguageMode language_mode,
TypeofMode typeof_mode);
BytecodeArrayBuilder& StoreGlobal(const Handle<String> name,
int feedback_slot,
@@ -98,20 +110,17 @@
// Register-register transfer.
BytecodeArrayBuilder& MoveRegister(Register from, Register to);
- BytecodeArrayBuilder& ExchangeRegisters(Register reg0, Register reg1);
// Named load property.
BytecodeArrayBuilder& LoadNamedProperty(Register object,
- const Handle<String> name,
- int feedback_slot,
- LanguageMode language_mode);
+ const Handle<Name> name,
+ int feedback_slot);
// Keyed load property. The key should be in the accumulator.
- BytecodeArrayBuilder& LoadKeyedProperty(Register object, int feedback_slot,
- LanguageMode language_mode);
+ BytecodeArrayBuilder& LoadKeyedProperty(Register object, int feedback_slot);
// Store properties. The value to be stored should be in the accumulator.
BytecodeArrayBuilder& StoreNamedProperty(Register object,
- const Handle<String> name,
+ const Handle<Name> name,
int feedback_slot,
LanguageMode language_mode);
BytecodeArrayBuilder& StoreKeyedProperty(Register object, Register key,
@@ -149,44 +158,51 @@
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| and all subsequent
- // arguments should be in registers <receiver + 1> to
- // <receiver + 1 + arg_count>.
- BytecodeArrayBuilder& Call(Register callable, Register receiver,
- size_t arg_count, int feedback_slot);
+ // |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>.
+ BytecodeArrayBuilder& Call(
+ Register callable, Register receiver_args, size_t receiver_arg_count,
+ int feedback_slot, TailCallMode tail_call_mode = TailCallMode::kDisallow);
- // Call the new operator. The |constructor| register is followed by
- // |arg_count| consecutive registers containing arguments to be
- // applied to the constructor.
+ 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);
+ }
+
+ // 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 + 1 + arg_count>.
+ // <first_arg + 1> to <first_arg + arg_count - 1>.
BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id,
Register first_arg, size_t arg_count);
// 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 + 1 + arg_count>. The
+ // 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>.
BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id,
Register first_arg, size_t arg_count,
Register first_return);
// Call the JS runtime function with |context_index|. The the receiver should
- // be in |receiver| and all subsequent arguments should be in registers
- // <receiver + 1> to <receiver + 1 + arg_count>.
- BytecodeArrayBuilder& CallJSRuntime(int context_index, Register receiver,
- size_t arg_count);
+ // 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);
// Operators (register holds the lhs value, accumulator holds the rhs value).
- BytecodeArrayBuilder& BinaryOperation(Token::Value binop, Register reg,
- Strength strength);
+ BytecodeArrayBuilder& BinaryOperation(Token::Value binop, Register reg);
// Count Operators (value stored in accumulator).
- BytecodeArrayBuilder& CountOperation(Token::Value op, Strength strength);
+ BytecodeArrayBuilder& CountOperation(Token::Value op);
// Unary Operators.
BytecodeArrayBuilder& LogicalNot();
@@ -195,11 +211,9 @@
// Deletes property from an object. This expects that accumulator contains
// the key to be deleted and the register contains a reference to the object.
BytecodeArrayBuilder& Delete(Register object, LanguageMode language_mode);
- BytecodeArrayBuilder& DeleteLookupSlot();
// Tests.
- BytecodeArrayBuilder& CompareOperation(Token::Value op, Register reg,
- Strength strength);
+ BytecodeArrayBuilder& CompareOperation(Token::Value op, Register reg);
// Casts.
BytecodeArrayBuilder& CastAccumulatorToBoolean();
@@ -214,48 +228,65 @@
BytecodeArrayBuilder& Jump(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfTrue(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfFalse(BytecodeLabel* label);
+ BytecodeArrayBuilder& JumpIfNotHole(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfNull(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfUndefined(BytecodeLabel* label);
+ BytecodeArrayBuilder& StackCheck();
+
BytecodeArrayBuilder& Throw();
+ BytecodeArrayBuilder& ReThrow();
BytecodeArrayBuilder& Return();
+ // Debugger.
+ BytecodeArrayBuilder& Debugger();
+
// Complex flow control.
- BytecodeArrayBuilder& ForInPrepare(Register cache_type, Register cache_array,
- Register cache_length);
+ BytecodeArrayBuilder& ForInPrepare(Register cache_info_triple);
BytecodeArrayBuilder& ForInDone(Register index, Register cache_length);
- BytecodeArrayBuilder& ForInNext(Register receiver, Register cache_type,
- Register cache_array, Register index);
+ BytecodeArrayBuilder& ForInNext(Register receiver, Register index,
+ Register cache_type_array_pair);
BytecodeArrayBuilder& ForInStep(Register index);
+ // Exception handling.
+ BytecodeArrayBuilder& MarkHandler(int handler_id, bool will_catch);
+ BytecodeArrayBuilder& MarkTryBegin(int handler_id, Register context);
+ BytecodeArrayBuilder& MarkTryEnd(int handler_id);
+
+ // Creates a new handler table entry and returns a {hander_id} identifying the
+ // entry, so that it can be referenced by above exception handling support.
+ int NewHandlerEntry() { return handler_table_builder()->NewHandlerEntry(); }
+
+ void SetStatementPosition(Statement* stmt);
+ void SetExpressionPosition(Expression* expr);
+
// Accessors
Zone* zone() const { return zone_; }
+ TemporaryRegisterAllocator* temporary_register_allocator() {
+ return &temporary_allocator_;
+ }
+ const TemporaryRegisterAllocator* temporary_register_allocator() const {
+ return &temporary_allocator_;
+ }
+
+ void EnsureReturn(FunctionLiteral* literal);
private:
- ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; }
- const ZoneVector<uint8_t>* bytecodes() const { return &bytecodes_; }
- Isolate* isolate() const { return isolate_; }
- ConstantArrayBuilder* constant_array_builder() {
- return &constant_array_builder_;
- }
- const ConstantArrayBuilder* constant_array_builder() const {
- return &constant_array_builder_;
- }
+ class PreviousBytecodeHelper;
+ friend class BytecodeRegisterAllocator;
static Bytecode BytecodeForBinaryOperation(Token::Value op);
static Bytecode BytecodeForCountOperation(Token::Value op);
static Bytecode BytecodeForCompareOperation(Token::Value op);
static Bytecode BytecodeForWideOperands(Bytecode bytecode);
- static Bytecode BytecodeForLoadIC(LanguageMode language_mode);
- static Bytecode BytecodeForKeyedLoadIC(LanguageMode language_mode);
static Bytecode BytecodeForStoreIC(LanguageMode language_mode);
static Bytecode BytecodeForKeyedStoreIC(LanguageMode language_mode);
- static Bytecode BytecodeForLoadGlobal(LanguageMode language_mode,
- TypeofMode typeof_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);
static bool FitsInIdx8Operand(int value);
static bool FitsInIdx8Operand(size_t value);
@@ -263,15 +294,17 @@
static bool FitsInIdx16Operand(int value);
static bool FitsInIdx16Operand(size_t value);
static bool FitsInReg8Operand(Register value);
+ static bool FitsInReg8OperandUntranslated(Register value);
static bool FitsInReg16Operand(Register value);
+ static bool FitsInReg16OperandUntranslated(Register value);
+
+ // RegisterMover interface.
+ void MoveRegisterUntranslated(Register from, Register to) override;
static Bytecode GetJumpWithConstantOperand(Bytecode jump_smi8_operand);
static Bytecode GetJumpWithConstantWideOperand(Bytecode jump_smi8_operand);
static Bytecode GetJumpWithToBoolean(Bytecode jump_smi8_operand);
- Register MapRegister(Register reg);
- Register MapRegisters(Register reg, Register args_base, int args_length = 1);
-
template <size_t N>
INLINE(void Output(Bytecode bytecode, uint32_t(&operands)[N]));
void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1,
@@ -292,49 +325,54 @@
const ZoneVector<uint8_t>::iterator& jump_location, int delta);
void LeaveBasicBlock();
- void EnsureReturn();
bool OperandIsValid(Bytecode bytecode, int operand_index,
uint32_t operand_value) const;
- bool LastBytecodeInSameBlock() const;
+ bool RegisterIsValid(Register reg, OperandType reg_type) const;
+ bool LastBytecodeInSameBlock() const;
bool NeedToBooleanCast();
bool IsRegisterInAccumulator(Register reg);
- bool RegisterIsValid(Register reg) const;
-
- // Temporary register management.
- int BorrowTemporaryRegister();
- int BorrowTemporaryRegisterNotInRange(int start_index, int end_index);
- void ReturnTemporaryRegister(int reg_index);
- int PrepareForConsecutiveTemporaryRegisters(size_t count);
- void BorrowConsecutiveTemporaryRegister(int reg_index);
- bool TemporaryRegisterIsLive(Register reg) const;
-
- Register first_temporary_register() const;
- Register last_temporary_register() const;
+ // Set position for implicit return.
+ void SetReturnPosition(FunctionLiteral* fun);
// Gets a constant pool entry for the |object|.
size_t GetConstantPoolEntry(Handle<Object> object);
+ ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; }
+ const ZoneVector<uint8_t>* bytecodes() const { return &bytecodes_; }
+ Isolate* isolate() const { return isolate_; }
+ ConstantArrayBuilder* constant_array_builder() {
+ return &constant_array_builder_;
+ }
+ const ConstantArrayBuilder* constant_array_builder() const {
+ return &constant_array_builder_;
+ }
+ HandlerTableBuilder* handler_table_builder() {
+ return &handler_table_builder_;
+ }
+ SourcePositionTableBuilder* source_position_table_builder() {
+ return &source_position_table_builder_;
+ }
+ RegisterTranslator* register_translator() { return ®ister_translator_; }
+
Isolate* isolate_;
Zone* zone_;
ZoneVector<uint8_t> bytecodes_;
bool bytecode_generated_;
ConstantArrayBuilder constant_array_builder_;
+ HandlerTableBuilder handler_table_builder_;
+ SourcePositionTableBuilder source_position_table_builder_;
size_t last_block_end_;
size_t last_bytecode_start_;
bool exit_seen_in_block_;
int unbound_jumps_;
-
int parameter_count_;
int local_register_count_;
int context_register_count_;
- int temporary_register_count_;
- ZoneSet<int> free_temporaries_;
-
- class PreviousBytecodeHelper;
- friend class BytecodeRegisterAllocator;
+ TemporaryRegisterAllocator temporary_allocator_;
+ RegisterTranslator register_translator_;
DISALLOW_COPY_AND_ASSIGN(BytecodeArrayBuilder);
};