Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: src/profile-generator.cc

Issue 3409002: Add support for abortion in v8::OutputStream. (Closed)
Patch Set: Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/profile-generator.h ('k') | test/cctest/test-heap-profiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2122 matching lines...) Expand 10 before | Expand all | Expand 10 after
2133 return diff; 2133 return diff;
2134 } 2134 }
2135 2135
2136 2136
2137 class OutputStreamWriter { 2137 class OutputStreamWriter {
2138 public: 2138 public:
2139 explicit OutputStreamWriter(v8::OutputStream* stream) 2139 explicit OutputStreamWriter(v8::OutputStream* stream)
2140 : stream_(stream), 2140 : stream_(stream),
2141 chunk_size_(stream->GetChunkSize()), 2141 chunk_size_(stream->GetChunkSize()),
2142 chunk_(chunk_size_), 2142 chunk_(chunk_size_),
2143 chunk_pos_(0) { 2143 chunk_pos_(0),
2144 aborted_(false) {
2144 ASSERT(chunk_size_ > 0); 2145 ASSERT(chunk_size_ > 0);
2145 } 2146 }
2147 bool aborted() { return aborted_; }
2146 void AddCharacter(char c) { 2148 void AddCharacter(char c) {
2147 ASSERT(c != '\0'); 2149 ASSERT(c != '\0');
2148 ASSERT(chunk_pos_ < chunk_size_); 2150 ASSERT(chunk_pos_ < chunk_size_);
2149 chunk_[chunk_pos_++] = c; 2151 chunk_[chunk_pos_++] = c;
2150 MaybeWriteChunk(); 2152 MaybeWriteChunk();
2151 } 2153 }
2152 void AddString(const char* s) { 2154 void AddString(const char* s) {
2153 AddSubstring(s, StrLength(s)); 2155 AddSubstring(s, StrLength(s));
2154 } 2156 }
2155 void AddSubstring(const char* s, int n) { 2157 void AddSubstring(const char* s, int n) {
2156 if (n <= 0) return; 2158 if (n <= 0) return;
2157 ASSERT(static_cast<size_t>(n) <= strlen(s)); 2159 ASSERT(static_cast<size_t>(n) <= strlen(s));
2158 const char* s_end = s + n; 2160 const char* s_end = s + n;
2159 while (s < s_end) { 2161 while (s < s_end) {
2160 int s_chunk_size = Min( 2162 int s_chunk_size = Min(
2161 chunk_size_ - chunk_pos_, static_cast<int>(s_end - s)); 2163 chunk_size_ - chunk_pos_, static_cast<int>(s_end - s));
2162 ASSERT(s_chunk_size > 0); 2164 ASSERT(s_chunk_size > 0);
2163 memcpy(chunk_.start() + chunk_pos_, s, s_chunk_size); 2165 memcpy(chunk_.start() + chunk_pos_, s, s_chunk_size);
2164 s += s_chunk_size; 2166 s += s_chunk_size;
2165 chunk_pos_ += s_chunk_size; 2167 chunk_pos_ += s_chunk_size;
2166 MaybeWriteChunk(); 2168 MaybeWriteChunk();
2167 } 2169 }
2168 } 2170 }
2169 void AddNumber(int n) { AddNumberImpl<int>(n, "%d"); } 2171 void AddNumber(int n) { AddNumberImpl<int>(n, "%d"); }
2170 void AddNumber(unsigned n) { AddNumberImpl<unsigned>(n, "%u"); } 2172 void AddNumber(unsigned n) { AddNumberImpl<unsigned>(n, "%u"); }
2171 void AddNumber(uint64_t n) { AddNumberImpl<uint64_t>(n, "%llu"); } 2173 void AddNumber(uint64_t n) { AddNumberImpl<uint64_t>(n, "%llu"); }
2172 void Finalize() { 2174 void Finalize() {
2175 if (aborted_) return;
2173 ASSERT(chunk_pos_ < chunk_size_); 2176 ASSERT(chunk_pos_ < chunk_size_);
2174 if (chunk_pos_ != 0) { 2177 if (chunk_pos_ != 0) {
2175 WriteChunk(); 2178 WriteChunk();
2176 } 2179 }
2177 stream_->EndOfStream(); 2180 stream_->EndOfStream();
2178 } 2181 }
2179 2182
2180 private: 2183 private:
2181 template<typename T> 2184 template<typename T>
2182 void AddNumberImpl(T n, const char* format) { 2185 void AddNumberImpl(T n, const char* format) {
2183 ScopedVector<char> buffer(32); 2186 ScopedVector<char> buffer(32);
2184 int result = OS::SNPrintF(buffer, format, n); 2187 int result = OS::SNPrintF(buffer, format, n);
2185 USE(result); 2188 USE(result);
2186 ASSERT(result != -1); 2189 ASSERT(result != -1);
2187 AddString(buffer.start()); 2190 AddString(buffer.start());
2188 } 2191 }
2189 void MaybeWriteChunk() { 2192 void MaybeWriteChunk() {
2190 ASSERT(chunk_pos_ <= chunk_size_); 2193 ASSERT(chunk_pos_ <= chunk_size_);
2191 if (chunk_pos_ == chunk_size_) { 2194 if (chunk_pos_ == chunk_size_) {
2192 WriteChunk(); 2195 WriteChunk();
2193 chunk_pos_ = 0; 2196 chunk_pos_ = 0;
2194 } 2197 }
2195 } 2198 }
2196 void WriteChunk() { 2199 void WriteChunk() {
2197 stream_->WriteAsciiChunk(chunk_.start(), chunk_pos_); 2200 if (aborted_) return;
2201 if (stream_->WriteAsciiChunk(chunk_.start(), chunk_pos_) ==
2202 v8::OutputStream::kAbort) aborted_ = true;
2198 } 2203 }
2199 2204
2200 v8::OutputStream* stream_; 2205 v8::OutputStream* stream_;
2201 int chunk_size_; 2206 int chunk_size_;
2202 ScopedVector<char> chunk_; 2207 ScopedVector<char> chunk_;
2203 int chunk_pos_; 2208 int chunk_pos_;
2209 bool aborted_;
2204 }; 2210 };
2205 2211
2206 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) { 2212 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) {
2207 ASSERT(writer_ == NULL); 2213 ASSERT(writer_ == NULL);
2208 writer_ = new OutputStreamWriter(stream); 2214 writer_ = new OutputStreamWriter(stream);
2209 2215
2210 // Since nodes graph is cyclic, we need the first pass to enumerate 2216 // Since nodes graph is cyclic, we need the first pass to enumerate
2211 // them. Strings can be serialized in one pass. 2217 // them. Strings can be serialized in one pass.
2212 EnumerateNodes(); 2218 EnumerateNodes();
2213 2219 SerializeImpl();
2214 writer_->AddCharacter('{'); 2220
2215 writer_->AddString("\"snapshot\":{");
2216 SerializeSnapshot();
2217 writer_->AddString("},\n");
2218 writer_->AddString("\"nodes\":[");
2219 SerializeNodes();
2220 writer_->AddString("],\n");
2221 writer_->AddString("\"strings\":[");
2222 SerializeStrings();
2223 writer_->AddCharacter(']');
2224 writer_->AddCharacter('}');
2225 writer_->Finalize();
2226
2227 delete writer_; 2221 delete writer_;
2228 writer_ = NULL; 2222 writer_ = NULL;
2229 } 2223 }
2230 2224
2231 2225
2226 void HeapSnapshotJSONSerializer::SerializeImpl() {
2227 writer_->AddCharacter('{');
2228 writer_->AddString("\"snapshot\":{");
2229 SerializeSnapshot();
2230 if (writer_->aborted()) return;
2231 writer_->AddString("},\n");
2232 writer_->AddString("\"nodes\":[");
2233 SerializeNodes();
2234 if (writer_->aborted()) return;
2235 writer_->AddString("],\n");
2236 writer_->AddString("\"strings\":[");
2237 SerializeStrings();
2238 if (writer_->aborted()) return;
2239 writer_->AddCharacter(']');
2240 writer_->AddCharacter('}');
2241 writer_->Finalize();
2242 }
2243
2244
2232 class HeapSnapshotJSONSerializerEnumerator { 2245 class HeapSnapshotJSONSerializerEnumerator {
2233 public: 2246 public:
2234 explicit HeapSnapshotJSONSerializerEnumerator(HeapSnapshotJSONSerializer* s) 2247 explicit HeapSnapshotJSONSerializerEnumerator(HeapSnapshotJSONSerializer* s)
2235 : s_(s) { 2248 : s_(s) {
2236 } 2249 }
2237 void Apply(HeapEntry** entry) { 2250 void Apply(HeapEntry** entry) {
2238 s_->GetNodeId(*entry); 2251 s_->GetNodeId(*entry);
2239 } 2252 }
2240 private: 2253 private:
2241 HeapSnapshotJSONSerializer* s_; 2254 HeapSnapshotJSONSerializer* s_;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2289 writer_->AddNumber(GetStringId(entry->name())); 2302 writer_->AddNumber(GetStringId(entry->name()));
2290 writer_->AddCharacter(','); 2303 writer_->AddCharacter(',');
2291 writer_->AddNumber(entry->id()); 2304 writer_->AddNumber(entry->id());
2292 writer_->AddCharacter(','); 2305 writer_->AddCharacter(',');
2293 writer_->AddNumber(entry->self_size()); 2306 writer_->AddNumber(entry->self_size());
2294 Vector<HeapGraphEdge> children = entry->children(); 2307 Vector<HeapGraphEdge> children = entry->children();
2295 writer_->AddCharacter(','); 2308 writer_->AddCharacter(',');
2296 writer_->AddNumber(children.length()); 2309 writer_->AddNumber(children.length());
2297 for (int i = 0; i < children.length(); ++i) { 2310 for (int i = 0; i < children.length(); ++i) {
2298 SerializeEdge(&children[i]); 2311 SerializeEdge(&children[i]);
2312 if (writer_->aborted()) return;
2299 } 2313 }
2300 } 2314 }
2301 2315
2302 2316
2303 void HeapSnapshotJSONSerializer::SerializeNodes() { 2317 void HeapSnapshotJSONSerializer::SerializeNodes() {
2304 // The first (zero) item of nodes array is a JSON-ified object 2318 // The first (zero) item of nodes array is a JSON-ified object
2305 // describing node serialization layout. 2319 // describing node serialization layout.
2306 // We use a set of macros to improve readability. 2320 // We use a set of macros to improve readability.
2307 #define JSON_A(s) "["s"]" 2321 #define JSON_A(s) "["s"]"
2308 #define JSON_O(s) "{"s"}" 2322 #define JSON_O(s) "{"s"}"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2356 for (int i = 1; i < sorted_nodes.length(); ++i) { 2370 for (int i = 1; i < sorted_nodes.length(); ++i) {
2357 HeapEntry* prev_heap_entry = 2371 HeapEntry* prev_heap_entry =
2358 reinterpret_cast<HeapEntry*>(sorted_nodes[i-1]->key); 2372 reinterpret_cast<HeapEntry*>(sorted_nodes[i-1]->key);
2359 prev_value += node_fields_count + 2373 prev_value += node_fields_count +
2360 prev_heap_entry->children().length() * edge_fields_count; 2374 prev_heap_entry->children().length() * edge_fields_count;
2361 sorted_nodes[i]->value = reinterpret_cast<void*>(prev_value); 2375 sorted_nodes[i]->value = reinterpret_cast<void*>(prev_value);
2362 } 2376 }
2363 } 2377 }
2364 for (int i = 0; i < sorted_nodes.length(); ++i) { 2378 for (int i = 0; i < sorted_nodes.length(); ++i) {
2365 SerializeNode(reinterpret_cast<HeapEntry*>(sorted_nodes[i]->key)); 2379 SerializeNode(reinterpret_cast<HeapEntry*>(sorted_nodes[i]->key));
2380 if (writer_->aborted()) return;
2366 } 2381 }
2367 } 2382 }
2368 2383
2369 2384
2370 void HeapSnapshotJSONSerializer::SerializeSnapshot() { 2385 void HeapSnapshotJSONSerializer::SerializeSnapshot() {
2371 writer_->AddString("\"title\":\""); 2386 writer_->AddString("\"title\":\"");
2372 writer_->AddString(snapshot_->title()); 2387 writer_->AddString(snapshot_->title());
2373 writer_->AddString("\""); 2388 writer_->AddString("\"");
2374 writer_->AddString(",\"uid\":"); 2389 writer_->AddString(",\"uid\":");
2375 writer_->AddNumber(snapshot_->uid()); 2390 writer_->AddNumber(snapshot_->uid());
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2436 2451
2437 2452
2438 void HeapSnapshotJSONSerializer::SerializeStrings() { 2453 void HeapSnapshotJSONSerializer::SerializeStrings() {
2439 List<HashMap::Entry*> sorted_strings; 2454 List<HashMap::Entry*> sorted_strings;
2440 SortHashMap(&strings_, &sorted_strings); 2455 SortHashMap(&strings_, &sorted_strings);
2441 writer_->AddString("\"<dummy>\""); 2456 writer_->AddString("\"<dummy>\"");
2442 for (int i = 0; i < sorted_strings.length(); ++i) { 2457 for (int i = 0; i < sorted_strings.length(); ++i) {
2443 writer_->AddCharacter(','); 2458 writer_->AddCharacter(',');
2444 SerializeString( 2459 SerializeString(
2445 reinterpret_cast<const unsigned char*>(sorted_strings[i]->key)); 2460 reinterpret_cast<const unsigned char*>(sorted_strings[i]->key));
2461 if (writer_->aborted()) return;
2446 } 2462 }
2447 } 2463 }
2448 2464
2449 2465
2450 template<typename T> 2466 template<typename T>
2451 inline static int SortUsingEntryValue(const T* x, const T* y) { 2467 inline static int SortUsingEntryValue(const T* x, const T* y) {
2452 return reinterpret_cast<intptr_t>((*x)->value) - 2468 return reinterpret_cast<intptr_t>((*x)->value) -
2453 reinterpret_cast<intptr_t>((*y)->value); 2469 reinterpret_cast<intptr_t>((*y)->value);
2454 } 2470 }
2455 2471
2456 void HeapSnapshotJSONSerializer::SortHashMap( 2472 void HeapSnapshotJSONSerializer::SortHashMap(
2457 HashMap* map, List<HashMap::Entry*>* sorted_entries) { 2473 HashMap* map, List<HashMap::Entry*>* sorted_entries) {
2458 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) 2474 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p))
2459 sorted_entries->Add(p); 2475 sorted_entries->Add(p);
2460 sorted_entries->Sort(SortUsingEntryValue); 2476 sorted_entries->Sort(SortUsingEntryValue);
2461 } 2477 }
2462 2478
2463 } } // namespace v8::internal 2479 } } // namespace v8::internal
2464 2480
2465 #endif // ENABLE_LOGGING_AND_PROFILING 2481 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW
« no previous file with comments | « src/profile-generator.h ('k') | test/cctest/test-heap-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698