| OLD | NEW |
| 1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 break; | 144 break; |
| 145 } | 145 } |
| 146 } | 146 } |
| 147 } | 147 } |
| 148 | 148 |
| 149 elements_[index].set_sync(); | 149 elements_[index].set_sync(); |
| 150 } | 150 } |
| 151 | 151 |
| 152 | 152 |
| 153 void VirtualFrame::MergeTo(VirtualFrame* expected) { | 153 void VirtualFrame::MergeTo(VirtualFrame* expected) { |
| 154 UNIMPLEMENTED(); | 154 Comment cmnt(masm_, "[ Merge frame"); |
| 155 // We should always be merging the code generator's current frame to an |
| 156 // expected frame. |
| 157 ASSERT(cgen_->frame() == this); |
| 158 |
| 159 // Adjust the stack pointer upward (toward the top of the virtual |
| 160 // frame) if necessary. |
| 161 if (stack_pointer_ < expected->stack_pointer_) { |
| 162 int difference = expected->stack_pointer_ - stack_pointer_; |
| 163 stack_pointer_ = expected->stack_pointer_; |
| 164 __ sub(sp, sp, Operand(difference * kPointerSize)); |
| 165 } |
| 166 |
| 167 MergeMoveRegistersToMemory(expected); |
| 168 MergeMoveRegistersToRegisters(expected); |
| 169 MergeMoveMemoryToRegisters(expected); |
| 170 |
| 171 // Fix any sync bit problems. |
| 172 for (int i = 0; i <= stack_pointer_; i++) { |
| 173 FrameElement source = elements_[i]; |
| 174 FrameElement target = expected->elements_[i]; |
| 175 if (source.is_synced() && !target.is_synced()) { |
| 176 elements_[i].clear_sync(); |
| 177 } else if (!source.is_synced() && target.is_synced()) { |
| 178 SyncElementAt(i); |
| 179 } |
| 180 } |
| 181 |
| 182 // Adjust the stack point downard if necessary. |
| 183 if (stack_pointer_ > expected->stack_pointer_) { |
| 184 int difference = stack_pointer_ - expected->stack_pointer_; |
| 185 stack_pointer_ = expected->stack_pointer_; |
| 186 __ add(sp, sp, Operand(difference * kPointerSize)); |
| 187 } |
| 188 |
| 189 // At this point, the frames should be identical. |
| 190 ASSERT(Equals(expected)); |
| 155 } | 191 } |
| 156 | 192 |
| 157 | 193 |
| 158 void VirtualFrame::MergeMoveRegistersToMemory(VirtualFrame* expected) { | 194 void VirtualFrame::MergeMoveRegistersToMemory(VirtualFrame* expected) { |
| 159 UNIMPLEMENTED(); | 195 ASSERT(stack_pointer_ >= expected->stack_pointer_); |
| 196 |
| 197 // Move registers, constants, and copies to memory. Perform moves |
| 198 // from the top downward in the frame in order to leave the backing |
| 199 // stores of copies in registers. |
| 200 // |
| 201 // Moving memory-backed copies to memory requires a spare register |
| 202 // for the memory-to-memory moves. Since we are performing a merge, |
| 203 // we use esi (which is already saved in the frame). We keep track |
| 204 // of the index of the frame element esi is caching or kIllegalIndex |
| 205 // if esi has not been disturbed. |
| 206 |
| 207 for (int i = 0; i < elements_.length(); i++) { |
| 208 ASSERT(elements_[i].is_memory()); |
| 209 ASSERT(expected->elements_[i].is_memory()); |
| 210 } |
| 160 } | 211 } |
| 161 | 212 |
| 162 | 213 |
| 163 void VirtualFrame::MergeMoveRegistersToRegisters(VirtualFrame* expected) { | 214 void VirtualFrame::MergeMoveRegistersToRegisters(VirtualFrame* expected) { |
| 164 UNIMPLEMENTED(); | |
| 165 } | 215 } |
| 166 | 216 |
| 167 | 217 |
| 168 void VirtualFrame::MergeMoveMemoryToRegisters(VirtualFrame *expected) { | 218 void VirtualFrame::MergeMoveMemoryToRegisters(VirtualFrame *expected) { |
| 169 UNIMPLEMENTED(); | |
| 170 } | 219 } |
| 171 | 220 |
| 172 | 221 |
| 173 void VirtualFrame::Enter() { | 222 void VirtualFrame::Enter() { |
| 174 Comment cmnt(masm_, "[ Enter JS frame"); | 223 Comment cmnt(masm_, "[ Enter JS frame"); |
| 175 #ifdef DEBUG | 224 #ifdef DEBUG |
| 176 { Label done, fail; | 225 { Label done, fail; |
| 177 __ tst(r1, Operand(kSmiTagMask)); | 226 __ tst(r1, Operand(kSmiTagMask)); |
| 178 __ b(eq, &fail); | 227 __ b(eq, &fail); |
| 179 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 228 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |
| 180 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); | 229 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); |
| 181 __ cmp(r2, Operand(JS_FUNCTION_TYPE)); | 230 __ cmp(r2, Operand(JS_FUNCTION_TYPE)); |
| 182 __ b(eq, &done); | 231 __ b(eq, &done); |
| 183 __ bind(&fail); | 232 __ bind(&fail); |
| 184 __ stop("CodeGenerator::EnterJSFrame - r1 not a function"); | 233 __ stop("CodeGenerator::EnterJSFrame - r1 not a function"); |
| 185 __ bind(&done); | 234 __ bind(&done); |
| 186 } | 235 } |
| 187 #endif // DEBUG | 236 #endif // DEBUG |
| 188 | 237 |
| 189 // We are about to push four values to the frame. | 238 // We are about to push four values to the frame. |
| 190 Adjust(4); | 239 Adjust(4); |
| 191 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); | 240 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); |
| 192 // Adjust FP to point to saved FP. | 241 // Adjust FP to point to saved FP. |
| 193 frame_pointer_ = elements_.length() - 2; | 242 frame_pointer_ = elements_.length() - 2; |
| 194 __ add(fp, sp, Operand(2 * kPointerSize)); | 243 __ add(fp, sp, Operand(2 * kPointerSize)); |
| 244 cgen_->allocator()->Unuse(r1); |
| 245 cgen_->allocator()->Unuse(lr); |
| 195 } | 246 } |
| 196 | 247 |
| 197 | 248 |
| 198 void VirtualFrame::Exit() { | 249 void VirtualFrame::Exit() { |
| 199 Comment cmnt(masm_, "[ Exit JS frame"); | 250 Comment cmnt(masm_, "[ Exit JS frame"); |
| 200 // Drop the execution stack down to the frame pointer and restore the caller | 251 // Drop the execution stack down to the frame pointer and restore the caller |
| 201 // frame pointer and return address. | 252 // frame pointer and return address. |
| 202 __ mov(sp, fp); | 253 __ mov(sp, fp); |
| 203 __ ldm(ia_w, sp, fp.bit() | lr.bit()); | 254 __ ldm(ia_w, sp, fp.bit() | lr.bit()); |
| 204 } | 255 } |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 ASSERT(cgen_->HasValidEntryRegisters()); | 340 ASSERT(cgen_->HasValidEntryRegisters()); |
| 290 __ CallRuntime(id, frame_arg_count); | 341 __ CallRuntime(id, frame_arg_count); |
| 291 Result result = cgen_->allocator()->Allocate(r0); | 342 Result result = cgen_->allocator()->Allocate(r0); |
| 292 ASSERT(result.is_valid()); | 343 ASSERT(result.is_valid()); |
| 293 return result; | 344 return result; |
| 294 } | 345 } |
| 295 | 346 |
| 296 | 347 |
| 297 Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id, | 348 Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id, |
| 298 InvokeJSFlags flags, | 349 InvokeJSFlags flags, |
| 350 Result* arg_count_register, |
| 299 int frame_arg_count) { | 351 int frame_arg_count) { |
| 300 UNIMPLEMENTED(); | 352 ASSERT(arg_count_register->reg().is(r0)); |
| 301 Result invalid(cgen_); | 353 PrepareForCall(frame_arg_count, frame_arg_count); |
| 302 return invalid; | 354 arg_count_register->Unuse(); |
| 355 __ InvokeBuiltin(id, flags); |
| 356 Result result = cgen_->allocator()->Allocate(r0); |
| 357 return result; |
| 303 } | 358 } |
| 304 | 359 |
| 305 | 360 |
| 306 Result VirtualFrame::RawCallCodeObject(Handle<Code> code, | 361 Result VirtualFrame::RawCallCodeObject(Handle<Code> code, |
| 307 RelocInfo::Mode rmode) { | 362 RelocInfo::Mode rmode) { |
| 308 ASSERT(cgen_->HasValidEntryRegisters()); | 363 ASSERT(cgen_->HasValidEntryRegisters()); |
| 309 __ Call(code, rmode); | 364 __ Call(code, rmode); |
| 310 Result result = cgen_->allocator()->Allocate(r0); | 365 Result result = cgen_->allocator()->Allocate(r0); |
| 311 ASSERT(result.is_valid()); | 366 ASSERT(result.is_valid()); |
| 312 return result; | 367 return result; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 339 arg->Unuse(); | 394 arg->Unuse(); |
| 340 return RawCallCodeObject(code, rmode); | 395 return RawCallCodeObject(code, rmode); |
| 341 } | 396 } |
| 342 | 397 |
| 343 | 398 |
| 344 Result VirtualFrame::CallCodeObject(Handle<Code> code, | 399 Result VirtualFrame::CallCodeObject(Handle<Code> code, |
| 345 RelocInfo::Mode rmode, | 400 RelocInfo::Mode rmode, |
| 346 Result* arg0, | 401 Result* arg0, |
| 347 Result* arg1, | 402 Result* arg1, |
| 348 int dropped_args) { | 403 int dropped_args) { |
| 349 UNIMPLEMENTED(); | 404 int spilled_args = 1; |
| 350 Result invalid(cgen_); | 405 switch (code->kind()) { |
| 351 return invalid; | 406 case Code::STORE_IC: |
| 407 ASSERT(arg0->reg().is(r0)); |
| 408 ASSERT(arg1->reg().is(r2)); |
| 409 ASSERT(dropped_args == 0); |
| 410 spilled_args = 1; |
| 411 break; |
| 412 case Code::BUILTIN: |
| 413 ASSERT(*code == Builtins::builtin(Builtins::JSConstructCall)); |
| 414 ASSERT(arg0->reg().is(r0)); |
| 415 ASSERT(arg1->reg().is(r1)); |
| 416 spilled_args = dropped_args + 1; |
| 417 break; |
| 418 default: |
| 419 // No other types of code objects are called with values |
| 420 // in exactly two registers. |
| 421 UNREACHABLE(); |
| 422 break; |
| 423 } |
| 424 PrepareForCall(spilled_args, dropped_args); |
| 425 arg0->Unuse(); |
| 426 arg1->Unuse(); |
| 427 return RawCallCodeObject(code, rmode); |
| 352 } | 428 } |
| 353 | 429 |
| 354 | 430 |
| 355 void VirtualFrame::Drop(int count) { | 431 void VirtualFrame::Drop(int count) { |
| 356 ASSERT(height() >= count); | 432 ASSERT(height() >= count); |
| 357 int num_virtual_elements = (elements_.length() - 1) - stack_pointer_; | 433 int num_virtual_elements = (elements_.length() - 1) - stack_pointer_; |
| 358 | 434 |
| 359 // Emit code to lower the stack pointer if necessary. | 435 // Emit code to lower the stack pointer if necessary. |
| 360 if (num_virtual_elements < count) { | 436 if (num_virtual_elements < count) { |
| 361 int num_dropped = count - num_virtual_elements; | 437 int num_dropped = count - num_virtual_elements; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 392 ASSERT(stack_pointer_ == elements_.length() - 1); | 468 ASSERT(stack_pointer_ == elements_.length() - 1); |
| 393 elements_.Add(FrameElement::MemoryElement()); | 469 elements_.Add(FrameElement::MemoryElement()); |
| 394 stack_pointer_++; | 470 stack_pointer_++; |
| 395 __ push(reg); | 471 __ push(reg); |
| 396 } | 472 } |
| 397 | 473 |
| 398 | 474 |
| 399 #undef __ | 475 #undef __ |
| 400 | 476 |
| 401 } } // namespace v8::internal | 477 } } // namespace v8::internal |
| OLD | NEW |