[runtime] Record runtime call stats for Map::TransitionTo*Property, Map::SetPrototype and property deletion to separate buckets.

Review-Url: https://codereview.chromium.org/1973473002
Cr-Commit-Position: refs/heads/master@{#36176}
This commit is contained in:
ishell 2016-05-11 05:59:46 -07:00 committed by Commit bot
parent 61b49b3c09
commit af02c0336d
7 changed files with 78 additions and 15 deletions

View File

@ -1017,6 +1017,7 @@ v8_source_set("v8_base") {
"src/conversions-inl.h",
"src/conversions.cc",
"src/conversions.h",
"src/counters-inl.h",
"src/counters.cc",
"src/counters.h",
"src/crankshaft/compilation-phase.cc",

24
src/counters-inl.h Normal file
View File

@ -0,0 +1,24 @@
// 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.
#ifndef V8_COUNTERS_INL_H_
#define V8_COUNTERS_INL_H_
#include "src/counters.h"
namespace v8 {
namespace internal {
RuntimeCallTimerScope::RuntimeCallTimerScope(
HeapObject* heap_object, RuntimeCallStats::CounterId counter_id) {
if (V8_UNLIKELY(FLAG_runtime_call_stats)) {
isolate_ = heap_object->GetIsolate();
RuntimeCallStats::Enter(isolate_, &timer_, counter_id);
}
}
} // namespace internal
} // namespace v8
#endif // V8_COUNTERS_INL_H_

View File

@ -300,6 +300,10 @@ void RuntimeCallStats::CorrectCurrentCounterId(Isolate* isolate,
void RuntimeCallStats::Print(std::ostream& os) {
RuntimeCallStatEntries entries;
#define PRINT_COUNTER(name) entries.Add(&this->name);
FOR_EACH_MANUAL_COUNTER(PRINT_COUNTER)
#undef PRINT_COUNTER
#define PRINT_COUNTER(name, nargs, ressize) entries.Add(&this->Runtime_##name);
FOR_EACH_INTRINSIC(PRINT_COUNTER)
#undef PRINT_COUNTER
@ -312,10 +316,6 @@ void RuntimeCallStats::Print(std::ostream& os) {
FOR_EACH_HANDLER_COUNTER(PRINT_COUNTER)
#undef PRINT_COUNTER
entries.Add(&this->ExternalCallback);
entries.Add(&this->GC);
entries.Add(&this->UnexpectedStubMiss);
entries.Print(os);
}

View File

@ -520,6 +520,20 @@ class RuntimeCallTimer {
base::ElapsedTimer timer_;
};
#define FOR_EACH_MANUAL_COUNTER(V) \
/* Counter for runtime callbacks into JavaScript. */ \
V(ExternalCallback) \
V(GC) \
/* Dummy counter for the unexpected stub miss. */ \
V(UnexpectedStubMiss) \
V(PrototypeMap_TransitionToAccessorProperty) \
V(PrototypeMap_TransitionToDataProperty) \
V(Map_TransitionToAccessorProperty) \
V(Map_TransitionToDataProperty) \
V(Map_SetPrototype) \
V(PrototypeObject_DeleteProperty) \
V(Object_DeleteProperty)
#define FOR_EACH_HANDLER_COUNTER(V) \
V(IC_HandlerCacheHit) \
V(KeyedLoadIC_LoadIndexedStringStub) \
@ -564,12 +578,10 @@ class RuntimeCallStats {
public:
typedef RuntimeCallCounter RuntimeCallStats::*CounterId;
// Dummy counter for the unexpected stub miss.
RuntimeCallCounter UnexpectedStubMiss =
RuntimeCallCounter("UnexpectedStubMiss");
// Counter for runtime callbacks into JavaScript.
RuntimeCallCounter ExternalCallback = RuntimeCallCounter("ExternalCallback");
RuntimeCallCounter GC = RuntimeCallCounter("GC");
#define CALL_RUNTIME_COUNTER(name) \
RuntimeCallCounter name = RuntimeCallCounter(#name);
FOR_EACH_MANUAL_COUNTER(CALL_RUNTIME_COUNTER)
#undef CALL_RUNTIME_COUNTER
#define CALL_RUNTIME_COUNTER(name, nargs, ressize) \
RuntimeCallCounter Runtime_##name = RuntimeCallCounter(#name);
FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER)
@ -622,13 +634,18 @@ class RuntimeCallStats {
// the time of C++ scope.
class RuntimeCallTimerScope {
public:
inline explicit RuntimeCallTimerScope(
Isolate* isolate, RuntimeCallStats::CounterId counter_id) {
inline RuntimeCallTimerScope(Isolate* isolate,
RuntimeCallStats::CounterId counter_id) {
if (V8_UNLIKELY(FLAG_runtime_call_stats)) {
isolate_ = isolate;
RuntimeCallStats::Enter(isolate_, &timer_, counter_id);
}
}
// This constructor is here just to avoid calling GetIsolate() when the
// stats are disabled and the isolate is not directly available.
inline RuntimeCallTimerScope(HeapObject* heap_object,
RuntimeCallStats::CounterId counter_id);
inline ~RuntimeCallTimerScope() {
if (V8_UNLIKELY(FLAG_runtime_call_stats)) {
RuntimeCallStats::Leave(isolate_, &timer_);

View File

@ -352,9 +352,14 @@ void LookupIterator::Delete() {
ElementsAccessor* accessor = object->GetElementsAccessor();
accessor->Delete(object, number_);
} else {
PropertyNormalizationMode mode = holder->map()->is_prototype_map()
? KEEP_INOBJECT_PROPERTIES
: CLEAR_INOBJECT_PROPERTIES;
bool is_prototype_map = holder->map()->is_prototype_map();
RuntimeCallTimerScope stats_scope(
isolate_, is_prototype_map
? &RuntimeCallStats::PrototypeObject_DeleteProperty
: &RuntimeCallStats::Object_DeleteProperty);
PropertyNormalizationMode mode =
is_prototype_map ? KEEP_INOBJECT_PROPERTIES : CLEAR_INOBJECT_PROPERTIES;
if (holder->HasFastProperties()) {
JSObject::NormalizeProperties(Handle<JSObject>::cast(holder), mode, 0,

View File

@ -22,6 +22,8 @@
#include "src/codegen.h"
#include "src/compilation-dependencies.h"
#include "src/compiler.h"
#include "src/counters-inl.h"
#include "src/counters.h"
#include "src/date.h"
#include "src/debug/debug.h"
#include "src/deoptimizer.h"
@ -9018,6 +9020,11 @@ Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
StoreFromKeyed store_mode) {
RuntimeCallTimerScope stats_scope(
*map, map->is_prototype_map()
? &RuntimeCallStats::PrototypeMap_TransitionToDataProperty
: &RuntimeCallStats::Map_TransitionToDataProperty);
DCHECK(name->IsUniqueName());
DCHECK(!map->is_dictionary_map());
@ -9098,6 +9105,12 @@ Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map,
Handle<Object> getter,
Handle<Object> setter,
PropertyAttributes attributes) {
RuntimeCallTimerScope stats_scope(
isolate,
map->is_prototype_map()
? &RuntimeCallStats::PrototypeMap_TransitionToAccessorProperty
: &RuntimeCallStats::Map_TransitionToAccessorProperty);
// At least one of the accessors needs to be a new value.
DCHECK(!getter->IsNull() || !setter->IsNull());
DCHECK(name->IsUniqueName());
@ -11667,6 +11680,8 @@ Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
// static
void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype,
PrototypeOptimizationMode proto_mode) {
RuntimeCallTimerScope stats_scope(*map, &RuntimeCallStats::Map_SetPrototype);
bool is_hidden = false;
if (prototype->IsJSObject()) {
Handle<JSObject> prototype_jsobj = Handle<JSObject>::cast(prototype);

View File

@ -685,6 +685,7 @@
'conversions-inl.h',
'conversions.cc',
'conversions.h',
'counters-inl.h',
'counters.cc',
'counters.h',
'crankshaft/compilation-phase.cc',