00001 #include "slate.hpp"
00002
00003 void profiler_start(struct object_heap* oh) {
00004 oh->currentlyProfiling = 1;
00005 oh->profilerTimeStart = getRealTimeClock();
00006 oh->profilerTime = oh->profilerTimeStart;
00007 oh->profilerLastTime = oh->profilerTimeStart;
00008 oh->profiledMethods.clear();
00009 oh->profilerCallCounts.clear();
00010 oh->profilerSelfTime.clear();
00011
00012 oh->profilerChildCallCount.clear();
00013 oh->profilerChildCallTime.clear();
00014
00015 oh->profilerCallStack.clear();
00016 oh->profilerCallStackTimes.clear();
00017
00018
00019 }
00020
00021
00022 void profiler_stop(struct object_heap* oh) {
00023 oh->currentlyProfiling = 0;
00024 }
00025
00026
00027
00028 void profiler_enter_method(struct object_heap* oh, struct Object* fromMethod, struct Object* toMethod, bool_t push) {
00029 if (!oh->currentlyProfiling) return;
00030
00031
00032
00033
00034 oh->profilerTime = getRealTimeClock();
00035 word_t timeDiff = oh->profilerTime - oh->profilerLastTime;
00036
00037 oh->profiledMethods.insert(toMethod);
00038
00039
00040 oh->profilerSelfTime[fromMethod] += timeDiff;
00041
00042 if (push) {
00043 oh->profilerCallCounts[toMethod] += 1;
00044 oh->profilerCallStack.push_back(toMethod);
00045 oh->profilerCallStackTimes.push_back(oh->profilerTime);
00046
00047 } else {
00048
00049 struct Object* parent;
00050 word_t callStartTime;
00051 struct Object* callMethod;
00052 do {
00053 callStartTime = oh->profilerCallStackTimes.back();
00054 callMethod = oh->profilerCallStack.back();
00055 oh->profilerCallStackTimes.pop_back();
00056 oh->profilerCallStack.pop_back();
00057
00058 parent = oh->profilerCallStack.back();
00059
00060
00061 word_t callTimeDiff = oh->profilerTime - callStartTime;
00062 if (oh->profilerChildCallTime.find(parent) == oh->profilerChildCallTime.end()) {
00063 oh->profilerChildCallTime[parent][callMethod] = callTimeDiff;
00064 } else {
00065 oh->profilerChildCallTime[parent][callMethod] += callTimeDiff;
00066 }
00067
00068 if (oh->profilerChildCallCount.find(parent) == oh->profilerChildCallCount.end()) {
00069 oh->profilerChildCallCount[parent][callMethod] = 1;
00070 } else {
00071 oh->profilerChildCallCount[parent][callMethod] += 1;
00072 }
00073
00074
00075 } while(callMethod != fromMethod && !oh->profilerCallStack.empty());
00076
00077 assert(callMethod == fromMethod || !oh->profilerCallStack.empty());
00078
00079
00080 }
00081
00082 oh->profilerLastTime = oh->profilerTime;
00083 }
00084
00085 void profiler_notice_forwarded_object(struct object_heap* oh, struct Object* from, struct Object* to) {
00086 if (!oh->currentlyProfiling) return;
00087
00088 if (oh->profiledMethods.find(from) == oh->profiledMethods.end()) return;
00089 oh->profiledMethods.erase(from); oh->profiledMethods.insert(to);
00090
00091 oh->profilerSelfTime[to] = oh->profilerSelfTime[from];
00092 oh->profilerSelfTime.erase(from);
00093
00094 oh->profilerCallCounts[to] = oh->profilerCallCounts[from];
00095 oh->profilerCallCounts.erase(from);
00096
00097
00098 for (std::map<struct Object*, std::map<struct Object*,word_t> >::iterator i = oh->profilerChildCallCount.begin();
00099 i != oh->profilerChildCallCount.end(); i++) {
00100 std::map<struct Object*,word_t>& childSet = (*i).second;
00101 if (childSet.find(from) != childSet.end()) {
00102 childSet[to] = childSet[from];
00103 childSet.erase(from);
00104 }
00105 }
00106 for (std::map<struct Object*, std::map<struct Object*,word_t> >::iterator i = oh->profilerChildCallTime.begin();
00107 i != oh->profilerChildCallTime.end(); i++) {
00108 std::map<struct Object*,word_t>& childSet = (*i).second;
00109 if (childSet.find(from) != childSet.end()) {
00110 childSet[to] = childSet[from];
00111 childSet.erase(from);
00112 }
00113 }
00114
00115 for (size_t i = 0; i < oh->profilerCallStack.size(); i++) {
00116 if (oh->profilerCallStack[i] == from) oh->profilerCallStack[i] = to;
00117 }
00118
00119
00120 }
00121
00122
00123 void profiler_delete_method(struct object_heap* oh, struct Object* method) {
00124 if (!oh->currentlyProfiling) return;
00125
00126 oh->profiledMethods.erase(method);
00127 oh->profilerSelfTime.erase(method);
00128 oh->profilerCallCounts.erase(method);
00129
00130 for (std::map<struct Object*, std::map<struct Object*,word_t> >::iterator i = oh->profilerChildCallCount.begin();
00131 i != oh->profilerChildCallCount.end(); i++) {
00132 (*i).second.erase(method);
00133 }
00134 for (std::map<struct Object*, std::map<struct Object*,word_t> >::iterator i = oh->profilerChildCallTime.begin();
00135 i != oh->profilerChildCallTime.end(); i++) {
00136 (*i).second.erase(method);
00137 }
00138
00139 for (size_t i = 0; i < oh->profilerCallStack.size(); i++) {
00140 if (oh->profilerCallStack[i] == method) oh->profilerCallStack[i] = oh->cached.nil;
00141 }
00142
00143 }
00144
00145