OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 4029 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4040 return elements; | 4040 return elements; |
4041 } | 4041 } |
4042 | 4042 |
4043 | 4043 |
4044 MaybeObject* Heap::CreateCode(const CodeDesc& desc, | 4044 MaybeObject* Heap::CreateCode(const CodeDesc& desc, |
4045 Code::Flags flags, | 4045 Code::Flags flags, |
4046 Handle<Object> self_reference, | 4046 Handle<Object> self_reference, |
4047 bool immovable, | 4047 bool immovable, |
4048 bool crankshafted, | 4048 bool crankshafted, |
4049 int prologue_offset) { | 4049 int prologue_offset) { |
4050 // Allocate ByteArray and ConstantPoolArray before the Code object, so that we | 4050 // Allocate ByteArray before the Code object, so that we do not risk |
4051 // do not risk leaving uninitialized Code object (and breaking the heap). | 4051 // leaving uninitialized Code object (and breaking the heap). |
4052 ByteArray* reloc_info; | 4052 ByteArray* reloc_info; |
4053 MaybeObject* maybe_reloc_info = AllocateByteArray(desc.reloc_size, TENURED); | 4053 MaybeObject* maybe_reloc_info = AllocateByteArray(desc.reloc_size, TENURED); |
4054 if (!maybe_reloc_info->To(&reloc_info)) return maybe_reloc_info; | 4054 if (!maybe_reloc_info->To(&reloc_info)) return maybe_reloc_info; |
4055 | 4055 |
4056 ConstantPoolArray* constant_pool; | |
4057 if (FLAG_enable_ool_constant_pool) { | |
4058 MaybeObject* maybe_constant_pool = desc.origin->AllocateConstantPool(this); | |
4059 if (!maybe_constant_pool->To(&constant_pool)) return maybe_constant_pool; | |
4060 } else { | |
4061 constant_pool = empty_constant_pool_array(); | |
4062 } | |
4063 | |
4064 // Compute size. | 4056 // Compute size. |
4065 int body_size = RoundUp(desc.instr_size, kObjectAlignment); | 4057 int body_size = RoundUp(desc.instr_size, kObjectAlignment); |
4066 int obj_size = Code::SizeFor(body_size); | 4058 int obj_size = Code::SizeFor(body_size); |
4067 ASSERT(IsAligned(static_cast<intptr_t>(obj_size), kCodeAlignment)); | 4059 ASSERT(IsAligned(static_cast<intptr_t>(obj_size), kCodeAlignment)); |
4068 MaybeObject* maybe_result; | 4060 MaybeObject* maybe_result; |
4069 // Large code objects and code objects which should stay at a fixed address | 4061 // Large code objects and code objects which should stay at a fixed address |
4070 // are allocated in large object space. | 4062 // are allocated in large object space. |
4071 HeapObject* result; | 4063 HeapObject* result; |
4072 bool force_lo_space = obj_size > code_space()->AreaSize(); | 4064 bool force_lo_space = obj_size > code_space()->AreaSize(); |
4073 if (force_lo_space) { | 4065 if (force_lo_space) { |
(...skipping 26 matching lines...) Expand all Loading... |
4100 code->set_is_crankshafted(crankshafted); | 4092 code->set_is_crankshafted(crankshafted); |
4101 code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER); | 4093 code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER); |
4102 code->set_raw_type_feedback_info(undefined_value()); | 4094 code->set_raw_type_feedback_info(undefined_value()); |
4103 code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER); | 4095 code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER); |
4104 code->set_gc_metadata(Smi::FromInt(0)); | 4096 code->set_gc_metadata(Smi::FromInt(0)); |
4105 code->set_ic_age(global_ic_age_); | 4097 code->set_ic_age(global_ic_age_); |
4106 code->set_prologue_offset(prologue_offset); | 4098 code->set_prologue_offset(prologue_offset); |
4107 if (code->kind() == Code::OPTIMIZED_FUNCTION) { | 4099 if (code->kind() == Code::OPTIMIZED_FUNCTION) { |
4108 code->set_marked_for_deoptimization(false); | 4100 code->set_marked_for_deoptimization(false); |
4109 } | 4101 } |
4110 | 4102 code->set_constant_pool(empty_constant_pool_array()); |
4111 if (FLAG_enable_ool_constant_pool) { | |
4112 desc.origin->PopulateConstantPool(constant_pool); | |
4113 } | |
4114 code->set_constant_pool(constant_pool); | |
4115 | 4103 |
4116 #ifdef ENABLE_DEBUGGER_SUPPORT | 4104 #ifdef ENABLE_DEBUGGER_SUPPORT |
4117 if (code->kind() == Code::FUNCTION) { | 4105 if (code->kind() == Code::FUNCTION) { |
4118 code->set_has_debug_break_slots( | 4106 code->set_has_debug_break_slots( |
4119 isolate_->debugger()->IsDebuggerActive()); | 4107 isolate_->debugger()->IsDebuggerActive()); |
4120 } | 4108 } |
4121 #endif | 4109 #endif |
4122 | 4110 |
4123 // Allow self references to created code object by patching the handle to | 4111 // Allow self references to created code object by patching the handle to |
4124 // point to the newly allocated Code object. | 4112 // point to the newly allocated Code object. |
(...skipping 10 matching lines...) Expand all Loading... |
4135 #ifdef VERIFY_HEAP | 4123 #ifdef VERIFY_HEAP |
4136 if (FLAG_verify_heap) { | 4124 if (FLAG_verify_heap) { |
4137 code->Verify(); | 4125 code->Verify(); |
4138 } | 4126 } |
4139 #endif | 4127 #endif |
4140 return code; | 4128 return code; |
4141 } | 4129 } |
4142 | 4130 |
4143 | 4131 |
4144 MaybeObject* Heap::CopyCode(Code* code) { | 4132 MaybeObject* Heap::CopyCode(Code* code) { |
4145 MaybeObject* maybe_result; | |
4146 Object* new_constant_pool; | |
4147 if (FLAG_enable_ool_constant_pool && | |
4148 code->constant_pool() != empty_constant_pool_array()) { | |
4149 // Copy the constant pool, since edits to the copied code may modify | |
4150 // the constant pool. | |
4151 maybe_result = CopyConstantPoolArray(code->constant_pool()); | |
4152 if (!maybe_result->ToObject(&new_constant_pool)) return maybe_result; | |
4153 } else { | |
4154 new_constant_pool = empty_constant_pool_array(); | |
4155 } | |
4156 | |
4157 // Allocate an object the same size as the code object. | 4133 // Allocate an object the same size as the code object. |
4158 int obj_size = code->Size(); | 4134 int obj_size = code->Size(); |
| 4135 MaybeObject* maybe_result; |
4159 if (obj_size > code_space()->AreaSize()) { | 4136 if (obj_size > code_space()->AreaSize()) { |
4160 maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE); | 4137 maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE); |
4161 } else { | 4138 } else { |
4162 maybe_result = AllocateRaw(obj_size, CODE_SPACE, CODE_SPACE); | 4139 maybe_result = AllocateRaw(obj_size, CODE_SPACE, CODE_SPACE); |
4163 } | 4140 } |
4164 | 4141 |
4165 Object* result; | 4142 Object* result; |
4166 if (!maybe_result->ToObject(&result)) return maybe_result; | 4143 if (!maybe_result->ToObject(&result)) return maybe_result; |
4167 | 4144 |
4168 // Copy code object. | 4145 // Copy code object. |
4169 Address old_addr = code->address(); | 4146 Address old_addr = code->address(); |
4170 Address new_addr = reinterpret_cast<HeapObject*>(result)->address(); | 4147 Address new_addr = reinterpret_cast<HeapObject*>(result)->address(); |
4171 CopyBlock(new_addr, old_addr, obj_size); | 4148 CopyBlock(new_addr, old_addr, obj_size); |
| 4149 // Relocate the copy. |
4172 Code* new_code = Code::cast(result); | 4150 Code* new_code = Code::cast(result); |
4173 | |
4174 // Update the constant pool. | |
4175 new_code->set_constant_pool(new_constant_pool); | |
4176 | |
4177 // Relocate the copy. | |
4178 ASSERT(!isolate_->code_range()->exists() || | 4151 ASSERT(!isolate_->code_range()->exists() || |
4179 isolate_->code_range()->contains(code->address())); | 4152 isolate_->code_range()->contains(code->address())); |
4180 new_code->Relocate(new_addr - old_addr); | 4153 new_code->Relocate(new_addr - old_addr); |
4181 return new_code; | 4154 return new_code; |
4182 } | 4155 } |
4183 | 4156 |
4184 | 4157 |
4185 MaybeObject* Heap::CopyCode(Code* code, Vector<byte> reloc_info) { | 4158 MaybeObject* Heap::CopyCode(Code* code, Vector<byte> reloc_info) { |
4186 // Allocate ByteArray and ConstantPoolArray before the Code object, so that we | 4159 // Allocate ByteArray before the Code object, so that we do not risk |
4187 // do not risk leaving uninitialized Code object (and breaking the heap). | 4160 // leaving uninitialized Code object (and breaking the heap). |
4188 Object* reloc_info_array; | 4161 Object* reloc_info_array; |
4189 { MaybeObject* maybe_reloc_info_array = | 4162 { MaybeObject* maybe_reloc_info_array = |
4190 AllocateByteArray(reloc_info.length(), TENURED); | 4163 AllocateByteArray(reloc_info.length(), TENURED); |
4191 if (!maybe_reloc_info_array->ToObject(&reloc_info_array)) { | 4164 if (!maybe_reloc_info_array->ToObject(&reloc_info_array)) { |
4192 return maybe_reloc_info_array; | 4165 return maybe_reloc_info_array; |
4193 } | 4166 } |
4194 } | 4167 } |
4195 Object* new_constant_pool; | |
4196 if (FLAG_enable_ool_constant_pool && | |
4197 code->constant_pool() != empty_constant_pool_array()) { | |
4198 // Copy the constant pool, since edits to the copied code may modify | |
4199 // the constant pool. | |
4200 MaybeObject* maybe_constant_pool = | |
4201 CopyConstantPoolArray(code->constant_pool()); | |
4202 if (!maybe_constant_pool->ToObject(&new_constant_pool)) | |
4203 return maybe_constant_pool; | |
4204 } else { | |
4205 new_constant_pool = empty_constant_pool_array(); | |
4206 } | |
4207 | 4168 |
4208 int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment); | 4169 int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment); |
4209 | 4170 |
4210 int new_obj_size = Code::SizeFor(new_body_size); | 4171 int new_obj_size = Code::SizeFor(new_body_size); |
4211 | 4172 |
4212 Address old_addr = code->address(); | 4173 Address old_addr = code->address(); |
4213 | 4174 |
4214 size_t relocation_offset = | 4175 size_t relocation_offset = |
4215 static_cast<size_t>(code->instruction_end() - old_addr); | 4176 static_cast<size_t>(code->instruction_end() - old_addr); |
4216 | 4177 |
4217 MaybeObject* maybe_result; | 4178 MaybeObject* maybe_result; |
4218 if (new_obj_size > code_space()->AreaSize()) { | 4179 if (new_obj_size > code_space()->AreaSize()) { |
4219 maybe_result = lo_space_->AllocateRaw(new_obj_size, EXECUTABLE); | 4180 maybe_result = lo_space_->AllocateRaw(new_obj_size, EXECUTABLE); |
4220 } else { | 4181 } else { |
4221 maybe_result = AllocateRaw(new_obj_size, CODE_SPACE, CODE_SPACE); | 4182 maybe_result = AllocateRaw(new_obj_size, CODE_SPACE, CODE_SPACE); |
4222 } | 4183 } |
4223 | 4184 |
4224 Object* result; | 4185 Object* result; |
4225 if (!maybe_result->ToObject(&result)) return maybe_result; | 4186 if (!maybe_result->ToObject(&result)) return maybe_result; |
4226 | 4187 |
4227 // Copy code object. | 4188 // Copy code object. |
4228 Address new_addr = reinterpret_cast<HeapObject*>(result)->address(); | 4189 Address new_addr = reinterpret_cast<HeapObject*>(result)->address(); |
4229 | 4190 |
4230 // Copy header and instructions. | 4191 // Copy header and instructions. |
4231 CopyBytes(new_addr, old_addr, relocation_offset); | 4192 CopyBytes(new_addr, old_addr, relocation_offset); |
4232 | 4193 |
4233 Code* new_code = Code::cast(result); | 4194 Code* new_code = Code::cast(result); |
4234 new_code->set_relocation_info(ByteArray::cast(reloc_info_array)); | 4195 new_code->set_relocation_info(ByteArray::cast(reloc_info_array)); |
4235 | 4196 |
4236 // Update constant pool. | |
4237 new_code->set_constant_pool(new_constant_pool); | |
4238 | |
4239 // Copy patched rinfo. | 4197 // Copy patched rinfo. |
4240 CopyBytes(new_code->relocation_start(), | 4198 CopyBytes(new_code->relocation_start(), |
4241 reloc_info.start(), | 4199 reloc_info.start(), |
4242 static_cast<size_t>(reloc_info.length())); | 4200 static_cast<size_t>(reloc_info.length())); |
4243 | 4201 |
4244 // Relocate the copy. | 4202 // Relocate the copy. |
4245 ASSERT(!isolate_->code_range()->exists() || | 4203 ASSERT(!isolate_->code_range()->exists() || |
4246 isolate_->code_range()->contains(code->address())); | 4204 isolate_->code_range()->contains(code->address())); |
4247 new_code->Relocate(new_addr - old_addr); | 4205 new_code->Relocate(new_addr - old_addr); |
4248 | 4206 |
(...skipping 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5345 if (number_of_code_ptr_entries > 0) { | 5303 if (number_of_code_ptr_entries > 0) { |
5346 int offset = | 5304 int offset = |
5347 constant_pool->OffsetOfElementAt(constant_pool->first_code_ptr_index()); | 5305 constant_pool->OffsetOfElementAt(constant_pool->first_code_ptr_index()); |
5348 MemsetPointer( | 5306 MemsetPointer( |
5349 reinterpret_cast<Address*>(HeapObject::RawField(constant_pool, offset)), | 5307 reinterpret_cast<Address*>(HeapObject::RawField(constant_pool, offset)), |
5350 isolate()->builtins()->builtin(Builtins::kIllegal)->entry(), | 5308 isolate()->builtins()->builtin(Builtins::kIllegal)->entry(), |
5351 number_of_code_ptr_entries); | 5309 number_of_code_ptr_entries); |
5352 } | 5310 } |
5353 if (number_of_heap_ptr_entries > 0) { | 5311 if (number_of_heap_ptr_entries > 0) { |
5354 int offset = | 5312 int offset = |
5355 constant_pool->OffsetOfElementAt(constant_pool->first_heap_ptr_index()); | 5313 constant_pool->OffsetOfElementAt(constant_pool->first_code_ptr_index()); |
5356 MemsetPointer( | 5314 MemsetPointer( |
5357 HeapObject::RawField(constant_pool, offset), | 5315 HeapObject::RawField(constant_pool, offset), |
5358 undefined_value(), | 5316 undefined_value(), |
5359 number_of_heap_ptr_entries); | 5317 number_of_heap_ptr_entries); |
5360 } | 5318 } |
5361 return constant_pool; | 5319 return constant_pool; |
5362 } | 5320 } |
5363 | 5321 |
5364 | 5322 |
5365 MaybeObject* Heap::AllocateEmptyConstantPoolArray() { | 5323 MaybeObject* Heap::AllocateEmptyConstantPoolArray() { |
(...skipping 2427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7793 static_cast<int>(object_sizes_last_time_[index])); | 7751 static_cast<int>(object_sizes_last_time_[index])); |
7794 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) | 7752 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) |
7795 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 7753 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
7796 | 7754 |
7797 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 7755 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
7798 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 7756 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
7799 ClearObjectStats(); | 7757 ClearObjectStats(); |
7800 } | 7758 } |
7801 | 7759 |
7802 } } // namespace v8::internal | 7760 } } // namespace v8::internal |
OLD | NEW |