| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 2180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2191 ASSERT(current_page->next_page()->is_valid()); | 2191 ASSERT(current_page->next_page()->is_valid()); |
| 2192 Page* next_page = current_page->next_page(); | 2192 Page* next_page = current_page->next_page(); |
| 2193 next_page->ClearGCFields(); | 2193 next_page->ClearGCFields(); |
| 2194 PutRestOfCurrentPageOnFreeList(current_page); | 2194 PutRestOfCurrentPageOnFreeList(current_page); |
| 2195 SetAllocationInfo(&allocation_info_, next_page); | 2195 SetAllocationInfo(&allocation_info_, next_page); |
| 2196 return AllocateLinearly(&allocation_info_, size_in_bytes); | 2196 return AllocateLinearly(&allocation_info_, size_in_bytes); |
| 2197 } | 2197 } |
| 2198 | 2198 |
| 2199 | 2199 |
| 2200 #ifdef DEBUG | 2200 #ifdef DEBUG |
| 2201 struct CommentStatistic { | |
| 2202 const char* comment; | |
| 2203 int size; | |
| 2204 int count; | |
| 2205 void Clear() { | |
| 2206 comment = NULL; | |
| 2207 size = 0; | |
| 2208 count = 0; | |
| 2209 } | |
| 2210 }; | |
| 2211 | |
| 2212 | |
| 2213 // must be small, since an iteration is used for lookup | |
| 2214 const int kMaxComments = 64; | |
| 2215 static CommentStatistic comments_statistics[kMaxComments+1]; | |
| 2216 | |
| 2217 | |
| 2218 void PagedSpace::ReportCodeStatistics() { | 2201 void PagedSpace::ReportCodeStatistics() { |
| 2202 Isolate* isolate = Isolate::Current(); |
| 2203 CommentStatistic* comments_statistics = |
| 2204 isolate->paged_space_comments_statistics(); |
| 2219 ReportCodeKindStatistics(); | 2205 ReportCodeKindStatistics(); |
| 2220 PrintF("Code comment statistics (\" [ comment-txt : size/ " | 2206 PrintF("Code comment statistics (\" [ comment-txt : size/ " |
| 2221 "count (average)\"):\n"); | 2207 "count (average)\"):\n"); |
| 2222 for (int i = 0; i <= kMaxComments; i++) { | 2208 for (int i = 0; i <= CommentStatistic::kMaxComments; i++) { |
| 2223 const CommentStatistic& cs = comments_statistics[i]; | 2209 const CommentStatistic& cs = comments_statistics[i]; |
| 2224 if (cs.size > 0) { | 2210 if (cs.size > 0) { |
| 2225 PrintF(" %-30s: %10d/%6d (%d)\n", cs.comment, cs.size, cs.count, | 2211 PrintF(" %-30s: %10d/%6d (%d)\n", cs.comment, cs.size, cs.count, |
| 2226 cs.size/cs.count); | 2212 cs.size/cs.count); |
| 2227 } | 2213 } |
| 2228 } | 2214 } |
| 2229 PrintF("\n"); | 2215 PrintF("\n"); |
| 2230 } | 2216 } |
| 2231 | 2217 |
| 2232 | 2218 |
| 2233 void PagedSpace::ResetCodeStatistics() { | 2219 void PagedSpace::ResetCodeStatistics() { |
| 2220 Isolate* isolate = Isolate::Current(); |
| 2221 CommentStatistic* comments_statistics = |
| 2222 isolate->paged_space_comments_statistics(); |
| 2234 ClearCodeKindStatistics(); | 2223 ClearCodeKindStatistics(); |
| 2235 for (int i = 0; i < kMaxComments; i++) comments_statistics[i].Clear(); | 2224 for (int i = 0; i < CommentStatistic::kMaxComments; i++) { |
| 2236 comments_statistics[kMaxComments].comment = "Unknown"; | 2225 comments_statistics[i].Clear(); |
| 2237 comments_statistics[kMaxComments].size = 0; | 2226 } |
| 2238 comments_statistics[kMaxComments].count = 0; | 2227 comments_statistics[CommentStatistic::kMaxComments].comment = "Unknown"; |
| 2228 comments_statistics[CommentStatistic::kMaxComments].size = 0; |
| 2229 comments_statistics[CommentStatistic::kMaxComments].count = 0; |
| 2239 } | 2230 } |
| 2240 | 2231 |
| 2241 | 2232 |
| 2242 // Adds comment to 'comment_statistics' table. Performance OK sa long as | 2233 // Adds comment to 'comment_statistics' table. Performance OK as long as |
| 2243 // 'kMaxComments' is small | 2234 // 'kMaxComments' is small |
| 2244 static void EnterComment(const char* comment, int delta) { | 2235 static void EnterComment(Isolate* isolate, const char* comment, int delta) { |
| 2236 CommentStatistic* comments_statistics = |
| 2237 isolate->paged_space_comments_statistics(); |
| 2245 // Do not count empty comments | 2238 // Do not count empty comments |
| 2246 if (delta <= 0) return; | 2239 if (delta <= 0) return; |
| 2247 CommentStatistic* cs = &comments_statistics[kMaxComments]; | 2240 CommentStatistic* cs = &comments_statistics[CommentStatistic::kMaxComments]; |
| 2248 // Search for a free or matching entry in 'comments_statistics': 'cs' | 2241 // Search for a free or matching entry in 'comments_statistics': 'cs' |
| 2249 // points to result. | 2242 // points to result. |
| 2250 for (int i = 0; i < kMaxComments; i++) { | 2243 for (int i = 0; i < CommentStatistic::kMaxComments; i++) { |
| 2251 if (comments_statistics[i].comment == NULL) { | 2244 if (comments_statistics[i].comment == NULL) { |
| 2252 cs = &comments_statistics[i]; | 2245 cs = &comments_statistics[i]; |
| 2253 cs->comment = comment; | 2246 cs->comment = comment; |
| 2254 break; | 2247 break; |
| 2255 } else if (strcmp(comments_statistics[i].comment, comment) == 0) { | 2248 } else if (strcmp(comments_statistics[i].comment, comment) == 0) { |
| 2256 cs = &comments_statistics[i]; | 2249 cs = &comments_statistics[i]; |
| 2257 break; | 2250 break; |
| 2258 } | 2251 } |
| 2259 } | 2252 } |
| 2260 // Update entry for 'comment' | 2253 // Update entry for 'comment' |
| 2261 cs->size += delta; | 2254 cs->size += delta; |
| 2262 cs->count += 1; | 2255 cs->count += 1; |
| 2263 } | 2256 } |
| 2264 | 2257 |
| 2265 | 2258 |
| 2266 // Call for each nested comment start (start marked with '[ xxx', end marked | 2259 // Call for each nested comment start (start marked with '[ xxx', end marked |
| 2267 // with ']'. RelocIterator 'it' must point to a comment reloc info. | 2260 // with ']'. RelocIterator 'it' must point to a comment reloc info. |
| 2268 static void CollectCommentStatistics(RelocIterator* it) { | 2261 static void CollectCommentStatistics(Isolate* isolate, RelocIterator* it) { |
| 2269 ASSERT(!it->done()); | 2262 ASSERT(!it->done()); |
| 2270 ASSERT(it->rinfo()->rmode() == RelocInfo::COMMENT); | 2263 ASSERT(it->rinfo()->rmode() == RelocInfo::COMMENT); |
| 2271 const char* tmp = reinterpret_cast<const char*>(it->rinfo()->data()); | 2264 const char* tmp = reinterpret_cast<const char*>(it->rinfo()->data()); |
| 2272 if (tmp[0] != '[') { | 2265 if (tmp[0] != '[') { |
| 2273 // Not a nested comment; skip | 2266 // Not a nested comment; skip |
| 2274 return; | 2267 return; |
| 2275 } | 2268 } |
| 2276 | 2269 |
| 2277 // Search for end of nested comment or a new nested comment | 2270 // Search for end of nested comment or a new nested comment |
| 2278 const char* const comment_txt = | 2271 const char* const comment_txt = |
| 2279 reinterpret_cast<const char*>(it->rinfo()->data()); | 2272 reinterpret_cast<const char*>(it->rinfo()->data()); |
| 2280 const byte* prev_pc = it->rinfo()->pc(); | 2273 const byte* prev_pc = it->rinfo()->pc(); |
| 2281 int flat_delta = 0; | 2274 int flat_delta = 0; |
| 2282 it->next(); | 2275 it->next(); |
| 2283 while (true) { | 2276 while (true) { |
| 2284 // All nested comments must be terminated properly, and therefore exit | 2277 // All nested comments must be terminated properly, and therefore exit |
| 2285 // from loop. | 2278 // from loop. |
| 2286 ASSERT(!it->done()); | 2279 ASSERT(!it->done()); |
| 2287 if (it->rinfo()->rmode() == RelocInfo::COMMENT) { | 2280 if (it->rinfo()->rmode() == RelocInfo::COMMENT) { |
| 2288 const char* const txt = | 2281 const char* const txt = |
| 2289 reinterpret_cast<const char*>(it->rinfo()->data()); | 2282 reinterpret_cast<const char*>(it->rinfo()->data()); |
| 2290 flat_delta += static_cast<int>(it->rinfo()->pc() - prev_pc); | 2283 flat_delta += static_cast<int>(it->rinfo()->pc() - prev_pc); |
| 2291 if (txt[0] == ']') break; // End of nested comment | 2284 if (txt[0] == ']') break; // End of nested comment |
| 2292 // A new comment | 2285 // A new comment |
| 2293 CollectCommentStatistics(it); | 2286 CollectCommentStatistics(isolate, it); |
| 2294 // Skip code that was covered with previous comment | 2287 // Skip code that was covered with previous comment |
| 2295 prev_pc = it->rinfo()->pc(); | 2288 prev_pc = it->rinfo()->pc(); |
| 2296 } | 2289 } |
| 2297 it->next(); | 2290 it->next(); |
| 2298 } | 2291 } |
| 2299 EnterComment(comment_txt, flat_delta); | 2292 EnterComment(isolate, comment_txt, flat_delta); |
| 2300 } | 2293 } |
| 2301 | 2294 |
| 2302 | 2295 |
| 2303 // Collects code size statistics: | 2296 // Collects code size statistics: |
| 2304 // - by code kind | 2297 // - by code kind |
| 2305 // - by code comment | 2298 // - by code comment |
| 2306 void PagedSpace::CollectCodeStatistics() { | 2299 void PagedSpace::CollectCodeStatistics() { |
| 2307 Isolate* isolate = Isolate::Current(); | 2300 Isolate* isolate = Isolate::Current(); |
| 2308 HeapObjectIterator obj_it(this); | 2301 HeapObjectIterator obj_it(this); |
| 2309 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { | 2302 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { |
| 2310 if (obj->IsCode()) { | 2303 if (obj->IsCode()) { |
| 2311 Code* code = Code::cast(obj); | 2304 Code* code = Code::cast(obj); |
| 2312 isolate->code_kind_statistics()[code->kind()] += code->Size(); | 2305 isolate->code_kind_statistics()[code->kind()] += code->Size(); |
| 2313 RelocIterator it(code); | 2306 RelocIterator it(code); |
| 2314 int delta = 0; | 2307 int delta = 0; |
| 2315 const byte* prev_pc = code->instruction_start(); | 2308 const byte* prev_pc = code->instruction_start(); |
| 2316 while (!it.done()) { | 2309 while (!it.done()) { |
| 2317 if (it.rinfo()->rmode() == RelocInfo::COMMENT) { | 2310 if (it.rinfo()->rmode() == RelocInfo::COMMENT) { |
| 2318 delta += static_cast<int>(it.rinfo()->pc() - prev_pc); | 2311 delta += static_cast<int>(it.rinfo()->pc() - prev_pc); |
| 2319 CollectCommentStatistics(&it); | 2312 CollectCommentStatistics(isolate, &it); |
| 2320 prev_pc = it.rinfo()->pc(); | 2313 prev_pc = it.rinfo()->pc(); |
| 2321 } | 2314 } |
| 2322 it.next(); | 2315 it.next(); |
| 2323 } | 2316 } |
| 2324 | 2317 |
| 2325 ASSERT(code->instruction_start() <= prev_pc && | 2318 ASSERT(code->instruction_start() <= prev_pc && |
| 2326 prev_pc <= code->relocation_start()); | 2319 prev_pc <= code->relocation_start()); |
| 2327 delta += static_cast<int>(code->relocation_start() - prev_pc); | 2320 delta += static_cast<int>(code->relocation_start() - prev_pc); |
| 2328 EnterComment("NoComment", delta); | 2321 EnterComment(isolate, "NoComment", delta); |
| 2329 } | 2322 } |
| 2330 } | 2323 } |
| 2331 } | 2324 } |
| 2332 | 2325 |
| 2333 | 2326 |
| 2334 void OldSpace::ReportStatistics() { | 2327 void OldSpace::ReportStatistics() { |
| 2335 int pct = Available() * 100 / Capacity(); | 2328 int pct = Available() * 100 / Capacity(); |
| 2336 PrintF(" capacity: %d, waste: %d, available: %d, %%%d\n", | 2329 PrintF(" capacity: %d, waste: %d, available: %d, %%%d\n", |
| 2337 Capacity(), Waste(), Available(), pct); | 2330 Capacity(), Waste(), Available(), pct); |
| 2338 | 2331 |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2911 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { | 2904 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { |
| 2912 if (obj->IsCode()) { | 2905 if (obj->IsCode()) { |
| 2913 Code* code = Code::cast(obj); | 2906 Code* code = Code::cast(obj); |
| 2914 isolate->code_kind_statistics()[code->kind()] += code->Size(); | 2907 isolate->code_kind_statistics()[code->kind()] += code->Size(); |
| 2915 } | 2908 } |
| 2916 } | 2909 } |
| 2917 } | 2910 } |
| 2918 #endif // DEBUG | 2911 #endif // DEBUG |
| 2919 | 2912 |
| 2920 } } // namespace v8::internal | 2913 } } // namespace v8::internal |
| OLD | NEW |