| 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 1873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1884 | 1884 |
| 1885 | 1885 |
| 1886 Object* Heap::AllocateSharedFunctionInfo(Object* name) { | 1886 Object* Heap::AllocateSharedFunctionInfo(Object* name) { |
| 1887 Object* result = Allocate(shared_function_info_map(), OLD_POINTER_SPACE); | 1887 Object* result = Allocate(shared_function_info_map(), OLD_POINTER_SPACE); |
| 1888 if (result->IsFailure()) return result; | 1888 if (result->IsFailure()) return result; |
| 1889 | 1889 |
| 1890 SharedFunctionInfo* share = SharedFunctionInfo::cast(result); | 1890 SharedFunctionInfo* share = SharedFunctionInfo::cast(result); |
| 1891 share->set_name(name); | 1891 share->set_name(name); |
| 1892 Code* illegal = Builtins::builtin(Builtins::Illegal); | 1892 Code* illegal = Builtins::builtin(Builtins::Illegal); |
| 1893 share->set_code(illegal); | 1893 share->set_code(illegal); |
| 1894 share->set_scope_info(ScopeInfo<>::EmptyHeapObject()); |
| 1894 Code* construct_stub = Builtins::builtin(Builtins::JSConstructStubGeneric); | 1895 Code* construct_stub = Builtins::builtin(Builtins::JSConstructStubGeneric); |
| 1895 share->set_construct_stub(construct_stub); | 1896 share->set_construct_stub(construct_stub); |
| 1896 share->set_expected_nof_properties(0); | 1897 share->set_expected_nof_properties(0); |
| 1897 share->set_length(0); | 1898 share->set_length(0); |
| 1898 share->set_formal_parameter_count(0); | 1899 share->set_formal_parameter_count(0); |
| 1899 share->set_instance_class_name(Object_symbol()); | 1900 share->set_instance_class_name(Object_symbol()); |
| 1900 share->set_function_data(undefined_value()); | 1901 share->set_function_data(undefined_value()); |
| 1901 share->set_script(undefined_value()); | 1902 share->set_script(undefined_value()); |
| 1902 share->set_start_position_and_type(0); | 1903 share->set_start_position_and_type(0); |
| 1903 share->set_debug_info(undefined_value()); | 1904 share->set_debug_info(undefined_value()); |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2311 } | 2312 } |
| 2312 // Iterate the archived stacks in all threads to check if | 2313 // Iterate the archived stacks in all threads to check if |
| 2313 // the code is referenced. | 2314 // the code is referenced. |
| 2314 FlushingStackVisitor threadvisitor(function_info->code()); | 2315 FlushingStackVisitor threadvisitor(function_info->code()); |
| 2315 ThreadManager::IterateArchivedThreads(&threadvisitor); | 2316 ThreadManager::IterateArchivedThreads(&threadvisitor); |
| 2316 if (threadvisitor.FoundCode()) return; | 2317 if (threadvisitor.FoundCode()) return; |
| 2317 | 2318 |
| 2318 // Check that there are heap allocated locals in the scopeinfo. If | 2319 // Check that there are heap allocated locals in the scopeinfo. If |
| 2319 // there is, we are potentially using eval and need the scopeinfo | 2320 // there is, we are potentially using eval and need the scopeinfo |
| 2320 // for variable resolution. | 2321 // for variable resolution. |
| 2321 if (ScopeInfo<>::HasHeapAllocatedLocals(function_info->code())) | 2322 if (ScopeInfo<>::HasHeapAllocatedLocals(function_info->scope_info())) |
| 2322 return; | 2323 return; |
| 2323 | 2324 |
| 2324 HandleScope scope; | 2325 HandleScope scope; |
| 2325 // Compute the lazy compilable version of the code. | 2326 // Compute the lazy compilable version of the code, clear the scope info. |
| 2326 function_info->set_code(*ComputeLazyCompile(function_info->length())); | 2327 function_info->set_code(*ComputeLazyCompile(function_info->length())); |
| 2328 function_info->set_scope_info(ScopeInfo<>::EmptyHeapObject()); |
| 2327 } | 2329 } |
| 2328 | 2330 |
| 2329 | 2331 |
| 2330 void Heap::FlushCode() { | 2332 void Heap::FlushCode() { |
| 2331 #ifdef ENABLE_DEBUGGER_SUPPORT | 2333 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 2332 // Do not flush code if the debugger is loaded or there are breakpoints. | 2334 // Do not flush code if the debugger is loaded or there are breakpoints. |
| 2333 if (Debug::IsLoaded() || Debug::has_break_points()) return; | 2335 if (Debug::IsLoaded() || Debug::has_break_points()) return; |
| 2334 #endif | 2336 #endif |
| 2335 HeapObjectIterator it(old_pointer_space()); | 2337 HeapObjectIterator it(old_pointer_space()); |
| 2336 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) { | 2338 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) { |
| 2337 if (obj->IsJSFunction()) { | 2339 if (obj->IsJSFunction()) { |
| 2338 JSFunction* jsfunction = JSFunction::cast(obj); | 2340 JSFunction* jsfunction = JSFunction::cast(obj); |
| 2339 | 2341 |
| 2340 // The function must have a valid context and not be a builtin. | 2342 // The function must have a valid context and not be a builtin. |
| 2341 if (jsfunction->unchecked_context()->IsContext() && | 2343 if (jsfunction->unchecked_context()->IsContext() && |
| 2342 !jsfunction->IsBuiltin()) { | 2344 !jsfunction->IsBuiltin()) { |
| 2343 FlushCodeForFunction(jsfunction->shared()); | 2345 FlushCodeForFunction(jsfunction->shared()); |
| 2344 } | 2346 } |
| 2345 } | 2347 } |
| 2346 } | 2348 } |
| 2347 } | 2349 } |
| 2348 | 2350 |
| 2349 | 2351 |
| 2350 Object* Heap::CreateCode(const CodeDesc& desc, | 2352 Object* Heap::CreateCode(const CodeDesc& desc, |
| 2351 ZoneScopeInfo* sinfo, | |
| 2352 Code::Flags flags, | 2353 Code::Flags flags, |
| 2353 Handle<Object> self_reference) { | 2354 Handle<Object> self_reference) { |
| 2354 // Allocate ByteArray before the Code object, so that we do not risk | 2355 // Allocate ByteArray before the Code object, so that we do not risk |
| 2355 // leaving uninitialized Code object (and breaking the heap). | 2356 // leaving uninitialized Code object (and breaking the heap). |
| 2356 Object* reloc_info = AllocateByteArray(desc.reloc_size, TENURED); | 2357 Object* reloc_info = AllocateByteArray(desc.reloc_size, TENURED); |
| 2357 if (reloc_info->IsFailure()) return reloc_info; | 2358 if (reloc_info->IsFailure()) return reloc_info; |
| 2358 | 2359 |
| 2359 // Compute size | 2360 // Compute size |
| 2360 int body_size = RoundUp(desc.instr_size, kObjectAlignment); | 2361 int body_size = RoundUp(desc.instr_size, kObjectAlignment); |
| 2361 int sinfo_size = 0; | 2362 int obj_size = Code::SizeFor(body_size); |
| 2362 if (sinfo != NULL) sinfo_size = sinfo->Serialize(NULL); | |
| 2363 int obj_size = Code::SizeFor(body_size, sinfo_size); | |
| 2364 ASSERT(IsAligned(obj_size, Code::kCodeAlignment)); | 2363 ASSERT(IsAligned(obj_size, Code::kCodeAlignment)); |
| 2365 Object* result; | 2364 Object* result; |
| 2366 if (obj_size > MaxObjectSizeInPagedSpace()) { | 2365 if (obj_size > MaxObjectSizeInPagedSpace()) { |
| 2367 result = lo_space_->AllocateRawCode(obj_size); | 2366 result = lo_space_->AllocateRawCode(obj_size); |
| 2368 } else { | 2367 } else { |
| 2369 result = code_space_->AllocateRaw(obj_size); | 2368 result = code_space_->AllocateRaw(obj_size); |
| 2370 } | 2369 } |
| 2371 | 2370 |
| 2372 if (result->IsFailure()) return result; | 2371 if (result->IsFailure()) return result; |
| 2373 | 2372 |
| 2374 // Initialize the object | 2373 // Initialize the object |
| 2375 HeapObject::cast(result)->set_map(code_map()); | 2374 HeapObject::cast(result)->set_map(code_map()); |
| 2376 Code* code = Code::cast(result); | 2375 Code* code = Code::cast(result); |
| 2377 ASSERT(!CodeRange::exists() || CodeRange::contains(code->address())); | 2376 ASSERT(!CodeRange::exists() || CodeRange::contains(code->address())); |
| 2378 code->set_instruction_size(desc.instr_size); | 2377 code->set_instruction_size(desc.instr_size); |
| 2379 code->set_relocation_info(ByteArray::cast(reloc_info)); | 2378 code->set_relocation_info(ByteArray::cast(reloc_info)); |
| 2380 code->set_sinfo_size(sinfo_size); | |
| 2381 code->set_flags(flags); | 2379 code->set_flags(flags); |
| 2382 // Allow self references to created code object by patching the handle to | 2380 // Allow self references to created code object by patching the handle to |
| 2383 // point to the newly allocated Code object. | 2381 // point to the newly allocated Code object. |
| 2384 if (!self_reference.is_null()) { | 2382 if (!self_reference.is_null()) { |
| 2385 *(self_reference.location()) = code; | 2383 *(self_reference.location()) = code; |
| 2386 } | 2384 } |
| 2387 // Migrate generated code. | 2385 // Migrate generated code. |
| 2388 // The generated code can contain Object** values (typically from handles) | 2386 // The generated code can contain Object** values (typically from handles) |
| 2389 // that are dereferenced during the copy to point directly to the actual heap | 2387 // that are dereferenced during the copy to point directly to the actual heap |
| 2390 // objects. These pointers can include references to the code object itself, | 2388 // objects. These pointers can include references to the code object itself, |
| 2391 // through the self_reference parameter. | 2389 // through the self_reference parameter. |
| 2392 code->CopyFrom(desc); | 2390 code->CopyFrom(desc); |
| 2393 if (sinfo != NULL) sinfo->Serialize(code); // write scope info | |
| 2394 | 2391 |
| 2395 #ifdef DEBUG | 2392 #ifdef DEBUG |
| 2396 code->Verify(); | 2393 code->Verify(); |
| 2397 #endif | 2394 #endif |
| 2398 return code; | 2395 return code; |
| 2399 } | 2396 } |
| 2400 | 2397 |
| 2401 | 2398 |
| 2402 Object* Heap::CopyCode(Code* code) { | 2399 Object* Heap::CopyCode(Code* code) { |
| 2403 // Allocate an object the same size as the code object. | 2400 // Allocate an object the same size as the code object. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2424 | 2421 |
| 2425 | 2422 |
| 2426 Object* Heap::CopyCode(Code* code, Vector<byte> reloc_info) { | 2423 Object* Heap::CopyCode(Code* code, Vector<byte> reloc_info) { |
| 2427 // Allocate ByteArray before the Code object, so that we do not risk | 2424 // Allocate ByteArray before the Code object, so that we do not risk |
| 2428 // leaving uninitialized Code object (and breaking the heap). | 2425 // leaving uninitialized Code object (and breaking the heap). |
| 2429 Object* reloc_info_array = AllocateByteArray(reloc_info.length(), TENURED); | 2426 Object* reloc_info_array = AllocateByteArray(reloc_info.length(), TENURED); |
| 2430 if (reloc_info_array->IsFailure()) return reloc_info_array; | 2427 if (reloc_info_array->IsFailure()) return reloc_info_array; |
| 2431 | 2428 |
| 2432 int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment); | 2429 int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment); |
| 2433 | 2430 |
| 2434 int sinfo_size = code->sinfo_size(); | 2431 int new_obj_size = Code::SizeFor(new_body_size); |
| 2435 | |
| 2436 int new_obj_size = Code::SizeFor(new_body_size, sinfo_size); | |
| 2437 | 2432 |
| 2438 Address old_addr = code->address(); | 2433 Address old_addr = code->address(); |
| 2439 | 2434 |
| 2440 size_t relocation_offset = | 2435 size_t relocation_offset = |
| 2441 static_cast<size_t>(code->instruction_end() - old_addr); | 2436 static_cast<size_t>(code->instruction_end() - old_addr); |
| 2442 | 2437 |
| 2443 Object* result; | 2438 Object* result; |
| 2444 if (new_obj_size > MaxObjectSizeInPagedSpace()) { | 2439 if (new_obj_size > MaxObjectSizeInPagedSpace()) { |
| 2445 result = lo_space_->AllocateRawCode(new_obj_size); | 2440 result = lo_space_->AllocateRawCode(new_obj_size); |
| 2446 } else { | 2441 } else { |
| 2447 result = code_space_->AllocateRaw(new_obj_size); | 2442 result = code_space_->AllocateRaw(new_obj_size); |
| 2448 } | 2443 } |
| 2449 | 2444 |
| 2450 if (result->IsFailure()) return result; | 2445 if (result->IsFailure()) return result; |
| 2451 | 2446 |
| 2452 // Copy code object. | 2447 // Copy code object. |
| 2453 Address new_addr = reinterpret_cast<HeapObject*>(result)->address(); | 2448 Address new_addr = reinterpret_cast<HeapObject*>(result)->address(); |
| 2454 | 2449 |
| 2455 // Copy header and instructions. | 2450 // Copy header and instructions. |
| 2456 memcpy(new_addr, old_addr, relocation_offset); | 2451 memcpy(new_addr, old_addr, relocation_offset); |
| 2457 | 2452 |
| 2458 Code* new_code = Code::cast(result); | 2453 Code* new_code = Code::cast(result); |
| 2459 new_code->set_relocation_info(ByteArray::cast(reloc_info_array)); | 2454 new_code->set_relocation_info(ByteArray::cast(reloc_info_array)); |
| 2460 | 2455 |
| 2461 // Copy patched rinfo. | 2456 // Copy patched rinfo. |
| 2462 memcpy(new_code->relocation_start(), reloc_info.start(), reloc_info.length()); | 2457 memcpy(new_code->relocation_start(), reloc_info.start(), reloc_info.length()); |
| 2463 // Copy sinfo. | |
| 2464 memcpy(new_code->sinfo_start(), code->sinfo_start(), code->sinfo_size()); | |
| 2465 | 2458 |
| 2466 // Relocate the copy. | 2459 // Relocate the copy. |
| 2467 ASSERT(!CodeRange::exists() || CodeRange::contains(code->address())); | 2460 ASSERT(!CodeRange::exists() || CodeRange::contains(code->address())); |
| 2468 new_code->Relocate(new_addr - old_addr); | 2461 new_code->Relocate(new_addr - old_addr); |
| 2469 | 2462 |
| 2470 #ifdef DEBUG | 2463 #ifdef DEBUG |
| 2471 code->Verify(); | 2464 code->Verify(); |
| 2472 #endif | 2465 #endif |
| 2473 return new_code; | 2466 return new_code; |
| 2474 } | 2467 } |
| (...skipping 2356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4831 void ExternalStringTable::TearDown() { | 4824 void ExternalStringTable::TearDown() { |
| 4832 new_space_strings_.Free(); | 4825 new_space_strings_.Free(); |
| 4833 old_space_strings_.Free(); | 4826 old_space_strings_.Free(); |
| 4834 } | 4827 } |
| 4835 | 4828 |
| 4836 | 4829 |
| 4837 List<Object*> ExternalStringTable::new_space_strings_; | 4830 List<Object*> ExternalStringTable::new_space_strings_; |
| 4838 List<Object*> ExternalStringTable::old_space_strings_; | 4831 List<Object*> ExternalStringTable::old_space_strings_; |
| 4839 | 4832 |
| 4840 } } // namespace v8::internal | 4833 } } // namespace v8::internal |
| OLD | NEW |