OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 ASSERT(allocator_ == NULL); | 106 ASSERT(allocator_ == NULL); |
107 RegisterAllocator register_allocator(this); | 107 RegisterAllocator register_allocator(this); |
108 allocator_ = ®ister_allocator; | 108 allocator_ = ®ister_allocator; |
109 ASSERT(frame_ == NULL); | 109 ASSERT(frame_ == NULL); |
110 frame_ = new VirtualFrame(this); | 110 frame_ = new VirtualFrame(this); |
111 set_in_spilled_code(false); | 111 set_in_spilled_code(false); |
112 | 112 |
113 // Adjust for function-level loop nesting. | 113 // Adjust for function-level loop nesting. |
114 loop_nesting_ += fun->loop_nesting(); | 114 loop_nesting_ += fun->loop_nesting(); |
115 | 115 |
| 116 JumpTarget::set_compiling_deferred_code(false); |
| 117 |
116 { | 118 { |
117 CodeGenState state(this); | 119 CodeGenState state(this); |
118 | 120 |
119 // Entry: | 121 // Entry: |
120 // Stack: receiver, arguments, return address. | 122 // Stack: receiver, arguments, return address. |
121 // ebp: caller's frame pointer | 123 // ebp: caller's frame pointer |
122 // esp: stack pointer | 124 // esp: stack pointer |
123 // edi: called JS function | 125 // edi: called JS function |
124 // esi: callee's context | 126 // esi: callee's context |
125 allocator_->Initialize(); | 127 allocator_->Initialize(); |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 ASSERT(state_ == NULL); | 311 ASSERT(state_ == NULL); |
310 ASSERT(loop_nesting() == 0); | 312 ASSERT(loop_nesting() == 0); |
311 ASSERT(!function_return_is_shadowed_); | 313 ASSERT(!function_return_is_shadowed_); |
312 function_return_.Unuse(); | 314 function_return_.Unuse(); |
313 DeleteFrame(); | 315 DeleteFrame(); |
314 | 316 |
315 // Process any deferred code using the register allocator. | 317 // Process any deferred code using the register allocator. |
316 if (HasStackOverflow()) { | 318 if (HasStackOverflow()) { |
317 ClearDeferred(); | 319 ClearDeferred(); |
318 } else { | 320 } else { |
| 321 JumpTarget::set_compiling_deferred_code(true); |
319 ProcessDeferred(); | 322 ProcessDeferred(); |
| 323 JumpTarget::set_compiling_deferred_code(false); |
320 } | 324 } |
321 | 325 |
322 // There is no need to delete the register allocator, it is a | 326 // There is no need to delete the register allocator, it is a |
323 // stack-allocated local. | 327 // stack-allocated local. |
324 allocator_ = NULL; | 328 allocator_ = NULL; |
325 scope_ = NULL; | 329 scope_ = NULL; |
326 } | 330 } |
327 | 331 |
328 | 332 |
329 Operand CodeGenerator::SlotOperand(Slot* slot, Register tmp) { | 333 Operand CodeGenerator::SlotOperand(Slot* slot, Register tmp) { |
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1240 ASSERT(!operand->is_valid()); | 1244 ASSERT(!operand->is_valid()); |
1241 return; | 1245 return; |
1242 } | 1246 } |
1243 | 1247 |
1244 // Get the literal value. | 1248 // Get the literal value. |
1245 Smi* smi_value = Smi::cast(*value); | 1249 Smi* smi_value = Smi::cast(*value); |
1246 int int_value = smi_value->value(); | 1250 int int_value = smi_value->value(); |
1247 | 1251 |
1248 switch (op) { | 1252 switch (op) { |
1249 case Token::ADD: { | 1253 case Token::ADD: { |
| 1254 operand->ToRegister(); |
| 1255 frame_->Spill(operand->reg()); |
| 1256 __ add(Operand(operand->reg()), Immediate(value)); |
| 1257 |
1250 DeferredCode* deferred = NULL; | 1258 DeferredCode* deferred = NULL; |
1251 if (reversed) { | 1259 if (reversed) { |
1252 deferred = new DeferredInlineSmiAddReversed(this, smi_value, | 1260 deferred = new DeferredInlineSmiAddReversed(this, smi_value, |
1253 overwrite_mode); | 1261 overwrite_mode); |
1254 } else { | 1262 } else { |
1255 deferred = new DeferredInlineSmiAdd(this, smi_value, overwrite_mode); | 1263 deferred = new DeferredInlineSmiAdd(this, smi_value, overwrite_mode); |
1256 } | 1264 } |
1257 operand->ToRegister(); | 1265 deferred->SetEntryFrame(operand); |
1258 frame_->Spill(operand->reg()); | |
1259 __ add(Operand(operand->reg()), Immediate(value)); | |
1260 deferred->enter()->Branch(overflow, operand, not_taken); | 1266 deferred->enter()->Branch(overflow, operand, not_taken); |
1261 __ test(operand->reg(), Immediate(kSmiTagMask)); | 1267 __ test(operand->reg(), Immediate(kSmiTagMask)); |
1262 deferred->enter()->Branch(not_zero, operand, not_taken); | 1268 deferred->enter()->Branch(not_zero, operand, not_taken); |
1263 deferred->BindExit(operand); | 1269 deferred->BindExit(operand); |
1264 frame_->Push(operand); | 1270 frame_->Push(operand); |
1265 break; | 1271 break; |
1266 } | 1272 } |
1267 | 1273 |
1268 case Token::SUB: { | 1274 case Token::SUB: { |
1269 DeferredCode* deferred = NULL; | 1275 DeferredCode* deferred = NULL; |
1270 Result answer(this); // Only allocate a new register if reversed. | 1276 Result answer(this); // Only allocate a new register if reversed. |
1271 if (reversed) { | 1277 if (reversed) { |
1272 answer = allocator()->Allocate(); | 1278 answer = allocator()->Allocate(); |
1273 ASSERT(answer.is_valid()); | 1279 ASSERT(answer.is_valid()); |
1274 deferred = new DeferredInlineSmiSubReversed(this, | 1280 deferred = new DeferredInlineSmiSubReversed(this, smi_value, |
1275 smi_value, | |
1276 overwrite_mode); | 1281 overwrite_mode); |
1277 __ Set(answer.reg(), Immediate(value)); | 1282 __ Set(answer.reg(), Immediate(value)); |
1278 // We are in the reversed case so they can't both be Smi constants. | 1283 // We are in the reversed case so they can't both be Smi constants. |
1279 ASSERT(operand->is_register()); | 1284 ASSERT(operand->is_register()); |
1280 __ sub(answer.reg(), Operand(operand->reg())); | 1285 __ sub(answer.reg(), Operand(operand->reg())); |
1281 } else { | 1286 } else { |
1282 operand->ToRegister(); | 1287 operand->ToRegister(); |
1283 frame_->Spill(operand->reg()); | 1288 frame_->Spill(operand->reg()); |
1284 deferred = new DeferredInlineSmiSub(this, | 1289 deferred = new DeferredInlineSmiSub(this, smi_value, overwrite_mode); |
1285 smi_value, | |
1286 overwrite_mode); | |
1287 __ sub(Operand(operand->reg()), Immediate(value)); | 1290 __ sub(Operand(operand->reg()), Immediate(value)); |
1288 answer = *operand; | 1291 answer = *operand; |
1289 } | 1292 } |
| 1293 deferred->SetEntryFrame(operand); |
1290 deferred->enter()->Branch(overflow, operand, not_taken); | 1294 deferred->enter()->Branch(overflow, operand, not_taken); |
1291 __ test(answer.reg(), Immediate(kSmiTagMask)); | 1295 __ test(answer.reg(), Immediate(kSmiTagMask)); |
1292 deferred->enter()->Branch(not_zero, operand, not_taken); | 1296 deferred->enter()->Branch(not_zero, operand, not_taken); |
1293 operand->Unuse(); | 1297 operand->Unuse(); |
1294 deferred->BindExit(&answer); | 1298 deferred->BindExit(&answer); |
1295 frame_->Push(&answer); | 1299 frame_->Push(&answer); |
1296 break; | 1300 break; |
1297 } | 1301 } |
1298 | 1302 |
1299 case Token::SAR: { | 1303 case Token::SAR: { |
(...skipping 4106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5406 : RelocInfo::CODE_TARGET; | 5410 : RelocInfo::CODE_TARGET; |
5407 Result answer = cgen_->frame()->CallLoadIC(mode); | 5411 Result answer = cgen_->frame()->CallLoadIC(mode); |
5408 // A test eax instruction following the call signals that the | 5412 // A test eax instruction following the call signals that the |
5409 // inobject property case was inlined. Ensure that there is not | 5413 // inobject property case was inlined. Ensure that there is not |
5410 // a test eax instruction here. | 5414 // a test eax instruction here. |
5411 __ nop(); | 5415 __ nop(); |
5412 cgen_->frame()->Push(&answer); | 5416 cgen_->frame()->Push(&answer); |
5413 } else { | 5417 } else { |
5414 // Inline the inobject property case. | 5418 // Inline the inobject property case. |
5415 Comment cmnt(masm, "[ Inlined named property load"); | 5419 Comment cmnt(masm, "[ Inlined named property load"); |
5416 DeferredReferenceGetNamedValue* deferred = | |
5417 new DeferredReferenceGetNamedValue(cgen_, GetName()); | |
5418 Result receiver = cgen_->frame()->Pop(); | 5420 Result receiver = cgen_->frame()->Pop(); |
5419 receiver.ToRegister(); | 5421 receiver.ToRegister(); |
5420 // Check that the receiver is a heap object. | |
5421 __ test(receiver.reg(), Immediate(kSmiTagMask)); | |
5422 deferred->enter()->Branch(zero, &receiver, not_taken); | |
5423 | 5422 |
5424 // Preallocate the value register to ensure that there is no | 5423 // Preallocate the value register to ensure that there is no |
5425 // spill emitted between the patch site label and the offset in | 5424 // spill emitted between the patch site label and the offset in |
5426 // the load instruction. | 5425 // the load instruction and that all frames reaching the |
| 5426 // deferred code are identical. |
5427 Result value = cgen_->allocator()->Allocate(); | 5427 Result value = cgen_->allocator()->Allocate(); |
5428 ASSERT(value.is_valid()); | 5428 ASSERT(value.is_valid()); |
| 5429 |
| 5430 // Check that the receiver is a heap object. |
| 5431 __ test(receiver.reg(), Immediate(kSmiTagMask)); |
| 5432 |
| 5433 DeferredReferenceGetNamedValue* deferred = |
| 5434 new DeferredReferenceGetNamedValue(cgen_, GetName()); |
| 5435 deferred->SetEntryFrame(&receiver); |
| 5436 deferred->enter()->Branch(zero, &receiver, not_taken); |
| 5437 |
5429 __ bind(deferred->patch_site()); | 5438 __ bind(deferred->patch_site()); |
5430 // This is the map check instruction that will be patched (so we can't | 5439 // This is the map check instruction that will be patched (so we can't |
5431 // use the double underscore macro that may insert instructions). | 5440 // use the double underscore macro that may insert instructions). |
5432 // Initially use an invalid map to force a failure. | 5441 // Initially use an invalid map to force a failure. |
5433 masm->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset), | 5442 masm->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset), |
5434 Immediate(Factory::null_value())); | 5443 Immediate(Factory::null_value())); |
5435 // This branch is always a forwards branch so it's always a fixed | 5444 // This branch is always a forwards branch so it's always a fixed |
5436 // size which allows the assert below to succeed and patching to work. | 5445 // size which allows the assert below to succeed and patching to work. |
5437 deferred->enter()->Branch(not_equal, &receiver, not_taken); | 5446 deferred->enter()->Branch(not_equal, &receiver, not_taken); |
5438 | 5447 |
(...skipping 1792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7231 | 7240 |
7232 // Slow-case: Go through the JavaScript implementation. | 7241 // Slow-case: Go through the JavaScript implementation. |
7233 __ bind(&slow); | 7242 __ bind(&slow); |
7234 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 7243 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
7235 } | 7244 } |
7236 | 7245 |
7237 | 7246 |
7238 #undef __ | 7247 #undef __ |
7239 | 7248 |
7240 } } // namespace v8::internal | 7249 } } // namespace v8::internal |
OLD | NEW |