| OLD | NEW |
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
| 6 // met: | 6 // met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 } else if (IsInternalReference(rmode_)) { | 80 } else if (IsInternalReference(rmode_)) { |
| 81 // absolute code pointer inside code object moves with the code object. | 81 // absolute code pointer inside code object moves with the code object. |
| 82 int32_t* p = reinterpret_cast<int32_t*>(pc_); | 82 int32_t* p = reinterpret_cast<int32_t*>(pc_); |
| 83 *p += delta; // Relocate entry. | 83 *p += delta; // Relocate entry. |
| 84 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); | 84 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); |
| 85 } | 85 } |
| 86 } | 86 } |
| 87 | 87 |
| 88 | 88 |
| 89 Address RelocInfo::target_address() { | 89 Address RelocInfo::target_address() { |
| 90 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 90 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
| 91 return Assembler::target_address_at(pc_, host_); | 91 return Assembler::target_address_at(pc_, host_); |
| 92 } | 92 } |
| 93 | 93 |
| 94 | 94 |
| 95 Address RelocInfo::target_address_address() { | 95 Address RelocInfo::target_address_address() { |
| 96 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) | 96 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) |
| 97 || rmode_ == EMBEDDED_OBJECT | 97 || rmode_ == EMBEDDED_OBJECT |
| 98 || rmode_ == EXTERNAL_REFERENCE); | 98 || rmode_ == EXTERNAL_REFERENCE); |
| 99 return reinterpret_cast<Address>(pc_); | 99 return reinterpret_cast<Address>(pc_); |
| 100 } | 100 } |
| 101 | 101 |
| 102 | 102 |
| 103 Address RelocInfo::constant_pool_entry_address() { | 103 Address RelocInfo::constant_pool_entry_address() { |
| 104 UNREACHABLE(); | 104 UNREACHABLE(); |
| 105 return NULL; | 105 return NULL; |
| 106 } | 106 } |
| 107 | 107 |
| 108 | 108 |
| 109 int RelocInfo::target_address_size() { | 109 int RelocInfo::target_address_size() { |
| 110 return Assembler::kSpecialTargetSize; | 110 return Assembler::kSpecialTargetSize; |
| 111 } | 111 } |
| 112 | 112 |
| 113 | 113 |
| 114 void RelocInfo::set_target_address(Address target, | 114 void RelocInfo::set_target_address(Address target, |
| 115 WriteBarrierMode write_barrier_mode, | 115 WriteBarrierMode write_barrier_mode, |
| 116 ICacheFlushMode icache_flush_mode) { | 116 ICacheFlushMode icache_flush_mode) { |
| 117 Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode); | 117 Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode); |
| 118 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 118 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
| 119 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL && | 119 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL && |
| 120 IsCodeTarget(rmode_)) { | 120 IsCodeTarget(rmode_)) { |
| 121 Object* target_code = Code::GetCodeFromTargetAddress(target); | 121 Object* target_code = Code::GetCodeFromTargetAddress(target); |
| 122 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 122 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
| 123 host(), this, HeapObject::cast(target_code)); | 123 host(), this, HeapObject::cast(target_code)); |
| 124 } | 124 } |
| 125 } | 125 } |
| 126 | 126 |
| 127 | 127 |
| 128 Object* RelocInfo::target_object() { | 128 Object* RelocInfo::target_object() { |
| 129 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 129 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
| 130 return Memory::Object_at(pc_); | 130 return Memory::Object_at(pc_); |
| 131 } | 131 } |
| 132 | 132 |
| 133 | 133 |
| 134 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { | 134 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { |
| 135 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 135 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
| 136 return Memory::Object_Handle_at(pc_); | 136 return Memory::Object_Handle_at(pc_); |
| 137 } | 137 } |
| 138 | 138 |
| 139 | 139 |
| 140 void RelocInfo::set_target_object(Object* target, | 140 void RelocInfo::set_target_object(Object* target, |
| 141 WriteBarrierMode write_barrier_mode, | 141 WriteBarrierMode write_barrier_mode, |
| 142 ICacheFlushMode icache_flush_mode) { | 142 ICacheFlushMode icache_flush_mode) { |
| 143 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 143 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
| 144 Memory::Object_at(pc_) = target; | 144 Memory::Object_at(pc_) = target; |
| 145 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 145 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
| 146 CpuFeatures::FlushICache(pc_, sizeof(Address)); | 146 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
| 147 } | 147 } |
| 148 if (write_barrier_mode == UPDATE_WRITE_BARRIER && | 148 if (write_barrier_mode == UPDATE_WRITE_BARRIER && |
| 149 host() != NULL && | 149 host() != NULL && |
| 150 target->IsHeapObject()) { | 150 target->IsHeapObject()) { |
| 151 host()->GetHeap()->incremental_marking()->RecordWrite( | 151 host()->GetHeap()->incremental_marking()->RecordWrite( |
| 152 host(), &Memory::Object_at(pc_), HeapObject::cast(target)); | 152 host(), &Memory::Object_at(pc_), HeapObject::cast(target)); |
| 153 } | 153 } |
| 154 } | 154 } |
| 155 | 155 |
| 156 | 156 |
| 157 Address RelocInfo::target_reference() { | 157 Address RelocInfo::target_reference() { |
| 158 ASSERT(rmode_ == RelocInfo::EXTERNAL_REFERENCE); | 158 DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE); |
| 159 return Memory::Address_at(pc_); | 159 return Memory::Address_at(pc_); |
| 160 } | 160 } |
| 161 | 161 |
| 162 | 162 |
| 163 Address RelocInfo::target_runtime_entry(Assembler* origin) { | 163 Address RelocInfo::target_runtime_entry(Assembler* origin) { |
| 164 ASSERT(IsRuntimeEntry(rmode_)); | 164 DCHECK(IsRuntimeEntry(rmode_)); |
| 165 return reinterpret_cast<Address>(*reinterpret_cast<int32_t*>(pc_)); | 165 return reinterpret_cast<Address>(*reinterpret_cast<int32_t*>(pc_)); |
| 166 } | 166 } |
| 167 | 167 |
| 168 | 168 |
| 169 void RelocInfo::set_target_runtime_entry(Address target, | 169 void RelocInfo::set_target_runtime_entry(Address target, |
| 170 WriteBarrierMode write_barrier_mode, | 170 WriteBarrierMode write_barrier_mode, |
| 171 ICacheFlushMode icache_flush_mode) { | 171 ICacheFlushMode icache_flush_mode) { |
| 172 ASSERT(IsRuntimeEntry(rmode_)); | 172 DCHECK(IsRuntimeEntry(rmode_)); |
| 173 if (target_address() != target) { | 173 if (target_address() != target) { |
| 174 set_target_address(target, write_barrier_mode, icache_flush_mode); | 174 set_target_address(target, write_barrier_mode, icache_flush_mode); |
| 175 } | 175 } |
| 176 } | 176 } |
| 177 | 177 |
| 178 | 178 |
| 179 Handle<Cell> RelocInfo::target_cell_handle() { | 179 Handle<Cell> RelocInfo::target_cell_handle() { |
| 180 ASSERT(rmode_ == RelocInfo::CELL); | 180 DCHECK(rmode_ == RelocInfo::CELL); |
| 181 Address address = Memory::Address_at(pc_); | 181 Address address = Memory::Address_at(pc_); |
| 182 return Handle<Cell>(reinterpret_cast<Cell**>(address)); | 182 return Handle<Cell>(reinterpret_cast<Cell**>(address)); |
| 183 } | 183 } |
| 184 | 184 |
| 185 | 185 |
| 186 Cell* RelocInfo::target_cell() { | 186 Cell* RelocInfo::target_cell() { |
| 187 ASSERT(rmode_ == RelocInfo::CELL); | 187 DCHECK(rmode_ == RelocInfo::CELL); |
| 188 return Cell::FromValueAddress(Memory::Address_at(pc_)); | 188 return Cell::FromValueAddress(Memory::Address_at(pc_)); |
| 189 } | 189 } |
| 190 | 190 |
| 191 | 191 |
| 192 void RelocInfo::set_target_cell(Cell* cell, | 192 void RelocInfo::set_target_cell(Cell* cell, |
| 193 WriteBarrierMode write_barrier_mode, | 193 WriteBarrierMode write_barrier_mode, |
| 194 ICacheFlushMode icache_flush_mode) { | 194 ICacheFlushMode icache_flush_mode) { |
| 195 ASSERT(rmode_ == RelocInfo::CELL); | 195 DCHECK(rmode_ == RelocInfo::CELL); |
| 196 Address address = cell->address() + Cell::kValueOffset; | 196 Address address = cell->address() + Cell::kValueOffset; |
| 197 Memory::Address_at(pc_) = address; | 197 Memory::Address_at(pc_) = address; |
| 198 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 198 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
| 199 CpuFeatures::FlushICache(pc_, sizeof(Address)); | 199 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
| 200 } | 200 } |
| 201 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { | 201 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { |
| 202 // TODO(1550) We are passing NULL as a slot because cell can never be on | 202 // TODO(1550) We are passing NULL as a slot because cell can never be on |
| 203 // evacuation candidate. | 203 // evacuation candidate. |
| 204 host()->GetHeap()->incremental_marking()->RecordWrite( | 204 host()->GetHeap()->incremental_marking()->RecordWrite( |
| 205 host(), NULL, cell); | 205 host(), NULL, cell); |
| 206 } | 206 } |
| 207 } | 207 } |
| 208 | 208 |
| 209 | 209 |
| 210 Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { | 210 Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { |
| 211 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 211 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
| 212 ASSERT(*pc_ == kCallOpcode); | 212 DCHECK(*pc_ == kCallOpcode); |
| 213 return Memory::Object_Handle_at(pc_ + 1); | 213 return Memory::Object_Handle_at(pc_ + 1); |
| 214 } | 214 } |
| 215 | 215 |
| 216 | 216 |
| 217 Code* RelocInfo::code_age_stub() { | 217 Code* RelocInfo::code_age_stub() { |
| 218 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 218 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
| 219 ASSERT(*pc_ == kCallOpcode); | 219 DCHECK(*pc_ == kCallOpcode); |
| 220 return Code::GetCodeFromTargetAddress( | 220 return Code::GetCodeFromTargetAddress( |
| 221 Assembler::target_address_at(pc_ + 1, host_)); | 221 Assembler::target_address_at(pc_ + 1, host_)); |
| 222 } | 222 } |
| 223 | 223 |
| 224 | 224 |
| 225 void RelocInfo::set_code_age_stub(Code* stub, | 225 void RelocInfo::set_code_age_stub(Code* stub, |
| 226 ICacheFlushMode icache_flush_mode) { | 226 ICacheFlushMode icache_flush_mode) { |
| 227 ASSERT(*pc_ == kCallOpcode); | 227 DCHECK(*pc_ == kCallOpcode); |
| 228 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 228 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
| 229 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), | 229 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), |
| 230 icache_flush_mode); | 230 icache_flush_mode); |
| 231 } | 231 } |
| 232 | 232 |
| 233 | 233 |
| 234 Address RelocInfo::call_address() { | 234 Address RelocInfo::call_address() { |
| 235 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 235 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
| 236 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 236 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
| 237 return Assembler::target_address_at(pc_ + 1, host_); | 237 return Assembler::target_address_at(pc_ + 1, host_); |
| 238 } | 238 } |
| 239 | 239 |
| 240 | 240 |
| 241 void RelocInfo::set_call_address(Address target) { | 241 void RelocInfo::set_call_address(Address target) { |
| 242 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 242 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
| 243 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 243 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
| 244 Assembler::set_target_address_at(pc_ + 1, host_, target); | 244 Assembler::set_target_address_at(pc_ + 1, host_, target); |
| 245 if (host() != NULL) { | 245 if (host() != NULL) { |
| 246 Object* target_code = Code::GetCodeFromTargetAddress(target); | 246 Object* target_code = Code::GetCodeFromTargetAddress(target); |
| 247 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 247 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
| 248 host(), this, HeapObject::cast(target_code)); | 248 host(), this, HeapObject::cast(target_code)); |
| 249 } | 249 } |
| 250 } | 250 } |
| 251 | 251 |
| 252 | 252 |
| 253 Object* RelocInfo::call_object() { | 253 Object* RelocInfo::call_object() { |
| 254 return *call_object_address(); | 254 return *call_object_address(); |
| 255 } | 255 } |
| 256 | 256 |
| 257 | 257 |
| 258 void RelocInfo::set_call_object(Object* target) { | 258 void RelocInfo::set_call_object(Object* target) { |
| 259 *call_object_address() = target; | 259 *call_object_address() = target; |
| 260 } | 260 } |
| 261 | 261 |
| 262 | 262 |
| 263 Object** RelocInfo::call_object_address() { | 263 Object** RelocInfo::call_object_address() { |
| 264 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 264 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
| 265 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 265 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
| 266 return reinterpret_cast<Object**>(pc_ + 1); | 266 return reinterpret_cast<Object**>(pc_ + 1); |
| 267 } | 267 } |
| 268 | 268 |
| 269 | 269 |
| 270 void RelocInfo::WipeOut() { | 270 void RelocInfo::WipeOut() { |
| 271 if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_)) { | 271 if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_)) { |
| 272 Memory::Address_at(pc_) = NULL; | 272 Memory::Address_at(pc_) = NULL; |
| 273 } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { | 273 } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { |
| 274 // Effectively write zero into the relocation. | 274 // Effectively write zero into the relocation. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 x_ = reinterpret_cast<int32_t>(internal_offset); | 359 x_ = reinterpret_cast<int32_t>(internal_offset); |
| 360 rmode_ = RelocInfo::INTERNAL_REFERENCE; | 360 rmode_ = RelocInfo::INTERNAL_REFERENCE; |
| 361 } | 361 } |
| 362 | 362 |
| 363 | 363 |
| 364 Immediate::Immediate(Handle<Object> handle) { | 364 Immediate::Immediate(Handle<Object> handle) { |
| 365 AllowDeferredHandleDereference using_raw_address; | 365 AllowDeferredHandleDereference using_raw_address; |
| 366 // Verify all Objects referred by code are NOT in new space. | 366 // Verify all Objects referred by code are NOT in new space. |
| 367 Object* obj = *handle; | 367 Object* obj = *handle; |
| 368 if (obj->IsHeapObject()) { | 368 if (obj->IsHeapObject()) { |
| 369 ASSERT(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj)); | 369 DCHECK(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj)); |
| 370 x_ = reinterpret_cast<intptr_t>(handle.location()); | 370 x_ = reinterpret_cast<intptr_t>(handle.location()); |
| 371 rmode_ = RelocInfo::EMBEDDED_OBJECT; | 371 rmode_ = RelocInfo::EMBEDDED_OBJECT; |
| 372 } else { | 372 } else { |
| 373 // no relocation needed | 373 // no relocation needed |
| 374 x_ = reinterpret_cast<intptr_t>(obj); | 374 x_ = reinterpret_cast<intptr_t>(obj); |
| 375 rmode_ = RelocInfo::NONE32; | 375 rmode_ = RelocInfo::NONE32; |
| 376 } | 376 } |
| 377 } | 377 } |
| 378 | 378 |
| 379 | 379 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 392 void Assembler::emit(uint32_t x) { | 392 void Assembler::emit(uint32_t x) { |
| 393 *reinterpret_cast<uint32_t*>(pc_) = x; | 393 *reinterpret_cast<uint32_t*>(pc_) = x; |
| 394 pc_ += sizeof(uint32_t); | 394 pc_ += sizeof(uint32_t); |
| 395 } | 395 } |
| 396 | 396 |
| 397 | 397 |
| 398 void Assembler::emit(Handle<Object> handle) { | 398 void Assembler::emit(Handle<Object> handle) { |
| 399 AllowDeferredHandleDereference heap_object_check; | 399 AllowDeferredHandleDereference heap_object_check; |
| 400 // Verify all Objects referred by code are NOT in new space. | 400 // Verify all Objects referred by code are NOT in new space. |
| 401 Object* obj = *handle; | 401 Object* obj = *handle; |
| 402 ASSERT(!isolate()->heap()->InNewSpace(obj)); | 402 DCHECK(!isolate()->heap()->InNewSpace(obj)); |
| 403 if (obj->IsHeapObject()) { | 403 if (obj->IsHeapObject()) { |
| 404 emit(reinterpret_cast<intptr_t>(handle.location()), | 404 emit(reinterpret_cast<intptr_t>(handle.location()), |
| 405 RelocInfo::EMBEDDED_OBJECT); | 405 RelocInfo::EMBEDDED_OBJECT); |
| 406 } else { | 406 } else { |
| 407 // no relocation needed | 407 // no relocation needed |
| 408 emit(reinterpret_cast<intptr_t>(obj)); | 408 emit(reinterpret_cast<intptr_t>(obj)); |
| 409 } | 409 } |
| 410 } | 410 } |
| 411 | 411 |
| 412 | 412 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 int32_t pos; | 445 int32_t pos; |
| 446 pos = label->pos() + Code::kHeaderSize - kHeapObjectTag; | 446 pos = label->pos() + Code::kHeaderSize - kHeapObjectTag; |
| 447 emit(pos); | 447 emit(pos); |
| 448 } else { | 448 } else { |
| 449 emit_disp(label, Displacement::CODE_RELATIVE); | 449 emit_disp(label, Displacement::CODE_RELATIVE); |
| 450 } | 450 } |
| 451 } | 451 } |
| 452 | 452 |
| 453 | 453 |
| 454 void Assembler::emit_w(const Immediate& x) { | 454 void Assembler::emit_w(const Immediate& x) { |
| 455 ASSERT(RelocInfo::IsNone(x.rmode_)); | 455 DCHECK(RelocInfo::IsNone(x.rmode_)); |
| 456 uint16_t value = static_cast<uint16_t>(x.x_); | 456 uint16_t value = static_cast<uint16_t>(x.x_); |
| 457 reinterpret_cast<uint16_t*>(pc_)[0] = value; | 457 reinterpret_cast<uint16_t*>(pc_)[0] = value; |
| 458 pc_ += sizeof(uint16_t); | 458 pc_ += sizeof(uint16_t); |
| 459 } | 459 } |
| 460 | 460 |
| 461 | 461 |
| 462 Address Assembler::target_address_at(Address pc, | 462 Address Assembler::target_address_at(Address pc, |
| 463 ConstantPoolArray* constant_pool) { | 463 ConstantPoolArray* constant_pool) { |
| 464 return pc + sizeof(int32_t) + *reinterpret_cast<int32_t*>(pc); | 464 return pc + sizeof(int32_t) + *reinterpret_cast<int32_t*>(pc); |
| 465 } | 465 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 496 Displacement disp(L, type); | 496 Displacement disp(L, type); |
| 497 L->link_to(pc_offset()); | 497 L->link_to(pc_offset()); |
| 498 emit(static_cast<int>(disp.data())); | 498 emit(static_cast<int>(disp.data())); |
| 499 } | 499 } |
| 500 | 500 |
| 501 | 501 |
| 502 void Assembler::emit_near_disp(Label* L) { | 502 void Assembler::emit_near_disp(Label* L) { |
| 503 byte disp = 0x00; | 503 byte disp = 0x00; |
| 504 if (L->is_near_linked()) { | 504 if (L->is_near_linked()) { |
| 505 int offset = L->near_link_pos() - pc_offset(); | 505 int offset = L->near_link_pos() - pc_offset(); |
| 506 ASSERT(is_int8(offset)); | 506 DCHECK(is_int8(offset)); |
| 507 disp = static_cast<byte>(offset & 0xFF); | 507 disp = static_cast<byte>(offset & 0xFF); |
| 508 } | 508 } |
| 509 L->link_to(pc_offset(), Label::kNear); | 509 L->link_to(pc_offset(), Label::kNear); |
| 510 *pc_++ = disp; | 510 *pc_++ = disp; |
| 511 } | 511 } |
| 512 | 512 |
| 513 | 513 |
| 514 void Operand::set_modrm(int mod, Register rm) { | 514 void Operand::set_modrm(int mod, Register rm) { |
| 515 ASSERT((mod & -4) == 0); | 515 DCHECK((mod & -4) == 0); |
| 516 buf_[0] = mod << 6 | rm.code(); | 516 buf_[0] = mod << 6 | rm.code(); |
| 517 len_ = 1; | 517 len_ = 1; |
| 518 } | 518 } |
| 519 | 519 |
| 520 | 520 |
| 521 void Operand::set_sib(ScaleFactor scale, Register index, Register base) { | 521 void Operand::set_sib(ScaleFactor scale, Register index, Register base) { |
| 522 ASSERT(len_ == 1); | 522 DCHECK(len_ == 1); |
| 523 ASSERT((scale & -4) == 0); | 523 DCHECK((scale & -4) == 0); |
| 524 // Use SIB with no index register only for base esp. | 524 // Use SIB with no index register only for base esp. |
| 525 ASSERT(!index.is(esp) || base.is(esp)); | 525 DCHECK(!index.is(esp) || base.is(esp)); |
| 526 buf_[1] = scale << 6 | index.code() << 3 | base.code(); | 526 buf_[1] = scale << 6 | index.code() << 3 | base.code(); |
| 527 len_ = 2; | 527 len_ = 2; |
| 528 } | 528 } |
| 529 | 529 |
| 530 | 530 |
| 531 void Operand::set_disp8(int8_t disp) { | 531 void Operand::set_disp8(int8_t disp) { |
| 532 ASSERT(len_ == 1 || len_ == 2); | 532 DCHECK(len_ == 1 || len_ == 2); |
| 533 *reinterpret_cast<int8_t*>(&buf_[len_++]) = disp; | 533 *reinterpret_cast<int8_t*>(&buf_[len_++]) = disp; |
| 534 } | 534 } |
| 535 | 535 |
| 536 | 536 |
| 537 void Operand::set_dispr(int32_t disp, RelocInfo::Mode rmode) { | 537 void Operand::set_dispr(int32_t disp, RelocInfo::Mode rmode) { |
| 538 ASSERT(len_ == 1 || len_ == 2); | 538 DCHECK(len_ == 1 || len_ == 2); |
| 539 int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); | 539 int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); |
| 540 *p = disp; | 540 *p = disp; |
| 541 len_ += sizeof(int32_t); | 541 len_ += sizeof(int32_t); |
| 542 rmode_ = rmode; | 542 rmode_ = rmode; |
| 543 } | 543 } |
| 544 | 544 |
| 545 Operand::Operand(Register reg) { | 545 Operand::Operand(Register reg) { |
| 546 // reg | 546 // reg |
| 547 set_modrm(3, reg); | 547 set_modrm(3, reg); |
| 548 } | 548 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 562 | 562 |
| 563 | 563 |
| 564 Operand::Operand(Immediate imm) { | 564 Operand::Operand(Immediate imm) { |
| 565 // [disp/r] | 565 // [disp/r] |
| 566 set_modrm(0, ebp); | 566 set_modrm(0, ebp); |
| 567 set_dispr(imm.x_, imm.rmode_); | 567 set_dispr(imm.x_, imm.rmode_); |
| 568 } | 568 } |
| 569 } } // namespace v8::internal | 569 } } // namespace v8::internal |
| 570 | 570 |
| 571 #endif // V8_IA32_ASSEMBLER_IA32_INL_H_ | 571 #endif // V8_IA32_ASSEMBLER_IA32_INL_H_ |
| OLD | NEW |