OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 | 598 |
599 for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) { | 599 for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) { |
600 if (gc_type & gc_prologue_callbacks_[i].gc_type) { | 600 if (gc_type & gc_prologue_callbacks_[i].gc_type) { |
601 gc_prologue_callbacks_[i].callback(gc_type, kNoGCCallbackFlags); | 601 gc_prologue_callbacks_[i].callback(gc_type, kNoGCCallbackFlags); |
602 } | 602 } |
603 } | 603 } |
604 | 604 |
605 EnsureFromSpaceIsCommitted(); | 605 EnsureFromSpaceIsCommitted(); |
606 | 606 |
607 if (collector == MARK_COMPACTOR) { | 607 if (collector == MARK_COMPACTOR) { |
| 608 // Flush all potentially unused code. |
| 609 FlushCode(); |
| 610 |
608 // Perform mark-sweep with optional compaction. | 611 // Perform mark-sweep with optional compaction. |
609 MarkCompact(tracer); | 612 MarkCompact(tracer); |
610 | 613 |
611 int old_gen_size = PromotedSpaceSize(); | 614 int old_gen_size = PromotedSpaceSize(); |
612 old_gen_promotion_limit_ = | 615 old_gen_promotion_limit_ = |
613 old_gen_size + Max(kMinimumPromotionLimit, old_gen_size / 3); | 616 old_gen_size + Max(kMinimumPromotionLimit, old_gen_size / 3); |
614 old_gen_allocation_limit_ = | 617 old_gen_allocation_limit_ = |
615 old_gen_size + Max(kMinimumAllocationLimit, old_gen_size / 2); | 618 old_gen_size + Max(kMinimumAllocationLimit, old_gen_size / 2); |
616 old_gen_exhausted_ = false; | 619 old_gen_exhausted_ = false; |
617 } else { | 620 } else { |
(...skipping 1558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2176 reinterpret_cast<ExternalArray*>(result)->set_map( | 2179 reinterpret_cast<ExternalArray*>(result)->set_map( |
2177 MapForExternalArrayType(array_type)); | 2180 MapForExternalArrayType(array_type)); |
2178 reinterpret_cast<ExternalArray*>(result)->set_length(length); | 2181 reinterpret_cast<ExternalArray*>(result)->set_length(length); |
2179 reinterpret_cast<ExternalArray*>(result)->set_external_pointer( | 2182 reinterpret_cast<ExternalArray*>(result)->set_external_pointer( |
2180 external_pointer); | 2183 external_pointer); |
2181 | 2184 |
2182 return result; | 2185 return result; |
2183 } | 2186 } |
2184 | 2187 |
2185 | 2188 |
| 2189 // The StackVisitor is used to traverse all the archived threads to see if |
| 2190 // there are activations on any of the stacks corresponding to the code. |
| 2191 class FlushingStackVisitor : public ThreadVisitor { |
| 2192 public: |
| 2193 explicit FlushingStackVisitor(Code* code) : found_(false), code_(code) {} |
| 2194 |
| 2195 void VisitThread(ThreadLocalTop* top) { |
| 2196 // If we already found the code in a previous traversed thread we return. |
| 2197 if (found_) return; |
| 2198 |
| 2199 for (StackFrameIterator it(top); !it.done(); it.Advance()) { |
| 2200 if (code_->contains(it.frame()->pc())) { |
| 2201 found_ = true; |
| 2202 return; |
| 2203 } |
| 2204 } |
| 2205 } |
| 2206 bool FoundCode() {return found_;} |
| 2207 |
| 2208 private: |
| 2209 bool found_; |
| 2210 Code* code_; |
| 2211 }; |
| 2212 |
| 2213 |
| 2214 static void FlushCodeForFunction(SharedFunctionInfo* function_info) { |
| 2215 // The function must be compiled and have the source code available, |
| 2216 // to be able to recompile it in case we need the function again. |
| 2217 if (!(function_info->is_compiled() && function_info->HasSourceCode())) return; |
| 2218 |
| 2219 // We never flush code for Api functions. |
| 2220 if (function_info->IsApiFunction()) return; |
| 2221 |
| 2222 // Only flush code for functions. |
| 2223 if (!function_info->code()->kind() == Code::FUNCTION) return; |
| 2224 |
| 2225 // Function must be lazy compilable. |
| 2226 if (!function_info->allows_lazy_compilation()) return; |
| 2227 |
| 2228 // If this is a full script wrapped in a function we do no flush the code. |
| 2229 if (function_info->is_toplevel()) return; |
| 2230 |
| 2231 // If this function is in the compilation cache we do not flush the code. |
| 2232 if (CompilationCache::HasFunction(function_info)) return; |
| 2233 |
| 2234 // Make sure we are not referencing the code from the stack. |
| 2235 for (StackFrameIterator it; !it.done(); it.Advance()) { |
| 2236 if (function_info->code()->contains(it.frame()->pc())) return; |
| 2237 } |
| 2238 // Iterate the archived stacks in all threads to check if |
| 2239 // the code is referenced. |
| 2240 FlushingStackVisitor threadvisitor(function_info->code()); |
| 2241 ThreadManager::IterateArchivedThreads(&threadvisitor); |
| 2242 if (threadvisitor.FoundCode()) return; |
| 2243 |
| 2244 HandleScope scope; |
| 2245 // Compute the lazy compilable version of the code. |
| 2246 function_info->set_code(*ComputeLazyCompile(function_info->length())); |
| 2247 } |
| 2248 |
| 2249 |
| 2250 void Heap::FlushCode() { |
| 2251 // Do not flush code if the debugger is loaded or there are breakpoints. |
| 2252 if (Debug::IsLoaded() || Debug::has_break_points()) return; |
| 2253 HeapObjectIterator it(old_pointer_space()); |
| 2254 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) { |
| 2255 if (obj->IsJSFunction()) { |
| 2256 JSFunction* jsfunction = JSFunction::cast(obj); |
| 2257 |
| 2258 // The function must have a valid context and not be a builtin. |
| 2259 if (jsfunction->unchecked_context()->IsContext() && |
| 2260 !jsfunction->IsBuiltin()) { |
| 2261 FlushCodeForFunction(jsfunction->shared()); |
| 2262 } |
| 2263 } |
| 2264 } |
| 2265 } |
| 2266 |
| 2267 |
2186 Object* Heap::CreateCode(const CodeDesc& desc, | 2268 Object* Heap::CreateCode(const CodeDesc& desc, |
2187 ZoneScopeInfo* sinfo, | 2269 ZoneScopeInfo* sinfo, |
2188 Code::Flags flags, | 2270 Code::Flags flags, |
2189 Handle<Object> self_reference) { | 2271 Handle<Object> self_reference) { |
2190 // Compute size | 2272 // Compute size |
2191 int body_size = RoundUp(desc.instr_size + desc.reloc_size, kObjectAlignment); | 2273 int body_size = RoundUp(desc.instr_size + desc.reloc_size, kObjectAlignment); |
2192 int sinfo_size = 0; | 2274 int sinfo_size = 0; |
2193 if (sinfo != NULL) sinfo_size = sinfo->Serialize(NULL); | 2275 if (sinfo != NULL) sinfo_size = sinfo->Serialize(NULL); |
2194 int obj_size = Code::SizeFor(body_size, sinfo_size); | 2276 int obj_size = Code::SizeFor(body_size, sinfo_size); |
2195 ASSERT(IsAligned(obj_size, Code::kCodeAlignment)); | 2277 ASSERT(IsAligned(obj_size, Code::kCodeAlignment)); |
(...skipping 2457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4653 void ExternalStringTable::TearDown() { | 4735 void ExternalStringTable::TearDown() { |
4654 new_space_strings_.Free(); | 4736 new_space_strings_.Free(); |
4655 old_space_strings_.Free(); | 4737 old_space_strings_.Free(); |
4656 } | 4738 } |
4657 | 4739 |
4658 | 4740 |
4659 List<Object*> ExternalStringTable::new_space_strings_; | 4741 List<Object*> ExternalStringTable::new_space_strings_; |
4660 List<Object*> ExternalStringTable::old_space_strings_; | 4742 List<Object*> ExternalStringTable::old_space_strings_; |
4661 | 4743 |
4662 } } // namespace v8::internal | 4744 } } // namespace v8::internal |
OLD | NEW |