Commit c92f41d0 authored by machenbach's avatar machenbach Committed by Commit bot

Revert of Collect type profile for DevTools. (patchset #39 id:730001 of...

Revert of Collect type profile for DevTools. (patchset #39 id:730001 of https://codereview.chromium.org/2707873002/ )

Reason for revert:
gcc bot has problems with this: https://build.chromium.org/p/client.v8/builders/V8%20Linux%20gcc%204.8/builds/11858

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-Commit-Position: refs/heads/master@{#43791}
> Committed: https://chromium.googlesource.com/v8/v8/+/0332bebde99d0f9a5a8326382f5f37cc26224ae0

TBR=yangguo@chromium.org,mvstanton@chromium.org,rmcilroy@chromium.org,mstarzinger@chromium.org,franzih@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/2749673003
Cr-Commit-Position: refs/heads/master@{#43798}
parent 62b6dd19
...@@ -15,8 +15,7 @@ namespace internal { ...@@ -15,8 +15,7 @@ namespace internal {
class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> { class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> {
public: public:
AstNumberingVisitor(uintptr_t stack_limit, Zone* zone, AstNumberingVisitor(uintptr_t stack_limit, Zone* zone,
Compiler::EagerInnerFunctionLiterals* eager_literals, Compiler::EagerInnerFunctionLiterals* eager_literals)
bool collect_type_profile = false)
: zone_(zone), : zone_(zone),
eager_literals_(eager_literals), eager_literals_(eager_literals),
next_id_(BailoutId::FirstUsable().ToInt()), next_id_(BailoutId::FirstUsable().ToInt()),
...@@ -26,8 +25,7 @@ class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> { ...@@ -26,8 +25,7 @@ class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> {
slot_cache_(zone), slot_cache_(zone),
disable_crankshaft_reason_(kNoReason), disable_crankshaft_reason_(kNoReason),
dont_optimize_reason_(kNoReason), dont_optimize_reason_(kNoReason),
catch_prediction_(HandlerTable::UNCAUGHT), catch_prediction_(HandlerTable::UNCAUGHT) {
collect_type_profile_(collect_type_profile) {
InitializeAstVisitor(stack_limit); InitializeAstVisitor(stack_limit);
} }
...@@ -103,7 +101,6 @@ class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> { ...@@ -103,7 +101,6 @@ class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> {
BailoutReason disable_crankshaft_reason_; BailoutReason disable_crankshaft_reason_;
BailoutReason dont_optimize_reason_; BailoutReason dont_optimize_reason_;
HandlerTable::CatchPrediction catch_prediction_; HandlerTable::CatchPrediction catch_prediction_;
bool collect_type_profile_;
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
DISALLOW_COPY_AND_ASSIGN(AstNumberingVisitor); DISALLOW_COPY_AND_ASSIGN(AstNumberingVisitor);
...@@ -425,8 +422,7 @@ void AstNumberingVisitor::VisitAssignment(Assignment* node) { ...@@ -425,8 +422,7 @@ void AstNumberingVisitor::VisitAssignment(Assignment* node) {
if (node->is_compound()) VisitBinaryOperation(node->binary_operation()); if (node->is_compound()) VisitBinaryOperation(node->binary_operation());
VisitReference(node->target()); VisitReference(node->target());
Visit(node->value()); Visit(node->value());
node->AssignFeedbackSlots(properties_.get_spec(), language_mode_, ReserveFeedbackSlots(node);
&slot_cache_, collect_type_profile_);
} }
...@@ -718,14 +714,12 @@ bool AstNumberingVisitor::Renumber(FunctionLiteral* node) { ...@@ -718,14 +714,12 @@ bool AstNumberingVisitor::Renumber(FunctionLiteral* node) {
bool AstNumbering::Renumber( bool AstNumbering::Renumber(
uintptr_t stack_limit, Zone* zone, FunctionLiteral* function, uintptr_t stack_limit, Zone* zone, FunctionLiteral* function,
Compiler::EagerInnerFunctionLiterals* eager_literals, Compiler::EagerInnerFunctionLiterals* eager_literals) {
bool collect_type_profile) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
DisallowHandleAllocation no_handles; DisallowHandleAllocation no_handles;
DisallowHandleDereference no_deref; DisallowHandleDereference no_deref;
AstNumberingVisitor visitor(stack_limit, zone, eager_literals, AstNumberingVisitor visitor(stack_limit, zone, eager_literals);
collect_type_profile);
return visitor.Renumber(function); return visitor.Renumber(function);
} }
} // namespace internal } // namespace internal
......
...@@ -27,8 +27,7 @@ namespace AstNumbering { ...@@ -27,8 +27,7 @@ namespace AstNumbering {
// non-null, adds any eager inner literal functions into it. // non-null, adds any eager inner literal functions into it.
bool Renumber( bool Renumber(
uintptr_t stack_limit, Zone* zone, FunctionLiteral* function, uintptr_t stack_limit, Zone* zone, FunctionLiteral* function,
ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* eager_literals, ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* eager_literals);
bool collect_type_profile = false);
} }
// Some details on yield IDs // Some details on yield IDs
......
...@@ -283,13 +283,8 @@ Assignment::Assignment(Token::Value op, Expression* target, Expression* value, ...@@ -283,13 +283,8 @@ Assignment::Assignment(Token::Value op, Expression* target, Expression* value,
void Assignment::AssignFeedbackSlots(FeedbackVectorSpec* spec, void Assignment::AssignFeedbackSlots(FeedbackVectorSpec* spec,
LanguageMode language_mode, LanguageMode language_mode,
FeedbackSlotCache* cache, FeedbackSlotCache* cache) {
bool collect_type_profile) {
AssignVectorSlots(target(), spec, language_mode, &slot_); AssignVectorSlots(target(), spec, language_mode, &slot_);
if (collect_type_profile) {
type_profile_slot_ = spec->AddTypeProfileSlot();
}
} }
void CountOperation::AssignFeedbackSlots(FeedbackVectorSpec* spec, void CountOperation::AssignFeedbackSlots(FeedbackVectorSpec* spec,
......
...@@ -2414,17 +2414,9 @@ class Assignment final : public Expression { ...@@ -2414,17 +2414,9 @@ class Assignment final : public Expression {
} }
void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
FeedbackSlotCache* cache, FeedbackSlotCache* cache);
bool collect_type_profile = false);
FeedbackSlot AssignmentSlot() const { return slot_; } FeedbackSlot AssignmentSlot() const { return slot_; }
FeedbackSlot TypeProfileSlot() const {
DCHECK(HasTypeProfileSlot());
return type_profile_slot_;
}
bool HasTypeProfileSlot() const { return !type_profile_slot_.IsInvalid(); }
private: private:
friend class AstNodeFactory; friend class AstNodeFactory;
...@@ -2446,8 +2438,6 @@ class Assignment final : public Expression { ...@@ -2446,8 +2438,6 @@ class Assignment final : public Expression {
Expression* value_; Expression* value_;
BinaryOperation* binary_operation_; BinaryOperation* binary_operation_;
SmallMapList receiver_types_; SmallMapList receiver_types_;
FeedbackSlot type_profile_slot_;
}; };
......
...@@ -478,23 +478,9 @@ bool Renumber(ParseInfo* parse_info, ...@@ -478,23 +478,9 @@ bool Renumber(ParseInfo* parse_info,
Compiler::EagerInnerFunctionLiterals* eager_literals) { Compiler::EagerInnerFunctionLiterals* eager_literals) {
RuntimeCallTimerScope runtimeTimer(parse_info->isolate(), RuntimeCallTimerScope runtimeTimer(parse_info->isolate(),
&RuntimeCallStats::CompileRenumber); &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( if (!AstNumbering::Renumber(
parse_info->isolate()->stack_guard()->real_climit(), parse_info->isolate()->stack_guard()->real_climit(),
parse_info->zone(), parse_info->literal(), eager_literals, parse_info->zone(), parse_info->literal(), eager_literals)) {
collect_type_profile)) {
return false; return false;
} }
if (!parse_info->shared_info().is_null()) { if (!parse_info->shared_info().is_null()) {
......
...@@ -802,22 +802,6 @@ void BytecodeGraphBuilder::VisitStaDataPropertyInLiteral() { ...@@ -802,22 +802,6 @@ void BytecodeGraphBuilder::VisitStaDataPropertyInLiteral() {
environment()->RecordAfterState(node, Environment::kAttachFrameState); 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() { void BytecodeGraphBuilder::VisitLdaContextSlot() {
const Operator* op = javascript()->LoadContext( const Operator* op = javascript()->LoadContext(
bytecode_iterator().GetUnsignedImmediateOperand(2), bytecode_iterator().GetUnsignedImmediateOperand(2),
......
...@@ -54,7 +54,6 @@ int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) { ...@@ -54,7 +54,6 @@ int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) {
case FeedbackSlotKind::kToBoolean: case FeedbackSlotKind::kToBoolean:
case FeedbackSlotKind::kLiteral: case FeedbackSlotKind::kLiteral:
case FeedbackSlotKind::kCreateClosure: case FeedbackSlotKind::kCreateClosure:
case FeedbackSlotKind::kTypeProfile:
return 1; return 1;
case FeedbackSlotKind::kCall: case FeedbackSlotKind::kCall:
...@@ -187,8 +186,7 @@ void FeedbackVector::ComputeCounts(int* with_type_info, int* generic, ...@@ -187,8 +186,7 @@ void FeedbackVector::ComputeCounts(int* with_type_info, int* generic,
case FeedbackSlotKind::kStoreOwnNamed: case FeedbackSlotKind::kStoreOwnNamed:
case FeedbackSlotKind::kStoreKeyedSloppy: case FeedbackSlotKind::kStoreKeyedSloppy:
case FeedbackSlotKind::kStoreKeyedStrict: case FeedbackSlotKind::kStoreKeyedStrict:
case FeedbackSlotKind::kStoreDataPropertyInLiteral: case FeedbackSlotKind::kStoreDataPropertyInLiteral: {
case FeedbackSlotKind::kTypeProfile: {
if (obj->IsWeakCell() || obj->IsFixedArray() || obj->IsString()) { if (obj->IsWeakCell() || obj->IsFixedArray() || obj->IsString()) {
with++; with++;
} else if (obj == megamorphic_sentinel) { } else if (obj == megamorphic_sentinel) {
......
...@@ -149,8 +149,6 @@ const char* FeedbackMetadata::Kind2String(FeedbackSlotKind kind) { ...@@ -149,8 +149,6 @@ const char* FeedbackMetadata::Kind2String(FeedbackSlotKind kind) {
return "kCreateClosure"; return "kCreateClosure";
case FeedbackSlotKind::kLiteral: case FeedbackSlotKind::kLiteral:
return "LITERAL"; return "LITERAL";
case FeedbackSlotKind::kTypeProfile:
return "TYPE_PROFILE";
case FeedbackSlotKind::kGeneral: case FeedbackSlotKind::kGeneral:
return "STUB"; return "STUB";
case FeedbackSlotKind::kKindsNumber: case FeedbackSlotKind::kKindsNumber:
...@@ -160,18 +158,6 @@ const char* FeedbackMetadata::Kind2String(FeedbackSlotKind kind) { ...@@ -160,18 +158,6 @@ const char* FeedbackMetadata::Kind2String(FeedbackSlotKind kind) {
return "?"; 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 { FeedbackSlotKind FeedbackVector::GetKind(FeedbackSlot slot) const {
DCHECK(!is_empty()); DCHECK(!is_empty());
return metadata()->GetKind(slot); return metadata()->GetKind(slot);
...@@ -233,7 +219,6 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate, ...@@ -233,7 +219,6 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate,
case FeedbackSlotKind::kStoreKeyedStrict: case FeedbackSlotKind::kStoreKeyedStrict:
case FeedbackSlotKind::kStoreDataPropertyInLiteral: case FeedbackSlotKind::kStoreDataPropertyInLiteral:
case FeedbackSlotKind::kGeneral: case FeedbackSlotKind::kGeneral:
case FeedbackSlotKind::kTypeProfile:
array->set(index, *uninitialized_sentinel, SKIP_WRITE_BARRIER); array->set(index, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
break; break;
...@@ -351,8 +336,7 @@ void FeedbackVector::ClearSlots(JSFunction* host_function) { ...@@ -351,8 +336,7 @@ void FeedbackVector::ClearSlots(JSFunction* host_function) {
break; break;
} }
case FeedbackSlotKind::kCreateClosure: { case FeedbackSlotKind::kCreateClosure: {
case FeedbackSlotKind::kTypeProfile: break;
break;
} }
case FeedbackSlotKind::kGeneral: { case FeedbackSlotKind::kGeneral: {
if (obj->IsHeapObject()) { if (obj->IsHeapObject()) {
...@@ -1039,49 +1023,5 @@ void StoreDataPropertyInLiteralICNexus::ConfigureMonomorphic( ...@@ -1039,49 +1023,5 @@ void StoreDataPropertyInLiteralICNexus::ConfigureMonomorphic(
SetFeedbackExtra(*name); 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++) {
Name* name = Name::cast(list->Get(i));
name->Print();
}
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -36,7 +36,6 @@ enum class FeedbackSlotKind { ...@@ -36,7 +36,6 @@ enum class FeedbackSlotKind {
kCompareOp, kCompareOp,
kToBoolean, kToBoolean,
kStoreDataPropertyInLiteral, kStoreDataPropertyInLiteral,
kTypeProfile,
kCreateClosure, kCreateClosure,
kLiteral, kLiteral,
// This is a general purpose slot that occupies one feedback vector element. // This is a general purpose slot that occupies one feedback vector element.
...@@ -151,11 +150,6 @@ class FeedbackVectorSpecBase { ...@@ -151,11 +150,6 @@ class FeedbackVectorSpecBase {
return AddSlot(FeedbackSlotKind::kStoreDataPropertyInLiteral); return AddSlot(FeedbackSlotKind::kStoreDataPropertyInLiteral);
} }
FeedbackSlot AddTypeProfileSlot() {
DCHECK(FLAG_type_profile);
return AddSlot(FeedbackSlotKind::kTypeProfile);
}
#ifdef OBJECT_PRINT #ifdef OBJECT_PRINT
// For gdb debugging. // For gdb debugging.
void Print(); void Print();
...@@ -256,8 +250,6 @@ class FeedbackMetadata : public FixedArray { ...@@ -256,8 +250,6 @@ class FeedbackMetadata : public FixedArray {
static const char* Kind2String(FeedbackSlotKind kind); static const char* Kind2String(FeedbackSlotKind kind);
bool HasTypeProfileSlot();
private: private:
static const int kFeedbackSlotKindBits = 5; static const int kFeedbackSlotKindBits = 5;
STATIC_ASSERT(static_cast<int>(FeedbackSlotKind::kKindsNumber) < STATIC_ASSERT(static_cast<int>(FeedbackSlotKind::kKindsNumber) <
...@@ -750,30 +742,6 @@ class StoreDataPropertyInLiteralICNexus : public FeedbackNexus { ...@@ -750,30 +742,6 @@ class StoreDataPropertyInLiteralICNexus : public FeedbackNexus {
InlineCacheState StateFromFeedback() const override; 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 BinaryOperationHint BinaryOperationHintFromFeedback(int type_feedback);
inline CompareOperationHint CompareOperationHintFromFeedback(int type_feedback); inline CompareOperationHint CompareOperationHintFromFeedback(int type_feedback);
......
...@@ -581,7 +581,6 @@ void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map, ...@@ -581,7 +581,6 @@ void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
case FeedbackSlotKind::kLiteral: case FeedbackSlotKind::kLiteral:
case FeedbackSlotKind::kGeneral: case FeedbackSlotKind::kGeneral:
case FeedbackSlotKind::kStoreDataPropertyInLiteral: case FeedbackSlotKind::kStoreDataPropertyInLiteral:
case FeedbackSlotKind::kTypeProfile:
case FeedbackSlotKind::kInvalid: case FeedbackSlotKind::kInvalid:
case FeedbackSlotKind::kKindsNumber: case FeedbackSlotKind::kKindsNumber:
UNREACHABLE(); UNREACHABLE();
...@@ -629,7 +628,6 @@ void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps, ...@@ -629,7 +628,6 @@ void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
case FeedbackSlotKind::kLiteral: case FeedbackSlotKind::kLiteral:
case FeedbackSlotKind::kGeneral: case FeedbackSlotKind::kGeneral:
case FeedbackSlotKind::kStoreDataPropertyInLiteral: case FeedbackSlotKind::kStoreDataPropertyInLiteral:
case FeedbackSlotKind::kTypeProfile:
case FeedbackSlotKind::kInvalid: case FeedbackSlotKind::kInvalid:
case FeedbackSlotKind::kKindsNumber: case FeedbackSlotKind::kKindsNumber:
UNREACHABLE(); UNREACHABLE();
......
...@@ -632,13 +632,6 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreDataPropertyInLiteral( ...@@ -632,13 +632,6 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreDataPropertyInLiteral(
return *this; return *this;
} }
BytecodeArrayBuilder& BytecodeArrayBuilder::CollectTypeProfile(
Register name, int feedback_slot) {
DCHECK(FLAG_type_profile);
OutputCollectTypeProfile(name, feedback_slot);
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
Register object, size_t name_index, int feedback_slot, Register object, size_t name_index, int feedback_slot,
LanguageMode language_mode) { LanguageMode language_mode) {
......
...@@ -137,11 +137,6 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final ...@@ -137,11 +137,6 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
Register object, Register name, DataPropertyInLiteralFlags flags, Register object, Register name, DataPropertyInLiteralFlags flags,
int feedback_slot); 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 // Store a property named by a property name. The value to be stored should be
// in the accumulator. // in the accumulator.
BytecodeArrayBuilder& StoreNamedProperty(Register object, BytecodeArrayBuilder& StoreNamedProperty(Register object,
......
...@@ -2214,34 +2214,18 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -2214,34 +2214,18 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
LhsKind assign_type = Property::GetAssignType(property); LhsKind assign_type = Property::GetAssignType(property);
// Evaluate LHS expression. // Evaluate LHS expression.
Register lhs_name;
if (expr->HasTypeProfileSlot()) {
lhs_name = register_allocator()->NewRegister();
}
switch (assign_type) { switch (assign_type) {
case VARIABLE: case VARIABLE:
if (expr->HasTypeProfileSlot()) {
builder()
->LoadLiteral(expr->target()->AsVariableProxy()->var()->raw_name())
.StoreAccumulatorInRegister(lhs_name);
}
// Nothing to do to evaluate variable assignment LHS. // Nothing to do to evaluate variable assignment LHS.
break; break;
case NAMED_PROPERTY: { case NAMED_PROPERTY: {
object = VisitForRegisterValue(property->obj()); object = VisitForRegisterValue(property->obj());
name = property->key()->AsLiteral()->AsRawPropertyName(); name = property->key()->AsLiteral()->AsRawPropertyName();
if (expr->HasTypeProfileSlot()) {
builder()->LoadLiteral(name).StoreAccumulatorInRegister(lhs_name);
}
break; break;
} }
case KEYED_PROPERTY: { case KEYED_PROPERTY: {
object = VisitForRegisterValue(property->obj()); object = VisitForRegisterValue(property->obj());
key = VisitForRegisterValue(property->key()); key = VisitForRegisterValue(property->key());
if (expr->HasTypeProfileSlot()) {
builder()->StoreAccumulatorInRegister(lhs_name);
}
break; break;
} }
case NAMED_SUPER_PROPERTY: { case NAMED_SUPER_PROPERTY: {
...@@ -2254,9 +2238,6 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -2254,9 +2238,6 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
builder() builder()
->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName()) ->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
.StoreAccumulatorInRegister(super_property_args[2]); .StoreAccumulatorInRegister(super_property_args[2]);
if (expr->HasTypeProfileSlot()) {
builder()->StoreAccumulatorInRegister(lhs_name);
}
break; break;
} }
case KEYED_SUPER_PROPERTY: { case KEYED_SUPER_PROPERTY: {
...@@ -2267,10 +2248,6 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -2267,10 +2248,6 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
VisitForRegisterValue(super_property->home_object(), VisitForRegisterValue(super_property->home_object(),
super_property_args[1]); super_property_args[1]);
VisitForRegisterValue(property->key(), super_property_args[2]); VisitForRegisterValue(property->key(), super_property_args[2]);
if (expr->HasTypeProfileSlot()) {
builder()->StoreAccumulatorInRegister(lhs_name);
}
break; break;
} }
} }
...@@ -2359,14 +2336,6 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -2359,14 +2336,6 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
break; 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) { void BytecodeGenerator::VisitYield(Yield* expr) {
......
...@@ -105,8 +105,6 @@ namespace interpreter { ...@@ -105,8 +105,6 @@ namespace interpreter {
OperandType::kReg, OperandType::kIdx) \ OperandType::kReg, OperandType::kIdx) \
V(StaDataPropertyInLiteral, AccumulatorUse::kRead, OperandType::kReg, \ V(StaDataPropertyInLiteral, AccumulatorUse::kRead, OperandType::kReg, \
OperandType::kReg, OperandType::kFlag8, OperandType::kIdx) \ OperandType::kReg, OperandType::kFlag8, OperandType::kIdx) \
V(CollectTypeProfile, AccumulatorUse::kRead, OperandType::kReg, \
OperandType::kIdx) \
\ \
/* Binary Operators */ \ /* Binary Operators */ \
V(Add, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \ V(Add, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \
......
...@@ -1045,19 +1045,6 @@ void Interpreter::DoStaDataPropertyInLiteral(InterpreterAssembler* assembler) { ...@@ -1045,19 +1045,6 @@ void Interpreter::DoStaDataPropertyInLiteral(InterpreterAssembler* assembler) {
__ Dispatch(); __ 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> // LdaModuleVariable <cell_index> <depth>
// //
// Load the contents of a module variable into the accumulator. The variable is // Load the contents of a module variable into the accumulator. The variable is
......
...@@ -751,7 +751,6 @@ void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT ...@@ -751,7 +751,6 @@ void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT
case FeedbackSlotKind::kCreateClosure: case FeedbackSlotKind::kCreateClosure:
case FeedbackSlotKind::kLiteral: case FeedbackSlotKind::kLiteral:
case FeedbackSlotKind::kGeneral: case FeedbackSlotKind::kGeneral:
case FeedbackSlotKind::kTypeProfile:
break; break;
case FeedbackSlotKind::kToBoolean: case FeedbackSlotKind::kToBoolean:
case FeedbackSlotKind::kInvalid: case FeedbackSlotKind::kInvalid:
......
...@@ -691,32 +691,6 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) { ...@@ -691,32 +691,6 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
return *object; return *object;
} }
RUNTIME_FUNCTION(Runtime_CollectTypeProfile) {
HandleScope scope(isolate);
DCHECK_EQ(4, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, 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);
name->Print();
nexus.Print();
PrintF("\n");
return *name;
}
// Return property without being observable by accessors or interceptors. // Return property without being observable by accessors or interceptors.
RUNTIME_FUNCTION(Runtime_GetDataProperty) { RUNTIME_FUNCTION(Runtime_GetDataProperty) {
HandleScope scope(isolate); HandleScope scope(isolate);
......
...@@ -394,7 +394,6 @@ namespace internal { ...@@ -394,7 +394,6 @@ namespace internal {
F(IsJSGlobalProxy, 1, 1) \ F(IsJSGlobalProxy, 1, 1) \
F(DefineAccessorPropertyUnchecked, 5, 1) \ F(DefineAccessorPropertyUnchecked, 5, 1) \
F(DefineDataPropertyInLiteral, 6, 1) \ F(DefineDataPropertyInLiteral, 6, 1) \
F(CollectTypeProfile, 4, 1) \
F(GetDataProperty, 2, 1) \ F(GetDataProperty, 2, 1) \
F(GetConstructorName, 1, 1) \ F(GetConstructorName, 1, 1) \
F(HasFastPackedElements, 1, 1) \ F(HasFastPackedElements, 1, 1) \
......
#Export
#undefined
#PostDebug
#undefined
#PostExperimentals
#undefined
#g
#undefined
#setTimeout
#Function
#.result
#Function
#attachInspector
#Function
#detachInspector
#Function
#setMaxAsyncTaskStacks
#Function
#breakProgram
#Function
#createObjectWithStrictCheck
#Function
#callWithScheduledBreak
#Function
#allowAccessorFormatting
#Function
#.result
#Function
#Export
#undefined
#PostDebug
#undefined
#PostExperimentals
#undefined
#g
#undefined
#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
// 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) { ...@@ -446,12 +446,6 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
scorecard[Bytecodes::ToByte(Bytecode::kTestNull)] = 1; 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 return occurs at the end and only once in the BytecodeArray.
CHECK_EQ(final_bytecode, Bytecode::kReturn); CHECK_EQ(final_bytecode, Bytecode::kReturn);
CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1); CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment