Revert of Collect type profile for DevTools. (patchset #40 id:750001 of https://codereview.chromium.org/2707873002/ )
Reason for revert: gcc bot is now flaky https://build.chromium.org/p/client.v8/builders/V8%20Linux%20gcc%204.8/builds/11863 Original issue's description: > Collect type profile for DevTools > > Collect type information for JavaScript variables and display it > in Chrome DevTools. > Design Doc: https://docs.google.com/a/google.com/document/d/1O1uepXZXBI6IwiawTrYC3ohhiNgzkyTdjn3R8ysbYgk/edit?usp=sharing > > When debugging JavaScript, it’s helpful to know the type of > a variable, parameter, and return values. JavaScript is > dynamically typed, and for complex > source code it’s often hard to infer types. With type profiling, we > can provide type information to JavaScript developers. > > This CL is a proof of concept. It collects type profile for > assignments and simply prints the types to stdout. > > The output looks something like this: > > #my_var1 > #Object > #number > #string > #number > #undefined > #string > #Object > #Object > > > We use an extra slot in the feedback vector of assignments to > carry the list of types for that assignment. The extra slot is > only added when the flag --type-profile is given. > > > Missing work: > * Collect data for parameters and return values (currently only assignments). > * Remove duplicates from the list of collected types and use a common base class. > * Add line numbers or source position instead of the variable name. > > > > BUG=v8:5935 > > Review-Url: https://codereview.chromium.org/2707873002 > Cr-Original-Commit-Position: refs/heads/master@{#43791} > Committed:0332bebde9
> Review-Url: https://codereview.chromium.org/2707873002 > Cr-Commit-Position: refs/heads/master@{#43804} > Committed:6cf880f4b8
TBR=yangguo@chromium.org,mvstanton@chromium.org,rmcilroy@chromium.org,mstarzinger@chromium.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=v8:5935 Review-Url: https://codereview.chromium.org/2754573002 Cr-Commit-Position: refs/heads/master@{#43805}
This commit is contained in:
parent
6cf880f4b8
commit
14d0930d40
@ -15,8 +15,7 @@ namespace internal {
|
||||
class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> {
|
||||
public:
|
||||
AstNumberingVisitor(uintptr_t stack_limit, Zone* zone,
|
||||
Compiler::EagerInnerFunctionLiterals* eager_literals,
|
||||
bool collect_type_profile = false)
|
||||
Compiler::EagerInnerFunctionLiterals* eager_literals)
|
||||
: zone_(zone),
|
||||
eager_literals_(eager_literals),
|
||||
next_id_(BailoutId::FirstUsable().ToInt()),
|
||||
@ -26,8 +25,7 @@ class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> {
|
||||
slot_cache_(zone),
|
||||
disable_crankshaft_reason_(kNoReason),
|
||||
dont_optimize_reason_(kNoReason),
|
||||
catch_prediction_(HandlerTable::UNCAUGHT),
|
||||
collect_type_profile_(collect_type_profile) {
|
||||
catch_prediction_(HandlerTable::UNCAUGHT) {
|
||||
InitializeAstVisitor(stack_limit);
|
||||
}
|
||||
|
||||
@ -103,7 +101,6 @@ class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> {
|
||||
BailoutReason disable_crankshaft_reason_;
|
||||
BailoutReason dont_optimize_reason_;
|
||||
HandlerTable::CatchPrediction catch_prediction_;
|
||||
bool collect_type_profile_;
|
||||
|
||||
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
|
||||
DISALLOW_COPY_AND_ASSIGN(AstNumberingVisitor);
|
||||
@ -425,8 +422,7 @@ void AstNumberingVisitor::VisitAssignment(Assignment* node) {
|
||||
if (node->is_compound()) VisitBinaryOperation(node->binary_operation());
|
||||
VisitReference(node->target());
|
||||
Visit(node->value());
|
||||
node->AssignFeedbackSlots(properties_.get_spec(), language_mode_,
|
||||
&slot_cache_, collect_type_profile_);
|
||||
ReserveFeedbackSlots(node);
|
||||
}
|
||||
|
||||
|
||||
@ -718,14 +714,12 @@ bool AstNumberingVisitor::Renumber(FunctionLiteral* node) {
|
||||
|
||||
bool AstNumbering::Renumber(
|
||||
uintptr_t stack_limit, Zone* zone, FunctionLiteral* function,
|
||||
Compiler::EagerInnerFunctionLiterals* eager_literals,
|
||||
bool collect_type_profile) {
|
||||
Compiler::EagerInnerFunctionLiterals* eager_literals) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
DisallowHandleAllocation no_handles;
|
||||
DisallowHandleDereference no_deref;
|
||||
|
||||
AstNumberingVisitor visitor(stack_limit, zone, eager_literals,
|
||||
collect_type_profile);
|
||||
AstNumberingVisitor visitor(stack_limit, zone, eager_literals);
|
||||
return visitor.Renumber(function);
|
||||
}
|
||||
} // namespace internal
|
||||
|
@ -27,8 +27,7 @@ namespace AstNumbering {
|
||||
// non-null, adds any eager inner literal functions into it.
|
||||
bool Renumber(
|
||||
uintptr_t stack_limit, Zone* zone, FunctionLiteral* function,
|
||||
ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* eager_literals,
|
||||
bool collect_type_profile = false);
|
||||
ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* eager_literals);
|
||||
}
|
||||
|
||||
// Some details on yield IDs
|
||||
|
@ -283,13 +283,8 @@ Assignment::Assignment(Token::Value op, Expression* target, Expression* value,
|
||||
|
||||
void Assignment::AssignFeedbackSlots(FeedbackVectorSpec* spec,
|
||||
LanguageMode language_mode,
|
||||
FeedbackSlotCache* cache,
|
||||
bool collect_type_profile) {
|
||||
FeedbackSlotCache* cache) {
|
||||
AssignVectorSlots(target(), spec, language_mode, &slot_);
|
||||
|
||||
if (collect_type_profile) {
|
||||
type_profile_slot_ = spec->AddTypeProfileSlot();
|
||||
}
|
||||
}
|
||||
|
||||
void CountOperation::AssignFeedbackSlots(FeedbackVectorSpec* spec,
|
||||
|
@ -2414,17 +2414,9 @@ class Assignment final : public Expression {
|
||||
}
|
||||
|
||||
void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
|
||||
FeedbackSlotCache* cache,
|
||||
bool collect_type_profile = false);
|
||||
FeedbackSlotCache* cache);
|
||||
FeedbackSlot AssignmentSlot() const { return slot_; }
|
||||
|
||||
FeedbackSlot TypeProfileSlot() const {
|
||||
DCHECK(HasTypeProfileSlot());
|
||||
return type_profile_slot_;
|
||||
}
|
||||
|
||||
bool HasTypeProfileSlot() const { return !type_profile_slot_.IsInvalid(); }
|
||||
|
||||
private:
|
||||
friend class AstNodeFactory;
|
||||
|
||||
@ -2446,8 +2438,6 @@ class Assignment final : public Expression {
|
||||
Expression* value_;
|
||||
BinaryOperation* binary_operation_;
|
||||
SmallMapList receiver_types_;
|
||||
|
||||
FeedbackSlot type_profile_slot_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -478,23 +478,9 @@ bool Renumber(ParseInfo* parse_info,
|
||||
Compiler::EagerInnerFunctionLiterals* eager_literals) {
|
||||
RuntimeCallTimerScope runtimeTimer(parse_info->isolate(),
|
||||
&RuntimeCallStats::CompileRenumber);
|
||||
|
||||
// CollectTypeProfile uses its own feedback slots. If we have existing
|
||||
// FeedbackMetadata, we can only collect type profile, if the feedback vector
|
||||
// has the appropriate slots.
|
||||
bool collect_type_profile;
|
||||
if (parse_info->shared_info().is_null() ||
|
||||
parse_info->shared_info()->feedback_metadata()->length() == 0) {
|
||||
collect_type_profile = FLAG_type_profile;
|
||||
} else {
|
||||
collect_type_profile =
|
||||
parse_info->shared_info()->feedback_metadata()->HasTypeProfileSlot();
|
||||
}
|
||||
|
||||
if (!AstNumbering::Renumber(
|
||||
parse_info->isolate()->stack_guard()->real_climit(),
|
||||
parse_info->zone(), parse_info->literal(), eager_literals,
|
||||
collect_type_profile)) {
|
||||
parse_info->zone(), parse_info->literal(), eager_literals)) {
|
||||
return false;
|
||||
}
|
||||
if (!parse_info->shared_info().is_null()) {
|
||||
|
@ -802,22 +802,6 @@ void BytecodeGraphBuilder::VisitStaDataPropertyInLiteral() {
|
||||
environment()->RecordAfterState(node, Environment::kAttachFrameState);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitCollectTypeProfile() {
|
||||
PrepareEagerCheckpoint();
|
||||
|
||||
Node* name =
|
||||
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
||||
Node* value = environment()->LookupAccumulator();
|
||||
Node* index = jsgraph()->Constant(bytecode_iterator().GetIndexOperand(1));
|
||||
|
||||
Node* vector = jsgraph()->Constant(feedback_vector());
|
||||
|
||||
const Operator* op = javascript()->CallRuntime(Runtime::kCollectTypeProfile);
|
||||
|
||||
Node* node = NewNode(op, name, value, vector, index);
|
||||
environment()->RecordAfterState(node, Environment::kAttachFrameState);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitLdaContextSlot() {
|
||||
const Operator* op = javascript()->LoadContext(
|
||||
bytecode_iterator().GetUnsignedImmediateOperand(2),
|
||||
|
@ -54,7 +54,6 @@ int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) {
|
||||
case FeedbackSlotKind::kToBoolean:
|
||||
case FeedbackSlotKind::kLiteral:
|
||||
case FeedbackSlotKind::kCreateClosure:
|
||||
case FeedbackSlotKind::kTypeProfile:
|
||||
return 1;
|
||||
|
||||
case FeedbackSlotKind::kCall:
|
||||
@ -187,8 +186,7 @@ void FeedbackVector::ComputeCounts(int* with_type_info, int* generic,
|
||||
case FeedbackSlotKind::kStoreOwnNamed:
|
||||
case FeedbackSlotKind::kStoreKeyedSloppy:
|
||||
case FeedbackSlotKind::kStoreKeyedStrict:
|
||||
case FeedbackSlotKind::kStoreDataPropertyInLiteral:
|
||||
case FeedbackSlotKind::kTypeProfile: {
|
||||
case FeedbackSlotKind::kStoreDataPropertyInLiteral: {
|
||||
if (obj->IsWeakCell() || obj->IsFixedArray() || obj->IsString()) {
|
||||
with++;
|
||||
} else if (obj == megamorphic_sentinel) {
|
||||
|
@ -149,8 +149,6 @@ const char* FeedbackMetadata::Kind2String(FeedbackSlotKind kind) {
|
||||
return "kCreateClosure";
|
||||
case FeedbackSlotKind::kLiteral:
|
||||
return "LITERAL";
|
||||
case FeedbackSlotKind::kTypeProfile:
|
||||
return "TYPE_PROFILE";
|
||||
case FeedbackSlotKind::kGeneral:
|
||||
return "STUB";
|
||||
case FeedbackSlotKind::kKindsNumber:
|
||||
@ -160,18 +158,6 @@ const char* FeedbackMetadata::Kind2String(FeedbackSlotKind kind) {
|
||||
return "?";
|
||||
}
|
||||
|
||||
bool FeedbackMetadata::HasTypeProfileSlot() {
|
||||
FeedbackMetadataIterator iter(this);
|
||||
while (iter.HasNext()) {
|
||||
iter.Next();
|
||||
FeedbackSlotKind kind = iter.kind();
|
||||
if (kind == FeedbackSlotKind::kTypeProfile) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FeedbackSlotKind FeedbackVector::GetKind(FeedbackSlot slot) const {
|
||||
DCHECK(!is_empty());
|
||||
return metadata()->GetKind(slot);
|
||||
@ -233,7 +219,6 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate,
|
||||
case FeedbackSlotKind::kStoreKeyedStrict:
|
||||
case FeedbackSlotKind::kStoreDataPropertyInLiteral:
|
||||
case FeedbackSlotKind::kGeneral:
|
||||
case FeedbackSlotKind::kTypeProfile:
|
||||
array->set(index, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
|
||||
break;
|
||||
|
||||
@ -351,8 +336,7 @@ void FeedbackVector::ClearSlots(JSFunction* host_function) {
|
||||
break;
|
||||
}
|
||||
case FeedbackSlotKind::kCreateClosure: {
|
||||
case FeedbackSlotKind::kTypeProfile:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
case FeedbackSlotKind::kGeneral: {
|
||||
if (obj->IsHeapObject()) {
|
||||
@ -1039,49 +1023,5 @@ void StoreDataPropertyInLiteralICNexus::ConfigureMonomorphic(
|
||||
SetFeedbackExtra(*name);
|
||||
}
|
||||
|
||||
InlineCacheState CollectTypeProfileNexus::StateFromFeedback() const {
|
||||
Isolate* isolate = GetIsolate();
|
||||
Object* const feedback = GetFeedback();
|
||||
|
||||
if (feedback == *FeedbackVector::UninitializedSentinel(isolate)) {
|
||||
return UNINITIALIZED;
|
||||
}
|
||||
return MONOMORPHIC;
|
||||
}
|
||||
|
||||
void CollectTypeProfileNexus::Collect(Handle<Name> type) {
|
||||
Isolate* isolate = GetIsolate();
|
||||
|
||||
Object* const feedback = GetFeedback();
|
||||
Handle<ArrayList> types;
|
||||
|
||||
if (feedback == *FeedbackVector::UninitializedSentinel(isolate)) {
|
||||
types = ArrayList::New(isolate, 1);
|
||||
} else {
|
||||
types = Handle<ArrayList>(ArrayList::cast(feedback), isolate);
|
||||
}
|
||||
// TODO(franzih): Somehow sort this list. Either avoid duplicates
|
||||
// or use the common base type.
|
||||
SetFeedback(*ArrayList::Add(types, type));
|
||||
}
|
||||
|
||||
void CollectTypeProfileNexus::Print() const {
|
||||
Isolate* isolate = GetIsolate();
|
||||
|
||||
Object* const feedback = GetFeedback();
|
||||
|
||||
if (feedback == *FeedbackVector::UninitializedSentinel(isolate)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Handle<ArrayList> list;
|
||||
list = Handle<ArrayList>(ArrayList::cast(feedback), isolate);
|
||||
|
||||
for (int i = 0; i < list->Length(); i++) {
|
||||
String* name = String::cast(list->Get(i));
|
||||
PrintF("%s\n", name->ToCString().get());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -36,7 +36,6 @@ enum class FeedbackSlotKind {
|
||||
kCompareOp,
|
||||
kToBoolean,
|
||||
kStoreDataPropertyInLiteral,
|
||||
kTypeProfile,
|
||||
kCreateClosure,
|
||||
kLiteral,
|
||||
// This is a general purpose slot that occupies one feedback vector element.
|
||||
@ -151,11 +150,6 @@ class FeedbackVectorSpecBase {
|
||||
return AddSlot(FeedbackSlotKind::kStoreDataPropertyInLiteral);
|
||||
}
|
||||
|
||||
FeedbackSlot AddTypeProfileSlot() {
|
||||
DCHECK(FLAG_type_profile);
|
||||
return AddSlot(FeedbackSlotKind::kTypeProfile);
|
||||
}
|
||||
|
||||
#ifdef OBJECT_PRINT
|
||||
// For gdb debugging.
|
||||
void Print();
|
||||
@ -256,8 +250,6 @@ class FeedbackMetadata : public FixedArray {
|
||||
|
||||
static const char* Kind2String(FeedbackSlotKind kind);
|
||||
|
||||
bool HasTypeProfileSlot();
|
||||
|
||||
private:
|
||||
static const int kFeedbackSlotKindBits = 5;
|
||||
STATIC_ASSERT(static_cast<int>(FeedbackSlotKind::kKindsNumber) <
|
||||
@ -750,30 +742,6 @@ class StoreDataPropertyInLiteralICNexus : public FeedbackNexus {
|
||||
InlineCacheState StateFromFeedback() const override;
|
||||
};
|
||||
|
||||
// For each assignment, store the type of the value in the collection of types
|
||||
// in the feedback vector.
|
||||
class CollectTypeProfileNexus : public FeedbackNexus {
|
||||
public:
|
||||
CollectTypeProfileNexus(Handle<FeedbackVector> vector, FeedbackSlot slot)
|
||||
: FeedbackNexus(vector, slot) {
|
||||
DCHECK_EQ(FeedbackSlotKind::kTypeProfile, vector->GetKind(slot));
|
||||
}
|
||||
CollectTypeProfileNexus(FeedbackVector* vector, FeedbackSlot slot)
|
||||
: FeedbackNexus(vector, slot) {
|
||||
DCHECK_EQ(FeedbackSlotKind::kTypeProfile, vector->GetKind(slot));
|
||||
}
|
||||
|
||||
// Add a type to the list of types.
|
||||
void Collect(Handle<Name> type);
|
||||
|
||||
// Dump the types to stdout.
|
||||
// TODO(franzih): pass this information to the debugger protocol instead of
|
||||
// stdout.
|
||||
void Print() const;
|
||||
|
||||
InlineCacheState StateFromFeedback() const override;
|
||||
};
|
||||
|
||||
inline BinaryOperationHint BinaryOperationHintFromFeedback(int type_feedback);
|
||||
inline CompareOperationHint CompareOperationHintFromFeedback(int type_feedback);
|
||||
|
||||
|
@ -581,7 +581,6 @@ void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
|
||||
case FeedbackSlotKind::kLiteral:
|
||||
case FeedbackSlotKind::kGeneral:
|
||||
case FeedbackSlotKind::kStoreDataPropertyInLiteral:
|
||||
case FeedbackSlotKind::kTypeProfile:
|
||||
case FeedbackSlotKind::kInvalid:
|
||||
case FeedbackSlotKind::kKindsNumber:
|
||||
UNREACHABLE();
|
||||
@ -629,7 +628,6 @@ void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
|
||||
case FeedbackSlotKind::kLiteral:
|
||||
case FeedbackSlotKind::kGeneral:
|
||||
case FeedbackSlotKind::kStoreDataPropertyInLiteral:
|
||||
case FeedbackSlotKind::kTypeProfile:
|
||||
case FeedbackSlotKind::kInvalid:
|
||||
case FeedbackSlotKind::kKindsNumber:
|
||||
UNREACHABLE();
|
||||
|
@ -632,13 +632,6 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreDataPropertyInLiteral(
|
||||
return *this;
|
||||
}
|
||||
|
||||
BytecodeArrayBuilder& BytecodeArrayBuilder::CollectTypeProfile(
|
||||
Register name, int feedback_slot) {
|
||||
DCHECK(FLAG_type_profile);
|
||||
OutputCollectTypeProfile(name, feedback_slot);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
|
||||
Register object, size_t name_index, int feedback_slot,
|
||||
LanguageMode language_mode) {
|
||||
|
@ -137,11 +137,6 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
|
||||
Register object, Register name, DataPropertyInLiteralFlags flags,
|
||||
int feedback_slot);
|
||||
|
||||
// Collect type information for developer tools. The value for which we
|
||||
// record the type is stored in the accumulator.
|
||||
// TODO(franzih): Do not pass the name, instead use the source position.
|
||||
BytecodeArrayBuilder& CollectTypeProfile(Register name, int feedback_slot);
|
||||
|
||||
// Store a property named by a property name. The value to be stored should be
|
||||
// in the accumulator.
|
||||
BytecodeArrayBuilder& StoreNamedProperty(Register object,
|
||||
|
@ -2214,34 +2214,18 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
LhsKind assign_type = Property::GetAssignType(property);
|
||||
|
||||
// Evaluate LHS expression.
|
||||
Register lhs_name;
|
||||
if (expr->HasTypeProfileSlot()) {
|
||||
lhs_name = register_allocator()->NewRegister();
|
||||
}
|
||||
|
||||
switch (assign_type) {
|
||||
case VARIABLE:
|
||||
if (expr->HasTypeProfileSlot()) {
|
||||
builder()
|
||||
->LoadLiteral(expr->target()->AsVariableProxy()->var()->raw_name())
|
||||
.StoreAccumulatorInRegister(lhs_name);
|
||||
}
|
||||
// Nothing to do to evaluate variable assignment LHS.
|
||||
break;
|
||||
case NAMED_PROPERTY: {
|
||||
object = VisitForRegisterValue(property->obj());
|
||||
name = property->key()->AsLiteral()->AsRawPropertyName();
|
||||
if (expr->HasTypeProfileSlot()) {
|
||||
builder()->LoadLiteral(name).StoreAccumulatorInRegister(lhs_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KEYED_PROPERTY: {
|
||||
object = VisitForRegisterValue(property->obj());
|
||||
key = VisitForRegisterValue(property->key());
|
||||
if (expr->HasTypeProfileSlot()) {
|
||||
builder()->StoreAccumulatorInRegister(lhs_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NAMED_SUPER_PROPERTY: {
|
||||
@ -2254,9 +2238,6 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
builder()
|
||||
->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
|
||||
.StoreAccumulatorInRegister(super_property_args[2]);
|
||||
if (expr->HasTypeProfileSlot()) {
|
||||
builder()->StoreAccumulatorInRegister(lhs_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
@ -2267,10 +2248,6 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
VisitForRegisterValue(super_property->home_object(),
|
||||
super_property_args[1]);
|
||||
VisitForRegisterValue(property->key(), super_property_args[2]);
|
||||
if (expr->HasTypeProfileSlot()) {
|
||||
builder()->StoreAccumulatorInRegister(lhs_name);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2359,14 +2336,6 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Value is in accumulator.
|
||||
if (expr->HasTypeProfileSlot()) {
|
||||
FeedbackSlot collect_type_feedback_slot = expr->TypeProfileSlot();
|
||||
|
||||
builder()->CollectTypeProfile(lhs_name,
|
||||
feedback_index(collect_type_feedback_slot));
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeGenerator::VisitYield(Yield* expr) {
|
||||
|
@ -105,8 +105,6 @@ namespace interpreter {
|
||||
OperandType::kReg, OperandType::kIdx) \
|
||||
V(StaDataPropertyInLiteral, AccumulatorUse::kRead, OperandType::kReg, \
|
||||
OperandType::kReg, OperandType::kFlag8, OperandType::kIdx) \
|
||||
V(CollectTypeProfile, AccumulatorUse::kRead, OperandType::kReg, \
|
||||
OperandType::kIdx) \
|
||||
\
|
||||
/* Binary Operators */ \
|
||||
V(Add, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \
|
||||
|
@ -1045,19 +1045,6 @@ void Interpreter::DoStaDataPropertyInLiteral(InterpreterAssembler* assembler) {
|
||||
__ Dispatch();
|
||||
}
|
||||
|
||||
void Interpreter::DoCollectTypeProfile(InterpreterAssembler* assembler) {
|
||||
Node* name = __ LoadRegister(__ BytecodeOperandReg(0));
|
||||
Node* value = __ GetAccumulator();
|
||||
Node* vector_index = __ SmiTag(__ BytecodeOperandIdx(1));
|
||||
|
||||
Node* feedback_vector = __ LoadFeedbackVector();
|
||||
Node* context = __ GetContext();
|
||||
|
||||
__ CallRuntime(Runtime::kCollectTypeProfile, context, name, value,
|
||||
feedback_vector, vector_index);
|
||||
__ Dispatch();
|
||||
}
|
||||
|
||||
// LdaModuleVariable <cell_index> <depth>
|
||||
//
|
||||
// Load the contents of a module variable into the accumulator. The variable is
|
||||
|
@ -751,7 +751,6 @@ void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT
|
||||
case FeedbackSlotKind::kCreateClosure:
|
||||
case FeedbackSlotKind::kLiteral:
|
||||
case FeedbackSlotKind::kGeneral:
|
||||
case FeedbackSlotKind::kTypeProfile:
|
||||
break;
|
||||
case FeedbackSlotKind::kToBoolean:
|
||||
case FeedbackSlotKind::kInvalid:
|
||||
|
@ -691,32 +691,6 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
|
||||
return *object;
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_CollectTypeProfile) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(4, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
|
||||
CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 2);
|
||||
CONVERT_SMI_ARG_CHECKED(index, 3);
|
||||
|
||||
DCHECK(FLAG_type_profile);
|
||||
|
||||
Handle<Name> type = Object::TypeOf(isolate, value);
|
||||
if (value->IsJSReceiver()) {
|
||||
Handle<JSReceiver> object = Handle<JSReceiver>::cast(value);
|
||||
type = JSReceiver::GetConstructorName(object);
|
||||
}
|
||||
|
||||
CollectTypeProfileNexus nexus(vector, vector->ToSlot(index));
|
||||
nexus.Collect(type);
|
||||
|
||||
PrintF("%s\n", name->ToCString().get());
|
||||
nexus.Print();
|
||||
PrintF("\n");
|
||||
|
||||
return *name;
|
||||
}
|
||||
|
||||
// Return property without being observable by accessors or interceptors.
|
||||
RUNTIME_FUNCTION(Runtime_GetDataProperty) {
|
||||
HandleScope scope(isolate);
|
||||
|
@ -394,7 +394,6 @@ namespace internal {
|
||||
F(IsJSGlobalProxy, 1, 1) \
|
||||
F(DefineAccessorPropertyUnchecked, 5, 1) \
|
||||
F(DefineDataPropertyInLiteral, 6, 1) \
|
||||
F(CollectTypeProfile, 4, 1) \
|
||||
F(GetDataProperty, 2, 1) \
|
||||
F(GetConstructorName, 1, 1) \
|
||||
F(HasFastPackedElements, 1, 1) \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,440 +0,0 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
// Flags: --type-profile
|
||||
|
||||
// Add mjsunit/array-splice.js as integration test for type profile.
|
||||
const expression = `
|
||||
function assertEquals() {
|
||||
}
|
||||
function assertFalse() {
|
||||
}
|
||||
function assertTrue() {
|
||||
}
|
||||
|
||||
// Check that splicing array of holes keeps it as array of holes
|
||||
(function() {
|
||||
for (var i = 0; i < 7; i++) {
|
||||
var array = new Array(10);
|
||||
var spliced = array.splice(1, 1, 'one', 'two');
|
||||
assertEquals(1, spliced.length);
|
||||
assertFalse(0 in spliced, "0 in spliced");
|
||||
|
||||
assertEquals(11, array.length);
|
||||
assertFalse(0 in array, "0 in array");
|
||||
assertTrue(1 in array);
|
||||
assertTrue(2 in array);
|
||||
assertFalse(3 in array, "3 in array");
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
// Check various variants of empty array's splicing.
|
||||
(function() {
|
||||
for (var i = 0; i < 7; i++) {
|
||||
assertEquals([], [].splice(0, 0));
|
||||
assertEquals([], [].splice(1, 0));
|
||||
assertEquals([], [].splice(0, 1));
|
||||
assertEquals([], [].splice(-1, 0));
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
// Check that even if result array is empty, receiver gets sliced.
|
||||
(function() {
|
||||
for (var i = 0; i < 7; i++) {
|
||||
var a = [1, 2, 3];
|
||||
assertEquals([], a.splice(1, 0, 'a', 'b', 'c'));
|
||||
assertEquals([1, 'a', 'b', 'c', 2, 3], a);
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
// Check various forms of arguments omission.
|
||||
(function() {
|
||||
var array;
|
||||
for (var i = 0; i < 7; i++) {
|
||||
array = [1, 2, 3]
|
||||
assertEquals([], array.splice());
|
||||
assertEquals([1, 2, 3], array);
|
||||
|
||||
// SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
|
||||
// given differently from when an undefined delete count is given.
|
||||
// This does not follow ECMA-262, but we do the same for
|
||||
// compatibility.
|
||||
array = [1, 2, 3]
|
||||
assertEquals([1, 2, 3], array.splice(0));
|
||||
assertEquals([], array);
|
||||
|
||||
array = [1, 2, 3]
|
||||
assertEquals([1, 2, 3], array.splice(undefined));
|
||||
assertEquals([], array);
|
||||
|
||||
array = [1, 2, 3]
|
||||
assertEquals([1, 2, 3], array.splice("foobar"));
|
||||
assertEquals([], array);
|
||||
|
||||
array = [1, 2, 3]
|
||||
assertEquals([], array.splice(undefined, undefined));
|
||||
assertEquals([1, 2, 3], array);
|
||||
|
||||
array = [1, 2, 3]
|
||||
assertEquals([], array.splice("foobar", undefined));
|
||||
assertEquals([1, 2, 3], array);
|
||||
|
||||
array = [1, 2, 3]
|
||||
assertEquals([], array.splice(undefined, "foobar"));
|
||||
assertEquals([1, 2, 3], array);
|
||||
|
||||
array = [1, 2, 3]
|
||||
assertEquals([], array.splice("foobar", "foobar"));
|
||||
assertEquals([1, 2, 3], array);
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
// Check variants of negatives and positive indices.
|
||||
(function() {
|
||||
var array, spliced;
|
||||
for (var i = 0; i < 7; i++) {
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(-100);
|
||||
assertEquals([], array);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(-1e100);
|
||||
assertEquals([], array);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(-3);
|
||||
assertEquals([1, 2, 3, 4], array);
|
||||
assertEquals([5, 6, 7], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(-3.999999);
|
||||
assertEquals([1, 2, 3, 4], array);
|
||||
assertEquals([5, 6, 7], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(-3.000001);
|
||||
assertEquals([1, 2, 3, 4], array);
|
||||
assertEquals([5, 6, 7], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(4);
|
||||
assertEquals([1, 2, 3, 4], array);
|
||||
assertEquals([5, 6, 7], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(4.999999);
|
||||
assertEquals([1, 2, 3, 4], array);
|
||||
assertEquals([5, 6, 7], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(4.000001);
|
||||
assertEquals([1, 2, 3, 4], array);
|
||||
assertEquals([5, 6, 7], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(6);
|
||||
assertEquals([1, 2, 3, 4, 5, 6], array);
|
||||
assertEquals([7], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(7);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], array);
|
||||
assertEquals([], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(8);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], array);
|
||||
assertEquals([], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(100);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], array);
|
||||
assertEquals([], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(1e100);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], array);
|
||||
assertEquals([], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(0, -100);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], array);
|
||||
assertEquals([], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(0, -1e100);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], array);
|
||||
assertEquals([], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(0, -3);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], array);
|
||||
assertEquals([], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(0, -3.999999);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], array);
|
||||
assertEquals([], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(0, -3.000001);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], array);
|
||||
assertEquals([], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(0, 4);
|
||||
assertEquals([5, 6, 7], array);
|
||||
assertEquals([1, 2, 3, 4], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(0, 4.999999);
|
||||
assertEquals([5, 6, 7], array);
|
||||
assertEquals([1, 2, 3, 4], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(0, 4.000001);
|
||||
assertEquals([5, 6, 7], array);
|
||||
assertEquals([1, 2, 3, 4], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(0, 6);
|
||||
assertEquals([7], array);
|
||||
assertEquals([1, 2, 3, 4, 5, 6], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(0, 7);
|
||||
assertEquals([], array);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(0, 8);
|
||||
assertEquals([], array);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(0, 100);
|
||||
assertEquals([], array);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
|
||||
|
||||
array = [1, 2, 3, 4, 5, 6, 7];
|
||||
spliced = array.splice(0, 1e100);
|
||||
assertEquals([], array);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
|
||||
|
||||
// Some exotic cases.
|
||||
obj = { toString: function() { throw 'Exception'; } };
|
||||
|
||||
// Throwing an exception in conversion:
|
||||
try {
|
||||
[1, 2, 3].splice(obj, 3);
|
||||
throw 'Should have thrown';
|
||||
} catch (e) {
|
||||
assertEquals('Exception', e);
|
||||
}
|
||||
|
||||
try {
|
||||
[1, 2, 3].splice(0, obj, 3);
|
||||
throw 'Should have thrown';
|
||||
} catch (e) {
|
||||
assertEquals('Exception', e);
|
||||
}
|
||||
|
||||
array = [1, 2, 3];
|
||||
array.splice(0, 3, obj);
|
||||
assertEquals(1, array.length);
|
||||
|
||||
// Custom conversion:
|
||||
array = [1, 2, 3];
|
||||
spliced = array.splice({valueOf: function() { return 1; }},
|
||||
{toString: function() { return 2; }},
|
||||
'one', 'two');
|
||||
assertEquals([2, 3], spliced);
|
||||
assertEquals([1, 'one', 'two'], array);
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
// Nasty: modify the array in ToInteger.
|
||||
(function() {
|
||||
var array = [];
|
||||
var spliced;
|
||||
|
||||
for (var i = 0; i < 13; i++) {
|
||||
bad_start = { valueOf: function() { array.push(2*i); return -1; } };
|
||||
bad_count = { valueOf: function() { array.push(2*i + 1); return 1; } };
|
||||
spliced = array.splice(bad_start, bad_count);
|
||||
// According to the spec (15.4.4.12), length is calculated before
|
||||
// performing ToInteger on arguments. However, v8 ignores elements
|
||||
// we add while converting, so we need corrective pushes.
|
||||
array.push(2*i); array.push(2*i + 1);
|
||||
if (i == 0) {
|
||||
assertEquals([], spliced); // Length was 0, nothing to get.
|
||||
assertEquals([0, 1], array);
|
||||
} else {
|
||||
// When we start splice, array is [0 .. 2*i - 1], so we get
|
||||
// as a result [2*i], this element is removed from the array,
|
||||
// but [2 * i, 2 * i + 1] are added.
|
||||
assertEquals([2 * i - 1], spliced);
|
||||
assertEquals(2 * i, array[i]);
|
||||
assertEquals(2 * i + 1, array[i + 1]);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
// Check the behaviour when approaching maximal values for length.
|
||||
(function() {
|
||||
for (var i = 0; i < 7; i++) {
|
||||
try {
|
||||
new Array(Math.pow(2, 32) - 3).splice(-1, 0, 1, 2, 3, 4, 5);
|
||||
throw 'Should have thrown RangeError';
|
||||
} catch (e) {
|
||||
assertTrue(e instanceof RangeError);
|
||||
}
|
||||
|
||||
// Check smi boundary
|
||||
var bigNum = (1 << 30) - 3;
|
||||
var array = new Array(bigNum);
|
||||
array.splice(-1, 0, 1, 2, 3, 4, 5, 6, 7);
|
||||
assertEquals(bigNum + 7, array.length);
|
||||
}
|
||||
})();
|
||||
|
||||
(function() {
|
||||
for (var i = 0; i < 7; i++) {
|
||||
var a = [7, 8, 9];
|
||||
a.splice(0, 0, 1, 2, 3, 4, 5, 6);
|
||||
assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a);
|
||||
assertFalse(a.hasOwnProperty(10), "a.hasOwnProperty(10)");
|
||||
assertEquals(undefined, a[10]);
|
||||
}
|
||||
})();
|
||||
|
||||
(function testSpliceDeleteDouble() {
|
||||
var a = [1.1, 1.2, 1.3, 1.4];
|
||||
a.splice(2, 1)
|
||||
assertEquals([1.1, 1.2, 1.4], a);
|
||||
})();
|
||||
|
||||
// Past this point the ArrayProtector is invalidated since we modify the
|
||||
// Array.prototype.
|
||||
|
||||
// Check the case of JS builtin .splice()
|
||||
(function() {
|
||||
for (var i = 0; i < 7; i++) {
|
||||
var array = [1, 2, 3, 4];
|
||||
Array.prototype[3] = 'foo'; // To force JS builtin.
|
||||
|
||||
var spliced = array.splice();
|
||||
|
||||
assertEquals([], spliced);
|
||||
assertEquals([1, 2, 3, 4], array);
|
||||
}
|
||||
})();
|
||||
|
||||
// Now check the case with array of holes and some elements on prototype.
|
||||
(function() {
|
||||
var len = 9;
|
||||
|
||||
var at3 = "@3";
|
||||
var at7 = "@7";
|
||||
|
||||
for (var i = 0; i < 7; i++) {
|
||||
var array = new Array(len);
|
||||
var array_proto = [];
|
||||
array_proto[3] = at3;
|
||||
array_proto[7] = at7;
|
||||
array.__proto__ = array_proto;
|
||||
|
||||
var spliced = array.splice(2, 2, 'one', undefined, 'two');
|
||||
|
||||
// Second hole (at index 3) of array turns into
|
||||
// value of Array.prototype[3] while copying.
|
||||
assertEquals([, at3], spliced);
|
||||
assertEquals([, , 'one', undefined, 'two', , , at7, at7, ,], array);
|
||||
|
||||
// ... but array[3] and array[7] is actually a hole:
|
||||
assertTrue(delete array_proto[3]);
|
||||
assertEquals(undefined, array[3]);
|
||||
assertTrue(delete array_proto[7]);
|
||||
assertEquals(undefined, array[7]);
|
||||
|
||||
// and now check hasOwnProperty
|
||||
assertFalse(array.hasOwnProperty(0), "array.hasOwnProperty(0)");
|
||||
assertFalse(array.hasOwnProperty(1), "array.hasOwnProperty(1)");
|
||||
assertTrue(array.hasOwnProperty(2));
|
||||
assertTrue(array.hasOwnProperty(3));
|
||||
assertTrue(array.hasOwnProperty(4));
|
||||
assertFalse(array.hasOwnProperty(5), "array.hasOwnProperty(5)");
|
||||
assertFalse(array.hasOwnProperty(6), "array.hasOwnProperty(6)");
|
||||
assertFalse(array.hasOwnProperty(7), "array.hasOwnProperty(7)");
|
||||
assertTrue(array.hasOwnProperty(8));
|
||||
assertFalse(array.hasOwnProperty(9), "array.hasOwnProperty(9)");
|
||||
|
||||
// and now check couple of indices above length.
|
||||
assertFalse(array.hasOwnProperty(10), "array.hasOwnProperty(10)");
|
||||
assertFalse(array.hasOwnProperty(15), "array.hasOwnProperty(15)");
|
||||
assertFalse(array.hasOwnProperty(31), "array.hasOwnProperty(31)");
|
||||
assertFalse(array.hasOwnProperty(63), "array.hasOwnProperty(63)");
|
||||
assertFalse(array.hasOwnProperty(Math.pow(2, 32) - 2),
|
||||
"array.hasOwnProperty(Math.pow(2, 32) - 2)");
|
||||
}
|
||||
})();
|
||||
|
||||
// Now check the case with array of holes and some elements on prototype.
|
||||
(function() {
|
||||
var len = 9;
|
||||
|
||||
var at3 = "@3";
|
||||
var at7 = "@7";
|
||||
|
||||
for (var i = 0; i < 7; i++) {
|
||||
var array = new Array(len);
|
||||
Array.prototype[3] = at3;
|
||||
Array.prototype[7] = at7;
|
||||
|
||||
var spliced = array.splice(2, 2, 'one', undefined, 'two');
|
||||
|
||||
// Second hole (at index 3) of array turns into
|
||||
// value of Array.prototype[3] while copying.
|
||||
assertEquals([, at3], spliced);
|
||||
assertEquals([, , 'one', undefined, 'two', , , at7, at7, ,], array);
|
||||
|
||||
// ... but array[3] and array[7] is actually a hole:
|
||||
assertTrue(delete Array.prototype[3]);
|
||||
assertEquals(undefined, array[3]);
|
||||
assertTrue(delete Array.prototype[7]);
|
||||
assertEquals(undefined, array[7]);
|
||||
|
||||
// and now check hasOwnProperty
|
||||
assertFalse(array.hasOwnProperty(0), "array.hasOwnProperty(0)");
|
||||
assertFalse(array.hasOwnProperty(1), "array.hasOwnProperty(1)");
|
||||
assertTrue(array.hasOwnProperty(2));
|
||||
assertTrue(array.hasOwnProperty(3));
|
||||
assertTrue(array.hasOwnProperty(4));
|
||||
assertFalse(array.hasOwnProperty(5), "array.hasOwnProperty(5)");
|
||||
assertFalse(array.hasOwnProperty(6), "array.hasOwnProperty(6)");
|
||||
assertFalse(array.hasOwnProperty(7), "array.hasOwnProperty(7)");
|
||||
assertTrue(array.hasOwnProperty(8));
|
||||
assertFalse(array.hasOwnProperty(9), "array.hasOwnProperty(9)");
|
||||
|
||||
// and now check couple of indices above length.
|
||||
assertFalse(array.hasOwnProperty(10), "array.hasOwnProperty(10)");
|
||||
assertFalse(array.hasOwnProperty(15), "array.hasOwnProperty(15)");
|
||||
assertFalse(array.hasOwnProperty(31), "array.hasOwnProperty(31)");
|
||||
assertFalse(array.hasOwnProperty(63), "array.hasOwnProperty(63)");
|
||||
assertFalse(array.hasOwnProperty(Math.pow(2, 32) - 2),
|
||||
"array.hasOwnProperty(Math.pow(2, 32) - 2)");
|
||||
}
|
||||
})();`;
|
||||
|
||||
|
||||
|
||||
Protocol.Runtime.evaluate({ expression: expression })
|
||||
.then(function() {InspectorTest.completeTest();});
|
@ -1,902 +0,0 @@
|
||||
setTimeout
|
||||
Function
|
||||
|
||||
.result
|
||||
Function
|
||||
|
||||
attachInspector
|
||||
Function
|
||||
|
||||
detachInspector
|
||||
Function
|
||||
|
||||
setMaxAsyncTaskStacks
|
||||
Function
|
||||
|
||||
breakProgram
|
||||
Function
|
||||
|
||||
createObjectWithStrictCheck
|
||||
Function
|
||||
|
||||
callWithScheduledBreak
|
||||
Function
|
||||
|
||||
allowAccessorFormatting
|
||||
Function
|
||||
|
||||
.result
|
||||
Function
|
||||
|
||||
print
|
||||
Function
|
||||
|
||||
quit
|
||||
Function
|
||||
|
||||
setlocale
|
||||
Function
|
||||
|
||||
read
|
||||
Function
|
||||
|
||||
load
|
||||
Function
|
||||
|
||||
compileAndRunWithOrigin
|
||||
Function
|
||||
|
||||
setCurrentTimeMSForTest
|
||||
Function
|
||||
|
||||
schedulePauseOnNextStatement
|
||||
Function
|
||||
|
||||
cancelPauseOnNextStatement
|
||||
Function
|
||||
|
||||
reconnect
|
||||
Function
|
||||
|
||||
createContextGroup
|
||||
Function
|
||||
|
||||
.result
|
||||
Function
|
||||
|
||||
sendMessageToBackend
|
||||
Function
|
||||
|
||||
.result
|
||||
Function
|
||||
|
||||
.result
|
||||
Function
|
||||
|
||||
InspectorTest
|
||||
Object
|
||||
|
||||
_dispatchTable
|
||||
Map
|
||||
|
||||
_requestId
|
||||
number
|
||||
|
||||
_dumpInspectorProtocolMessages
|
||||
boolean
|
||||
|
||||
_eventHandler
|
||||
Object
|
||||
|
||||
Protocol
|
||||
Object
|
||||
|
||||
log
|
||||
Function
|
||||
|
||||
logMessage
|
||||
Function
|
||||
|
||||
logObject
|
||||
Function
|
||||
|
||||
logCallFrames
|
||||
Function
|
||||
|
||||
logSourceLocation
|
||||
Function
|
||||
|
||||
logSourceLocations
|
||||
Function
|
||||
|
||||
logAsyncStackTrace
|
||||
Function
|
||||
|
||||
completeTest
|
||||
Function
|
||||
|
||||
completeTestAfterPendingTimeouts
|
||||
Function
|
||||
|
||||
waitPendingTasks
|
||||
Function
|
||||
|
||||
addScript
|
||||
Function
|
||||
|
||||
addScriptWithUrl
|
||||
Function
|
||||
|
||||
addModule
|
||||
Function
|
||||
|
||||
startDumpingProtocolMessages
|
||||
Function
|
||||
|
||||
sendRawCommand
|
||||
Function
|
||||
|
||||
checkExpectation
|
||||
Function
|
||||
|
||||
expectedSuccess
|
||||
Function
|
||||
|
||||
expectedError
|
||||
Function
|
||||
|
||||
setupScriptMap
|
||||
Function
|
||||
|
||||
runTestSuite
|
||||
Function
|
||||
|
||||
runAsyncTestSuite
|
||||
AsyncFunction
|
||||
|
||||
_sendCommandPromise
|
||||
Function
|
||||
|
||||
_waitForEventPromise
|
||||
Function
|
||||
|
||||
_dispatchMessage
|
||||
Function
|
||||
|
||||
loadScript
|
||||
Function
|
||||
|
||||
.result
|
||||
Function
|
||||
|
||||
expression
|
||||
string
|
||||
|
||||
eventPattern
|
||||
RegExp
|
||||
|
||||
match
|
||||
object
|
||||
|
||||
requestId
|
||||
number
|
||||
|
||||
messageObject
|
||||
Object
|
||||
|
||||
fulfillCallback
|
||||
Function
|
||||
|
||||
promise
|
||||
Promise
|
||||
|
||||
l
|
||||
object
|
||||
|
||||
n
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
|
||||
o
|
||||
number
|
||||
|
||||
q
|
||||
number
|
||||
|
||||
q
|
||||
number
|
||||
|
||||
y
|
||||
number
|
||||
|
||||
z
|
||||
number
|
||||
|
||||
A
|
||||
number
|
||||
|
||||
q
|
||||
number
|
||||
|
||||
B
|
||||
number
|
||||
|
||||
o
|
||||
number
|
||||
|
||||
C
|
||||
number
|
||||
|
||||
.result
|
||||
Promise
|
||||
|
||||
.result
|
||||
Function
|
||||
|
||||
__proto__
|
||||
object
|
||||
|
||||
__proto__
|
||||
object
|
||||
object
|
||||
|
||||
__proto__
|
||||
object
|
||||
object
|
||||
object
|
||||
|
||||
my_var1
|
||||
Object
|
||||
|
||||
my_var2
|
||||
number
|
||||
|
||||
my_var1
|
||||
Object
|
||||
number
|
||||
|
||||
my_var2
|
||||
number
|
||||
number
|
||||
|
||||
my_var1
|
||||
Object
|
||||
number
|
||||
string
|
||||
|
||||
my_var2
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
my_var1
|
||||
Object
|
||||
number
|
||||
string
|
||||
number
|
||||
|
||||
my_var2
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
my_var1
|
||||
Object
|
||||
number
|
||||
string
|
||||
number
|
||||
undefined
|
||||
|
||||
my_var2
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
my_var1
|
||||
Object
|
||||
number
|
||||
string
|
||||
number
|
||||
undefined
|
||||
string
|
||||
|
||||
my_var2
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
my_var1
|
||||
Object
|
||||
number
|
||||
string
|
||||
number
|
||||
undefined
|
||||
string
|
||||
Object
|
||||
|
||||
my_var2
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
my_var1
|
||||
Object
|
||||
number
|
||||
string
|
||||
number
|
||||
undefined
|
||||
string
|
||||
Object
|
||||
Object
|
||||
|
||||
my_var2
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
|
||||
Function
|
||||
|
||||
MyClass
|
||||
Function
|
||||
|
||||
my_var
|
||||
MyClass
|
||||
|
||||
my_var
|
||||
MyClass
|
||||
Object
|
||||
|
||||
my_var
|
||||
MyClass
|
||||
Object
|
||||
number
|
||||
|
||||
.result
|
||||
undefined
|
||||
|
||||
type
|
||||
string
|
||||
|
||||
messageId
|
||||
number
|
||||
|
||||
l
|
||||
object
|
||||
|
||||
n
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
|
||||
o
|
||||
number
|
||||
number
|
||||
|
||||
q
|
||||
number
|
||||
number
|
||||
|
||||
r
|
||||
number
|
||||
|
||||
q
|
||||
number
|
||||
|
||||
handler
|
||||
Function
|
||||
|
||||
l
|
||||
object
|
||||
|
||||
n
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
|
||||
o
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
q
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
r
|
||||
number
|
||||
number
|
||||
|
||||
q
|
||||
number
|
||||
|
||||
y
|
||||
number
|
||||
|
||||
z
|
||||
number
|
||||
|
||||
B
|
||||
number
|
||||
|
||||
.result
|
||||
undefined
|
||||
|
||||
eventPattern
|
||||
RegExp
|
||||
RegExp
|
||||
|
||||
match
|
||||
object
|
||||
object
|
||||
|
||||
requestId
|
||||
number
|
||||
number
|
||||
|
||||
messageObject
|
||||
Object
|
||||
Object
|
||||
|
||||
fulfillCallback
|
||||
Function
|
||||
Function
|
||||
|
||||
promise
|
||||
Promise
|
||||
Promise
|
||||
|
||||
l
|
||||
object
|
||||
object
|
||||
|
||||
n
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
|
||||
o
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
q
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
q
|
||||
number
|
||||
number
|
||||
|
||||
y
|
||||
number
|
||||
number
|
||||
|
||||
z
|
||||
number
|
||||
number
|
||||
|
||||
A
|
||||
number
|
||||
number
|
||||
|
||||
q
|
||||
number
|
||||
number
|
||||
|
||||
B
|
||||
number
|
||||
number
|
||||
|
||||
o
|
||||
number
|
||||
number
|
||||
|
||||
C
|
||||
number
|
||||
number
|
||||
|
||||
messageId
|
||||
number
|
||||
number
|
||||
|
||||
l
|
||||
object
|
||||
object
|
||||
|
||||
n
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
|
||||
o
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
q
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
r
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
q
|
||||
number
|
||||
number
|
||||
|
||||
handler
|
||||
Function
|
||||
Function
|
||||
|
||||
l
|
||||
object
|
||||
object
|
||||
|
||||
n
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
m
|
||||
number
|
||||
number
|
||||
|
||||
o
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
q
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
r
|
||||
number
|
||||
number
|
||||
number
|
||||
number
|
||||
|
||||
q
|
||||
number
|
||||
number
|
||||
|
||||
y
|
||||
number
|
||||
number
|
||||
|
||||
z
|
||||
number
|
||||
number
|
||||
|
||||
B
|
||||
number
|
||||
number
|
||||
|
||||
.result
|
||||
undefined
|
||||
|
@ -1,38 +0,0 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Flags: --type-profile --turbo
|
||||
|
||||
const expression = `
|
||||
function test(param) {
|
||||
var my_var1 = param;
|
||||
var my_var2 = 17;
|
||||
}
|
||||
|
||||
test({});
|
||||
test(123);
|
||||
test('hello');
|
||||
test(123);
|
||||
test(undefined);
|
||||
test('hello');
|
||||
test({x: 12});
|
||||
test({x: 12});
|
||||
|
||||
class MyClass {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
|
||||
function testConstructorNames(param) {
|
||||
var my_var = param;
|
||||
}
|
||||
|
||||
testConstructorNames(new MyClass());
|
||||
testConstructorNames({});
|
||||
testConstructorNames(2);
|
||||
`;
|
||||
|
||||
|
||||
Protocol.Runtime.evaluate({ expression: expression })
|
||||
.then(function() {InspectorTest.completeTest();});
|
@ -446,12 +446,6 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
|
||||
scorecard[Bytecodes::ToByte(Bytecode::kTestNull)] = 1;
|
||||
}
|
||||
|
||||
if (!FLAG_type_profile) {
|
||||
// Bytecode for CollectTypeProfile is only emitted when
|
||||
// Type Information for DevTools is turned on.
|
||||
scorecard[Bytecodes::ToByte(Bytecode::kCollectTypeProfile)] = 1;
|
||||
}
|
||||
|
||||
// Check return occurs at the end and only once in the BytecodeArray.
|
||||
CHECK_EQ(final_bytecode, Bytecode::kReturn);
|
||||
CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1);
|
||||
|
Loading…
Reference in New Issue
Block a user