2016-12-05 13:03:07 +00:00
|
|
|
// Copyright 2015 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2019-05-24 13:51:59 +00:00
|
|
|
#include "src/init/v8.h"
|
2016-12-05 13:03:07 +00:00
|
|
|
|
|
|
|
#include "src/interpreter/bytecode-array-builder.h"
|
|
|
|
#include "src/interpreter/bytecode-array-random-iterator.h"
|
2019-05-24 13:51:59 +00:00
|
|
|
#include "src/numbers/hash-seed-inl.h"
|
2019-05-23 08:51:46 +00:00
|
|
|
#include "src/objects/objects-inl.h"
|
2018-11-03 00:13:22 +00:00
|
|
|
#include "src/objects/smi.h"
|
2017-12-13 12:19:44 +00:00
|
|
|
#include "test/unittests/interpreter/bytecode-utils.h"
|
2016-12-05 13:03:07 +00:00
|
|
|
#include "test/unittests/test-utils.h"
|
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
namespace interpreter {
|
|
|
|
|
|
|
|
class BytecodeArrayRandomIteratorTest : public TestWithIsolateAndZone {
|
|
|
|
public:
|
2018-09-13 09:22:50 +00:00
|
|
|
BytecodeArrayRandomIteratorTest() = default;
|
|
|
|
~BytecodeArrayRandomIteratorTest() override = default;
|
2016-12-05 13:03:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(BytecodeArrayRandomIteratorTest, InvalidBeforeStart) {
|
|
|
|
// Use a builder to create an array with containing multiple bytecodes
|
|
|
|
// with 0, 1 and 2 operands.
|
2017-10-19 15:12:42 +00:00
|
|
|
FeedbackVectorSpec feedback_spec(zone());
|
2017-11-15 14:36:57 +00:00
|
|
|
BytecodeArrayBuilder builder(zone(), 3, 3, &feedback_spec);
|
2017-02-10 17:22:45 +00:00
|
|
|
AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
|
2019-02-14 21:10:30 +00:00
|
|
|
HashSeed(isolate()));
|
2017-10-27 19:53:15 +00:00
|
|
|
double heap_num_0 = 2.718;
|
|
|
|
double heap_num_1 = 2.0 * Smi::kMaxValue;
|
2018-11-03 00:13:22 +00:00
|
|
|
Smi zero = Smi::zero();
|
|
|
|
Smi smi_0 = Smi::FromInt(64);
|
|
|
|
Smi smi_1 = Smi::FromInt(-65536);
|
2016-12-05 13:03:07 +00:00
|
|
|
Register reg_0(0);
|
|
|
|
Register reg_1(1);
|
2017-12-13 12:19:44 +00:00
|
|
|
RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
|
|
|
|
RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
|
2021-12-16 13:20:11 +00:00
|
|
|
Register param = Register::FromParameterIndex(2);
|
2017-02-10 17:22:45 +00:00
|
|
|
const AstRawString* name = ast_factory.GetOneByteString("abc");
|
2017-10-19 15:12:42 +00:00
|
|
|
uint32_t feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
|
2016-12-05 13:03:07 +00:00
|
|
|
|
|
|
|
builder.LoadLiteral(heap_num_0)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(heap_num_1)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(zero)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(smi_0)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(smi_1)
|
|
|
|
.StoreAccumulatorInRegister(reg_1)
|
|
|
|
.LoadAccumulatorWithRegister(reg_0)
|
|
|
|
.BinaryOperation(Token::Value::ADD, reg_0, 2)
|
|
|
|
.StoreAccumulatorInRegister(reg_1)
|
|
|
|
.LoadNamedProperty(reg_1, name, feedback_slot)
|
|
|
|
.BinaryOperation(Token::Value::ADD, reg_0, 3)
|
|
|
|
.StoreAccumulatorInRegister(param)
|
|
|
|
.CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
|
2017-09-01 10:49:06 +00:00
|
|
|
.ForInPrepare(triple, feedback_slot)
|
2016-12-05 13:03:07 +00:00
|
|
|
.CallRuntime(Runtime::kLoadIC_Miss, reg_0)
|
|
|
|
.Debugger()
|
|
|
|
.Return();
|
|
|
|
|
[offthread] Add an OffThreadIsolate
The Factory/OffThreadFactory allows us to cleanly separate object
construction behaviour between main-thread and off-thread in a
syntactically consistent way (so that methods templated on the factory
type can be made to work on both).
However, there are cases where we also have to access the Isolate, for
handle creation or exception throwing. So far we have been pushing more
and more "customization points" into the factories to allow these
factory-templated methods to dispatch on this isolate behaviour via
these factory methods. Unfortunately, this is an increasing layering
violation between Factory and Isolate, particularly around exception
handling.
Now, we introduce an OffThreadIsolate, analogous to Isolate in the same
way as OffThreadFactory is analogous to Factory. All methods which were
templated on Factory are now templated on Isolate, and methods which
used to take an Isolate, and which were recently changed to take a
templated Factory, are changed/reverted to take a templated Isolate.
OffThreadFactory gets an isolate() method to match Factory's.
Notably, FactoryHandle is changed to "HandleFor", where the template
argument can be either of the Isolate type or the Factory type (allowing
us to dispatch on both depending on what is available).
Bug: chromium:1011762
Change-Id: Id144176f7da534dd76f3d535ab2ade008b6845e3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2030909
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66101}
2020-02-04 10:50:53 +00:00
|
|
|
ast_factory.Internalize(isolate());
|
2016-12-05 13:03:07 +00:00
|
|
|
Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
|
|
|
|
BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
|
|
|
|
|
|
|
|
iterator.GoToStart();
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
ASSERT_FALSE(iterator.IsValid());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(BytecodeArrayRandomIteratorTest, InvalidAfterEnd) {
|
|
|
|
// Use a builder to create an array with containing multiple bytecodes
|
|
|
|
// with 0, 1 and 2 operands.
|
2017-10-19 15:12:42 +00:00
|
|
|
FeedbackVectorSpec feedback_spec(zone());
|
2017-11-15 14:36:57 +00:00
|
|
|
BytecodeArrayBuilder builder(zone(), 3, 3, &feedback_spec);
|
2017-02-10 17:22:45 +00:00
|
|
|
AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
|
2019-02-14 21:10:30 +00:00
|
|
|
HashSeed(isolate()));
|
2017-10-27 19:53:15 +00:00
|
|
|
double heap_num_0 = 2.718;
|
|
|
|
double heap_num_1 = 2.0 * Smi::kMaxValue;
|
2018-11-03 00:13:22 +00:00
|
|
|
Smi zero = Smi::zero();
|
|
|
|
Smi smi_0 = Smi::FromInt(64);
|
|
|
|
Smi smi_1 = Smi::FromInt(-65536);
|
2016-12-05 13:03:07 +00:00
|
|
|
Register reg_0(0);
|
|
|
|
Register reg_1(1);
|
2017-12-13 12:19:44 +00:00
|
|
|
RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
|
|
|
|
RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
|
2021-12-16 13:20:11 +00:00
|
|
|
Register param = Register::FromParameterIndex(2);
|
2017-02-10 17:22:45 +00:00
|
|
|
const AstRawString* name = ast_factory.GetOneByteString("abc");
|
2017-10-19 15:12:42 +00:00
|
|
|
uint32_t feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
|
2016-12-05 13:03:07 +00:00
|
|
|
|
|
|
|
builder.LoadLiteral(heap_num_0)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(heap_num_1)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(zero)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(smi_0)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(smi_1)
|
|
|
|
.StoreAccumulatorInRegister(reg_1)
|
|
|
|
.LoadAccumulatorWithRegister(reg_0)
|
|
|
|
.BinaryOperation(Token::Value::ADD, reg_0, 2)
|
|
|
|
.StoreAccumulatorInRegister(reg_1)
|
|
|
|
.LoadNamedProperty(reg_1, name, feedback_slot)
|
|
|
|
.BinaryOperation(Token::Value::ADD, reg_0, 3)
|
|
|
|
.StoreAccumulatorInRegister(param)
|
|
|
|
.CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
|
2017-09-01 10:49:06 +00:00
|
|
|
.ForInPrepare(triple, feedback_slot)
|
2016-12-05 13:03:07 +00:00
|
|
|
.CallRuntime(Runtime::kLoadIC_Miss, reg_0)
|
|
|
|
.Debugger()
|
|
|
|
.Return();
|
|
|
|
|
[offthread] Add an OffThreadIsolate
The Factory/OffThreadFactory allows us to cleanly separate object
construction behaviour between main-thread and off-thread in a
syntactically consistent way (so that methods templated on the factory
type can be made to work on both).
However, there are cases where we also have to access the Isolate, for
handle creation or exception throwing. So far we have been pushing more
and more "customization points" into the factories to allow these
factory-templated methods to dispatch on this isolate behaviour via
these factory methods. Unfortunately, this is an increasing layering
violation between Factory and Isolate, particularly around exception
handling.
Now, we introduce an OffThreadIsolate, analogous to Isolate in the same
way as OffThreadFactory is analogous to Factory. All methods which were
templated on Factory are now templated on Isolate, and methods which
used to take an Isolate, and which were recently changed to take a
templated Factory, are changed/reverted to take a templated Isolate.
OffThreadFactory gets an isolate() method to match Factory's.
Notably, FactoryHandle is changed to "HandleFor", where the template
argument can be either of the Isolate type or the Factory type (allowing
us to dispatch on both depending on what is available).
Bug: chromium:1011762
Change-Id: Id144176f7da534dd76f3d535ab2ade008b6845e3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2030909
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66101}
2020-02-04 10:50:53 +00:00
|
|
|
ast_factory.Internalize(isolate());
|
2016-12-05 13:03:07 +00:00
|
|
|
Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
|
|
|
|
BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
|
|
|
|
|
|
|
|
iterator.GoToEnd();
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
++iterator;
|
|
|
|
ASSERT_FALSE(iterator.IsValid());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(BytecodeArrayRandomIteratorTest, AccessesFirst) {
|
|
|
|
// Use a builder to create an array with containing multiple bytecodes
|
|
|
|
// with 0, 1 and 2 operands.
|
2017-10-19 15:12:42 +00:00
|
|
|
FeedbackVectorSpec feedback_spec(zone());
|
2017-11-15 14:36:57 +00:00
|
|
|
BytecodeArrayBuilder builder(zone(), 3, 3, &feedback_spec);
|
2017-02-10 17:22:45 +00:00
|
|
|
AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
|
2019-02-14 21:10:30 +00:00
|
|
|
HashSeed(isolate()));
|
2017-10-27 19:53:15 +00:00
|
|
|
double heap_num_0 = 2.718;
|
|
|
|
double heap_num_1 = 2.0 * Smi::kMaxValue;
|
2018-11-03 00:13:22 +00:00
|
|
|
Smi zero = Smi::zero();
|
|
|
|
Smi smi_0 = Smi::FromInt(64);
|
|
|
|
Smi smi_1 = Smi::FromInt(-65536);
|
2016-12-05 13:03:07 +00:00
|
|
|
Register reg_0(0);
|
|
|
|
Register reg_1(1);
|
2017-12-13 12:19:44 +00:00
|
|
|
RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
|
|
|
|
RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
|
2021-12-16 13:20:11 +00:00
|
|
|
Register param = Register::FromParameterIndex(2);
|
2017-02-10 17:22:45 +00:00
|
|
|
const AstRawString* name = ast_factory.GetOneByteString("abc");
|
2017-10-19 15:12:42 +00:00
|
|
|
uint32_t feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
|
2016-12-05 13:03:07 +00:00
|
|
|
|
|
|
|
builder.LoadLiteral(heap_num_0)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(heap_num_1)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(zero)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(smi_0)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(smi_1)
|
|
|
|
.StoreAccumulatorInRegister(reg_1)
|
|
|
|
.LoadAccumulatorWithRegister(reg_0)
|
|
|
|
.BinaryOperation(Token::Value::ADD, reg_0, 2)
|
|
|
|
.StoreAccumulatorInRegister(reg_1)
|
|
|
|
.LoadNamedProperty(reg_1, name, feedback_slot)
|
|
|
|
.BinaryOperation(Token::Value::ADD, reg_0, 3)
|
|
|
|
.StoreAccumulatorInRegister(param)
|
|
|
|
.CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
|
2017-09-01 10:49:06 +00:00
|
|
|
.ForInPrepare(triple, feedback_slot)
|
2016-12-05 13:03:07 +00:00
|
|
|
.CallRuntime(Runtime::kLoadIC_Miss, reg_0)
|
|
|
|
.Debugger()
|
|
|
|
.Return();
|
|
|
|
|
[offthread] Add an OffThreadIsolate
The Factory/OffThreadFactory allows us to cleanly separate object
construction behaviour between main-thread and off-thread in a
syntactically consistent way (so that methods templated on the factory
type can be made to work on both).
However, there are cases where we also have to access the Isolate, for
handle creation or exception throwing. So far we have been pushing more
and more "customization points" into the factories to allow these
factory-templated methods to dispatch on this isolate behaviour via
these factory methods. Unfortunately, this is an increasing layering
violation between Factory and Isolate, particularly around exception
handling.
Now, we introduce an OffThreadIsolate, analogous to Isolate in the same
way as OffThreadFactory is analogous to Factory. All methods which were
templated on Factory are now templated on Isolate, and methods which
used to take an Isolate, and which were recently changed to take a
templated Factory, are changed/reverted to take a templated Isolate.
OffThreadFactory gets an isolate() method to match Factory's.
Notably, FactoryHandle is changed to "HandleFor", where the template
argument can be either of the Isolate type or the Factory type (allowing
us to dispatch on both depending on what is available).
Bug: chromium:1011762
Change-Id: Id144176f7da534dd76f3d535ab2ade008b6845e3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2030909
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66101}
2020-02-04 10:50:53 +00:00
|
|
|
ast_factory.Internalize(isolate());
|
2016-12-05 13:03:07 +00:00
|
|
|
Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
|
|
|
|
BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
|
|
|
|
|
|
|
|
iterator.GoToStart();
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
|
|
|
|
EXPECT_EQ(iterator.current_index(), 0);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), 0);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
2019-06-17 15:25:41 +00:00
|
|
|
EXPECT_EQ(iterator.GetConstantForIndexOperand(0, isolate())->Number(),
|
|
|
|
heap_num_0);
|
2016-12-05 13:03:07 +00:00
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(BytecodeArrayRandomIteratorTest, AccessesLast) {
|
|
|
|
// Use a builder to create an array with containing multiple bytecodes
|
|
|
|
// with 0, 1 and 2 operands.
|
2017-10-19 15:12:42 +00:00
|
|
|
FeedbackVectorSpec feedback_spec(zone());
|
2017-11-15 14:36:57 +00:00
|
|
|
BytecodeArrayBuilder builder(zone(), 3, 3, &feedback_spec);
|
2017-02-10 17:22:45 +00:00
|
|
|
AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
|
2019-02-14 21:10:30 +00:00
|
|
|
HashSeed(isolate()));
|
2017-10-27 19:53:15 +00:00
|
|
|
double heap_num_0 = 2.718;
|
|
|
|
double heap_num_1 = 2.0 * Smi::kMaxValue;
|
2018-11-03 00:13:22 +00:00
|
|
|
Smi zero = Smi::zero();
|
|
|
|
Smi smi_0 = Smi::FromInt(64);
|
|
|
|
Smi smi_1 = Smi::FromInt(-65536);
|
2016-12-05 13:03:07 +00:00
|
|
|
Register reg_0(0);
|
|
|
|
Register reg_1(1);
|
2017-12-13 12:19:44 +00:00
|
|
|
RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
|
|
|
|
RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
|
2021-12-16 13:20:11 +00:00
|
|
|
Register param = Register::FromParameterIndex(2);
|
2017-02-10 17:22:45 +00:00
|
|
|
const AstRawString* name = ast_factory.GetOneByteString("abc");
|
2017-10-19 15:12:42 +00:00
|
|
|
uint32_t feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
|
2016-12-05 13:03:07 +00:00
|
|
|
|
|
|
|
builder.LoadLiteral(heap_num_0)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(heap_num_1)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(zero)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(smi_0)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(smi_1)
|
|
|
|
.StoreAccumulatorInRegister(reg_1)
|
|
|
|
.LoadAccumulatorWithRegister(reg_0)
|
|
|
|
.BinaryOperation(Token::Value::ADD, reg_0, 2)
|
|
|
|
.StoreAccumulatorInRegister(reg_1)
|
|
|
|
.LoadNamedProperty(reg_1, name, feedback_slot)
|
|
|
|
.BinaryOperation(Token::Value::ADD, reg_0, 3)
|
|
|
|
.StoreAccumulatorInRegister(param)
|
|
|
|
.CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
|
2017-09-01 10:49:06 +00:00
|
|
|
.ForInPrepare(triple, feedback_slot)
|
2016-12-05 13:03:07 +00:00
|
|
|
.CallRuntime(Runtime::kLoadIC_Miss, reg_0)
|
|
|
|
.Debugger()
|
|
|
|
.Return();
|
|
|
|
|
[offthread] Add an OffThreadIsolate
The Factory/OffThreadFactory allows us to cleanly separate object
construction behaviour between main-thread and off-thread in a
syntactically consistent way (so that methods templated on the factory
type can be made to work on both).
However, there are cases where we also have to access the Isolate, for
handle creation or exception throwing. So far we have been pushing more
and more "customization points" into the factories to allow these
factory-templated methods to dispatch on this isolate behaviour via
these factory methods. Unfortunately, this is an increasing layering
violation between Factory and Isolate, particularly around exception
handling.
Now, we introduce an OffThreadIsolate, analogous to Isolate in the same
way as OffThreadFactory is analogous to Factory. All methods which were
templated on Factory are now templated on Isolate, and methods which
used to take an Isolate, and which were recently changed to take a
templated Factory, are changed/reverted to take a templated Isolate.
OffThreadFactory gets an isolate() method to match Factory's.
Notably, FactoryHandle is changed to "HandleFor", where the template
argument can be either of the Isolate type or the Factory type (allowing
us to dispatch on both depending on what is available).
Bug: chromium:1011762
Change-Id: Id144176f7da534dd76f3d535ab2ade008b6845e3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2030909
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66101}
2020-02-04 10:50:53 +00:00
|
|
|
ast_factory.Internalize(isolate());
|
2016-12-05 13:03:07 +00:00
|
|
|
Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
|
|
|
|
BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
|
|
|
|
|
|
|
|
iterator.GoToEnd();
|
|
|
|
|
|
|
|
int offset = bytecodeArray->length() -
|
|
|
|
Bytecodes::Size(Bytecode::kReturn, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kReturn);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 20);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(BytecodeArrayRandomIteratorTest, RandomAccessValid) {
|
|
|
|
// Use a builder to create an array with containing multiple bytecodes
|
|
|
|
// with 0, 1 and 2 operands.
|
2017-10-19 15:12:42 +00:00
|
|
|
FeedbackVectorSpec feedback_spec(zone());
|
2021-02-17 14:36:58 +00:00
|
|
|
BytecodeArrayBuilder builder(zone(), 3, 17, &feedback_spec);
|
2017-02-10 17:22:45 +00:00
|
|
|
AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
|
2019-02-14 21:10:30 +00:00
|
|
|
HashSeed(isolate()));
|
2017-10-27 19:53:15 +00:00
|
|
|
double heap_num_0 = 2.718;
|
|
|
|
double heap_num_1 = 2.0 * Smi::kMaxValue;
|
2018-11-03 00:13:22 +00:00
|
|
|
Smi zero = Smi::zero();
|
|
|
|
Smi smi_0 = Smi::FromInt(64);
|
|
|
|
Smi smi_1 = Smi::FromInt(-65536);
|
2016-12-05 13:03:07 +00:00
|
|
|
Register reg_0(0);
|
2021-02-17 14:36:58 +00:00
|
|
|
Register reg_16(16); // Something not eligible for short Star.
|
2017-12-13 12:19:44 +00:00
|
|
|
RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
|
|
|
|
RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
|
2021-12-16 13:20:11 +00:00
|
|
|
Register param = Register::FromParameterIndex(2);
|
2017-02-10 17:22:45 +00:00
|
|
|
const AstRawString* name = ast_factory.GetOneByteString("abc");
|
2016-12-05 13:03:07 +00:00
|
|
|
uint32_t name_index = 2;
|
2017-10-19 15:12:42 +00:00
|
|
|
uint32_t feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
|
2016-12-05 13:03:07 +00:00
|
|
|
|
|
|
|
builder.LoadLiteral(heap_num_0)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(heap_num_1)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(zero)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(smi_0)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(smi_1)
|
2021-02-17 14:36:58 +00:00
|
|
|
.StoreAccumulatorInRegister(reg_16)
|
2016-12-05 13:03:07 +00:00
|
|
|
.LoadAccumulatorWithRegister(reg_0)
|
|
|
|
.BinaryOperation(Token::Value::ADD, reg_0, 2)
|
2021-02-17 14:36:58 +00:00
|
|
|
.StoreAccumulatorInRegister(reg_16)
|
|
|
|
.LoadNamedProperty(reg_16, name, feedback_slot)
|
2016-12-05 13:03:07 +00:00
|
|
|
.BinaryOperation(Token::Value::ADD, reg_0, 3)
|
|
|
|
.StoreAccumulatorInRegister(param)
|
|
|
|
.CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
|
2017-09-01 10:49:06 +00:00
|
|
|
.ForInPrepare(triple, feedback_slot)
|
2016-12-05 13:03:07 +00:00
|
|
|
.CallRuntime(Runtime::kLoadIC_Miss, reg_0)
|
|
|
|
.Debugger()
|
|
|
|
.Return();
|
|
|
|
|
|
|
|
// Test iterator sees the expected output from the builder.
|
[offthread] Add an OffThreadIsolate
The Factory/OffThreadFactory allows us to cleanly separate object
construction behaviour between main-thread and off-thread in a
syntactically consistent way (so that methods templated on the factory
type can be made to work on both).
However, there are cases where we also have to access the Isolate, for
handle creation or exception throwing. So far we have been pushing more
and more "customization points" into the factories to allow these
factory-templated methods to dispatch on this isolate behaviour via
these factory methods. Unfortunately, this is an increasing layering
violation between Factory and Isolate, particularly around exception
handling.
Now, we introduce an OffThreadIsolate, analogous to Isolate in the same
way as OffThreadFactory is analogous to Factory. All methods which were
templated on Factory are now templated on Isolate, and methods which
used to take an Isolate, and which were recently changed to take a
templated Factory, are changed/reverted to take a templated Isolate.
OffThreadFactory gets an isolate() method to match Factory's.
Notably, FactoryHandle is changed to "HandleFor", where the template
argument can be either of the Isolate type or the Factory type (allowing
us to dispatch on both depending on what is available).
Bug: chromium:1011762
Change-Id: Id144176f7da534dd76f3d535ab2ade008b6845e3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2030909
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66101}
2020-02-04 10:50:53 +00:00
|
|
|
ast_factory.Internalize(isolate());
|
2016-12-05 13:03:07 +00:00
|
|
|
BytecodeArrayRandomIterator iterator(builder.ToBytecodeArray(isolate()),
|
|
|
|
zone());
|
|
|
|
const int kPrefixByteSize = 1;
|
|
|
|
int offset = 0;
|
|
|
|
|
2020-03-20 14:28:41 +00:00
|
|
|
iterator.GoToIndex(11);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset = Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
|
|
|
|
kPrefixByteSize;
|
|
|
|
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 11);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
|
|
|
|
iterator.GoToIndex(2);
|
|
|
|
offset = Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
|
|
|
|
EXPECT_EQ(iterator.current_index(), 2);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
2019-06-17 15:25:41 +00:00
|
|
|
EXPECT_EQ(iterator.GetConstantForIndexOperand(0, isolate())->Number(),
|
|
|
|
heap_num_1);
|
2016-12-05 13:03:07 +00:00
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
|
2020-03-20 14:28:41 +00:00
|
|
|
iterator.GoToIndex(16);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset = Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
|
|
|
|
kPrefixByteSize;
|
|
|
|
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntimeForPair);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 16);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadLookupSlotForCall);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(1).index(), param.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(1), 1);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterCountOperand(2), 1u);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(3).index(), reg_0.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(3), 2);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
|
|
|
|
iterator -= 3;
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaNamedProperty);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 13);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_16.index());
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.GetIndexOperand(1), name_index);
|
|
|
|
EXPECT_EQ(iterator.GetIndexOperand(2), feedback_slot);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
|
|
|
|
iterator += 2;
|
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 15);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), param.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
|
2020-03-20 14:28:41 +00:00
|
|
|
iterator.GoToIndex(20);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset = Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
|
|
|
|
kPrefixByteSize;
|
|
|
|
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
|
|
|
|
offset +=
|
|
|
|
Bytecodes::Size(Bytecode::kCallRuntimeForPair, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kForInPrepare, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kCallRuntime, OperandScale::kSingle);
|
|
|
|
offset += Bytecodes::Size(Bytecode::kDebugger, OperandScale::kSingle);
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kReturn);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 20);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
|
2020-03-20 14:28:41 +00:00
|
|
|
iterator.GoToIndex(22);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_FALSE(iterator.IsValid());
|
|
|
|
|
|
|
|
iterator.GoToIndex(-5);
|
|
|
|
EXPECT_FALSE(iterator.IsValid());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
|
|
|
|
// Use a builder to create an array with containing multiple bytecodes
|
|
|
|
// with 0, 1 and 2 operands.
|
2017-10-19 15:12:42 +00:00
|
|
|
FeedbackVectorSpec feedback_spec(zone());
|
2021-02-17 14:36:58 +00:00
|
|
|
BytecodeArrayBuilder builder(zone(), 3, 17, &feedback_spec);
|
2017-02-10 17:22:45 +00:00
|
|
|
AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
|
2019-02-14 21:10:30 +00:00
|
|
|
HashSeed(isolate()));
|
2017-10-27 19:53:15 +00:00
|
|
|
double heap_num_0 = 2.718;
|
|
|
|
double heap_num_1 = 2.0 * Smi::kMaxValue;
|
2018-11-03 00:13:22 +00:00
|
|
|
Smi zero = Smi::zero();
|
|
|
|
Smi smi_0 = Smi::FromInt(64);
|
|
|
|
Smi smi_1 = Smi::FromInt(-65536);
|
2016-12-05 13:03:07 +00:00
|
|
|
Register reg_0(0);
|
2021-02-17 14:36:58 +00:00
|
|
|
Register reg_16(16); // Something not eligible for short Star.
|
2017-12-13 12:19:44 +00:00
|
|
|
RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
|
|
|
|
RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
|
2021-12-16 13:20:11 +00:00
|
|
|
Register param = Register::FromParameterIndex(2);
|
2017-02-10 17:22:45 +00:00
|
|
|
const AstRawString* name = ast_factory.GetOneByteString("abc");
|
2016-12-05 13:03:07 +00:00
|
|
|
uint32_t name_index = 2;
|
2017-10-19 15:12:42 +00:00
|
|
|
uint32_t feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
|
2016-12-05 13:03:07 +00:00
|
|
|
|
|
|
|
builder.LoadLiteral(heap_num_0)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(heap_num_1)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(zero)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(smi_0)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(smi_1)
|
2021-02-17 14:36:58 +00:00
|
|
|
.StoreAccumulatorInRegister(reg_16)
|
2016-12-05 13:03:07 +00:00
|
|
|
.LoadAccumulatorWithRegister(reg_0)
|
|
|
|
.BinaryOperation(Token::Value::ADD, reg_0, 2)
|
2021-02-17 14:36:58 +00:00
|
|
|
.StoreAccumulatorInRegister(reg_16)
|
|
|
|
.LoadNamedProperty(reg_16, name, feedback_slot)
|
2016-12-05 13:03:07 +00:00
|
|
|
.BinaryOperation(Token::Value::ADD, reg_0, 3)
|
|
|
|
.StoreAccumulatorInRegister(param)
|
|
|
|
.CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
|
2017-09-01 10:49:06 +00:00
|
|
|
.ForInPrepare(triple, feedback_slot)
|
2016-12-05 13:03:07 +00:00
|
|
|
.CallRuntime(Runtime::kLoadIC_Miss, reg_0)
|
|
|
|
.Debugger()
|
|
|
|
.Return();
|
|
|
|
|
|
|
|
// Test iterator sees the expected output from the builder.
|
[offthread] Add an OffThreadIsolate
The Factory/OffThreadFactory allows us to cleanly separate object
construction behaviour between main-thread and off-thread in a
syntactically consistent way (so that methods templated on the factory
type can be made to work on both).
However, there are cases where we also have to access the Isolate, for
handle creation or exception throwing. So far we have been pushing more
and more "customization points" into the factories to allow these
factory-templated methods to dispatch on this isolate behaviour via
these factory methods. Unfortunately, this is an increasing layering
violation between Factory and Isolate, particularly around exception
handling.
Now, we introduce an OffThreadIsolate, analogous to Isolate in the same
way as OffThreadFactory is analogous to Factory. All methods which were
templated on Factory are now templated on Isolate, and methods which
used to take an Isolate, and which were recently changed to take a
templated Factory, are changed/reverted to take a templated Isolate.
OffThreadFactory gets an isolate() method to match Factory's.
Notably, FactoryHandle is changed to "HandleFor", where the template
argument can be either of the Isolate type or the Factory type (allowing
us to dispatch on both depending on what is available).
Bug: chromium:1011762
Change-Id: Id144176f7da534dd76f3d535ab2ade008b6845e3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2030909
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66101}
2020-02-04 10:50:53 +00:00
|
|
|
ast_factory.Internalize(isolate());
|
2016-12-05 13:03:07 +00:00
|
|
|
BytecodeArrayRandomIterator iterator(builder.ToBytecodeArray(isolate()),
|
|
|
|
zone());
|
|
|
|
const int kPrefixByteSize = 1;
|
|
|
|
int offset = 0;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
|
|
|
|
EXPECT_EQ(iterator.current_index(), 0);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
2019-06-17 15:25:41 +00:00
|
|
|
EXPECT_EQ(iterator.GetConstantForIndexOperand(0, isolate())->Number(),
|
|
|
|
heap_num_0);
|
2016-12-05 13:03:07 +00:00
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
2021-02-17 14:36:58 +00:00
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar0);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 1);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
|
|
|
|
EXPECT_EQ(iterator.current_index(), 2);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
2019-06-17 15:25:41 +00:00
|
|
|
EXPECT_EQ(iterator.GetConstantForIndexOperand(0, isolate())->Number(),
|
|
|
|
heap_num_1);
|
2016-12-05 13:03:07 +00:00
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
2021-02-17 14:36:58 +00:00
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar0);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 3);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaZero);
|
|
|
|
EXPECT_EQ(iterator.current_index(), 4);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
2021-02-17 14:36:58 +00:00
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar0);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 5);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
|
|
|
|
EXPECT_EQ(iterator.current_index(), 6);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_0);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
2021-02-17 14:36:58 +00:00
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar0);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 7);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
2021-02-17 14:36:58 +00:00
|
|
|
offset += Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
2016-12-05 13:03:07 +00:00
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 8);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple);
|
|
|
|
EXPECT_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_1);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
|
|
|
|
kPrefixByteSize;
|
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 9);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_16.index());
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdar);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 10);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 11);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 12);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_16.index());
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaNamedProperty);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 13);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_16.index());
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.GetIndexOperand(1), name_index);
|
|
|
|
EXPECT_EQ(iterator.GetIndexOperand(2), feedback_slot);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 14);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 15);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), param.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntimeForPair);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 16);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadLookupSlotForCall);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(1).index(), param.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(1), 1);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterCountOperand(2), 1u);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(3).index(), reg_0.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(3), 2);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset +=
|
|
|
|
Bytecodes::Size(Bytecode::kCallRuntimeForPair, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kForInPrepare);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 17);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
|
2017-09-01 10:49:06 +00:00
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 3);
|
|
|
|
EXPECT_EQ(iterator.GetIndexOperand(1), feedback_slot);
|
2016-12-05 13:03:07 +00:00
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kForInPrepare, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntime);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 18);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadIC_Miss);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(1).index(), reg_0.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterCountOperand(2), 1u);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kCallRuntime, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 19);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
offset += Bytecodes::Size(Bytecode::kDebugger, OperandScale::kSingle);
|
|
|
|
++iterator;
|
|
|
|
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kReturn);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 20);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
++iterator;
|
|
|
|
ASSERT_TRUE(!iterator.IsValid());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
|
|
|
|
// Use a builder to create an array with containing multiple bytecodes
|
|
|
|
// with 0, 1 and 2 operands.
|
2017-10-19 15:12:42 +00:00
|
|
|
FeedbackVectorSpec feedback_spec(zone());
|
2021-02-17 14:36:58 +00:00
|
|
|
BytecodeArrayBuilder builder(zone(), 3, 17, &feedback_spec);
|
2017-02-10 17:22:45 +00:00
|
|
|
AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
|
2019-02-14 21:10:30 +00:00
|
|
|
HashSeed(isolate()));
|
2017-10-27 19:53:15 +00:00
|
|
|
double heap_num_0 = 2.718;
|
|
|
|
double heap_num_1 = 2.0 * Smi::kMaxValue;
|
2018-11-03 00:13:22 +00:00
|
|
|
Smi zero = Smi::zero();
|
|
|
|
Smi smi_0 = Smi::FromInt(64);
|
|
|
|
Smi smi_1 = Smi::FromInt(-65536);
|
2016-12-05 13:03:07 +00:00
|
|
|
Register reg_0(0);
|
2021-02-17 14:36:58 +00:00
|
|
|
Register reg_16(16); // Something not eligible for short Star.
|
2017-12-13 12:19:44 +00:00
|
|
|
RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
|
|
|
|
RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
|
2021-12-16 13:20:11 +00:00
|
|
|
Register param = Register::FromParameterIndex(2);
|
2017-02-10 17:22:45 +00:00
|
|
|
const AstRawString* name = ast_factory.GetOneByteString("abc");
|
2016-12-05 13:03:07 +00:00
|
|
|
uint32_t name_index = 2;
|
2017-10-19 15:12:42 +00:00
|
|
|
uint32_t feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
|
2016-12-05 13:03:07 +00:00
|
|
|
|
|
|
|
builder.LoadLiteral(heap_num_0)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(heap_num_1)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(zero)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(smi_0)
|
|
|
|
.StoreAccumulatorInRegister(reg_0)
|
|
|
|
.LoadLiteral(smi_1)
|
2021-02-17 14:36:58 +00:00
|
|
|
.StoreAccumulatorInRegister(reg_16)
|
2016-12-05 13:03:07 +00:00
|
|
|
.LoadAccumulatorWithRegister(reg_0)
|
|
|
|
.BinaryOperation(Token::Value::ADD, reg_0, 2)
|
2021-02-17 14:36:58 +00:00
|
|
|
.StoreAccumulatorInRegister(reg_16)
|
|
|
|
.LoadNamedProperty(reg_16, name, feedback_slot)
|
2016-12-05 13:03:07 +00:00
|
|
|
.BinaryOperation(Token::Value::ADD, reg_0, 3)
|
|
|
|
.StoreAccumulatorInRegister(param)
|
|
|
|
.CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
|
2017-09-01 10:49:06 +00:00
|
|
|
.ForInPrepare(triple, feedback_slot)
|
2016-12-05 13:03:07 +00:00
|
|
|
.CallRuntime(Runtime::kLoadIC_Miss, reg_0)
|
|
|
|
.Debugger()
|
|
|
|
.Return();
|
|
|
|
|
|
|
|
// Test iterator sees the expected output from the builder.
|
[offthread] Add an OffThreadIsolate
The Factory/OffThreadFactory allows us to cleanly separate object
construction behaviour between main-thread and off-thread in a
syntactically consistent way (so that methods templated on the factory
type can be made to work on both).
However, there are cases where we also have to access the Isolate, for
handle creation or exception throwing. So far we have been pushing more
and more "customization points" into the factories to allow these
factory-templated methods to dispatch on this isolate behaviour via
these factory methods. Unfortunately, this is an increasing layering
violation between Factory and Isolate, particularly around exception
handling.
Now, we introduce an OffThreadIsolate, analogous to Isolate in the same
way as OffThreadFactory is analogous to Factory. All methods which were
templated on Factory are now templated on Isolate, and methods which
used to take an Isolate, and which were recently changed to take a
templated Factory, are changed/reverted to take a templated Isolate.
OffThreadFactory gets an isolate() method to match Factory's.
Notably, FactoryHandle is changed to "HandleFor", where the template
argument can be either of the Isolate type or the Factory type (allowing
us to dispatch on both depending on what is available).
Bug: chromium:1011762
Change-Id: Id144176f7da534dd76f3d535ab2ade008b6845e3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2030909
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66101}
2020-02-04 10:50:53 +00:00
|
|
|
ast_factory.Internalize(isolate());
|
2016-12-05 13:03:07 +00:00
|
|
|
Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
|
|
|
|
BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
|
|
|
|
const int kPrefixByteSize = 1;
|
|
|
|
int offset = bytecodeArray->length();
|
|
|
|
|
|
|
|
iterator.GoToEnd();
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kReturn, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kReturn);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 20);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kDebugger, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 19);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kCallRuntime, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntime);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 18);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadIC_Miss);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(1).index(), reg_0.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterCountOperand(2), 1u);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kForInPrepare, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kForInPrepare);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 17);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
|
2017-09-01 10:49:06 +00:00
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 3);
|
|
|
|
EXPECT_EQ(iterator.GetIndexOperand(1), feedback_slot);
|
2016-12-05 13:03:07 +00:00
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -=
|
|
|
|
Bytecodes::Size(Bytecode::kCallRuntimeForPair, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntimeForPair);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 16);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadLookupSlotForCall);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(1).index(), param.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(1), 1);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterCountOperand(2), 1u);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(3).index(), reg_0.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(3), 2);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 15);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), param.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 14);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaNamedProperty);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 13);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_16.index());
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.GetIndexOperand(1), name_index);
|
|
|
|
EXPECT_EQ(iterator.GetIndexOperand(2), feedback_slot);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 12);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_16.index());
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 11);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdar);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 10);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 9);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
2021-02-17 14:36:58 +00:00
|
|
|
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_16.index());
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
|
|
|
|
kPrefixByteSize;
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 8);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple);
|
|
|
|
EXPECT_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_1);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
2021-02-17 14:36:58 +00:00
|
|
|
offset -= Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar0);
|
2020-03-20 14:28:41 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 7);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
|
|
|
|
EXPECT_EQ(iterator.current_index(), 6);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_0);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
2021-02-17 14:36:58 +00:00
|
|
|
offset -= Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar0);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 5);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaZero);
|
|
|
|
EXPECT_EQ(iterator.current_index(), 4);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
2021-02-17 14:36:58 +00:00
|
|
|
offset -= Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar0);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 3);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
|
|
|
|
EXPECT_EQ(iterator.current_index(), 2);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
2019-06-17 15:25:41 +00:00
|
|
|
EXPECT_EQ(iterator.GetConstantForIndexOperand(0, isolate())->Number(),
|
|
|
|
heap_num_1);
|
2016-12-05 13:03:07 +00:00
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
2021-02-17 14:36:58 +00:00
|
|
|
offset -= Bytecodes::Size(Bytecode::kStar0, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar0);
|
2016-12-05 13:03:07 +00:00
|
|
|
EXPECT_EQ(iterator.current_index(), 1);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
|
|
|
|
offset -= Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
|
|
|
|
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
|
|
|
|
EXPECT_EQ(iterator.current_index(), 0);
|
|
|
|
EXPECT_EQ(iterator.current_offset(), offset);
|
|
|
|
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
|
2019-06-17 15:25:41 +00:00
|
|
|
EXPECT_EQ(iterator.GetConstantForIndexOperand(0, isolate())->Number(),
|
|
|
|
heap_num_0);
|
2016-12-05 13:03:07 +00:00
|
|
|
ASSERT_TRUE(iterator.IsValid());
|
|
|
|
--iterator;
|
|
|
|
ASSERT_FALSE(iterator.IsValid());
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace interpreter
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|