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 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 // ----------------------------------- | 245 // ----------------------------------- |
246 // rsp[0] return address | 246 // rsp[0] return address |
247 // rsp[8] argument argc | 247 // rsp[8] argument argc |
248 // rsp[16] argument argc - 1 | 248 // rsp[16] argument argc - 1 |
249 // ... | 249 // ... |
250 // rsp[argc * 8] argument 1 | 250 // rsp[argc * 8] argument 1 |
251 // rsp[(argc + 1) * 8] argument 0 = receiver | 251 // rsp[(argc + 1) * 8] argument 0 = receiver |
252 // rsp[(argc + 2) * 8] function name | 252 // rsp[(argc + 2) * 8] function name |
253 Label miss; | 253 Label miss; |
254 | 254 |
255 __ IncrementCounter(&Counters::call_global_inline, 1); | |
256 | |
257 // Get the number of arguments. | 255 // Get the number of arguments. |
258 const int argc = arguments().immediate(); | 256 const int argc = arguments().immediate(); |
259 | 257 |
260 // Get the receiver from the stack. | 258 // Get the receiver from the stack. |
261 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 259 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
262 | 260 |
263 // If the object is the holder then we know that it's a global | 261 // If the object is the holder then we know that it's a global |
264 // object which can only happen for contextual calls. In this case, | 262 // object which can only happen for contextual calls. In this case, |
265 // the receiver cannot be a smi. | 263 // the receiver cannot be a smi. |
266 if (object != holder) { | 264 if (object != holder) { |
(...skipping 15 matching lines...) Expand all Loading... |
282 // Patch the receiver on the stack with the global proxy. | 280 // Patch the receiver on the stack with the global proxy. |
283 if (object->IsGlobalObject()) { | 281 if (object->IsGlobalObject()) { |
284 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 282 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
285 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 283 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
286 } | 284 } |
287 | 285 |
288 // Setup the context (function already in edi). | 286 // Setup the context (function already in edi). |
289 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 287 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
290 | 288 |
291 // Jump to the cached code (tail call). | 289 // Jump to the cached code (tail call). |
| 290 __ IncrementCounter(&Counters::call_global_inline, 1); |
292 ASSERT(function->is_compiled()); | 291 ASSERT(function->is_compiled()); |
293 Handle<Code> code(function->code()); | 292 Handle<Code> code(function->code()); |
294 ParameterCount expected(function->shared()->formal_parameter_count()); | 293 ParameterCount expected(function->shared()->formal_parameter_count()); |
295 __ InvokeCode(code, expected, arguments(), | 294 __ InvokeCode(code, expected, arguments(), |
296 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | 295 RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
297 | 296 |
298 // Handle call cache miss. | 297 // Handle call cache miss. |
299 __ bind(&miss); | 298 __ bind(&miss); |
300 __ DecrementCounter(&Counters::call_global_inline, 1); | |
301 __ IncrementCounter(&Counters::call_global_inline_miss, 1); | 299 __ IncrementCounter(&Counters::call_global_inline_miss, 1); |
302 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); | 300 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); |
303 __ Jump(ic, RelocInfo::CODE_TARGET); | 301 __ Jump(ic, RelocInfo::CODE_TARGET); |
304 | 302 |
305 // Return the generated code. | 303 // Return the generated code. |
306 return GetCode(NORMAL, name); | 304 return GetCode(NORMAL, name); |
307 } | 305 } |
308 | 306 |
309 | 307 |
310 Object* LoadStubCompiler::CompileLoadCallback(JSObject* a, | 308 Object* LoadStubCompiler::CompileLoadCallback(JSObject* a, |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 JSGlobalPropertyCell* cell, | 369 JSGlobalPropertyCell* cell, |
372 String* name, | 370 String* name, |
373 bool is_dont_delete) { | 371 bool is_dont_delete) { |
374 // ----------- S t a t e ------------- | 372 // ----------- S t a t e ------------- |
375 // -- rcx : name | 373 // -- rcx : name |
376 // -- rsp[0] : return address | 374 // -- rsp[0] : return address |
377 // -- rsp[8] : receiver | 375 // -- rsp[8] : receiver |
378 // ----------------------------------- | 376 // ----------------------------------- |
379 Label miss; | 377 Label miss; |
380 | 378 |
381 __ IncrementCounter(&Counters::named_load_global_inline, 1); | |
382 | |
383 // Get the receiver from the stack. | 379 // Get the receiver from the stack. |
384 __ movq(rax, Operand(rsp, kPointerSize)); | 380 __ movq(rax, Operand(rsp, kPointerSize)); |
385 | 381 |
386 // If the object is the holder then we know that it's a global | 382 // If the object is the holder then we know that it's a global |
387 // object which can only happen for contextual loads. In this case, | 383 // object which can only happen for contextual loads. In this case, |
388 // the receiver cannot be a smi. | 384 // the receiver cannot be a smi. |
389 if (object != holder) { | 385 if (object != holder) { |
390 __ testl(rax, Immediate(kSmiTagMask)); | 386 __ testl(rax, Immediate(kSmiTagMask)); |
391 __ j(zero, &miss); | 387 __ j(zero, &miss); |
392 } | 388 } |
393 | 389 |
394 // Check that the maps haven't changed. | 390 // Check that the maps haven't changed. |
395 CheckPrototypes(object, rax, holder, rbx, rdx, name, &miss); | 391 CheckPrototypes(object, rax, holder, rbx, rdx, name, &miss); |
396 | 392 |
397 // Get the value from the cell. | 393 // Get the value from the cell. |
398 __ Move(rax, Handle<JSGlobalPropertyCell>(cell)); | 394 __ Move(rax, Handle<JSGlobalPropertyCell>(cell)); |
399 __ movq(rax, FieldOperand(rax, JSGlobalPropertyCell::kValueOffset)); | 395 __ movq(rax, FieldOperand(rax, JSGlobalPropertyCell::kValueOffset)); |
400 | 396 |
401 // Check for deleted property if property can actually be deleted. | 397 // Check for deleted property if property can actually be deleted. |
402 if (!is_dont_delete) { | 398 if (!is_dont_delete) { |
403 __ Cmp(rax, Factory::the_hole_value()); | 399 __ Cmp(rax, Factory::the_hole_value()); |
404 __ j(equal, &miss); | 400 __ j(equal, &miss); |
405 } else if (FLAG_debug_code) { | 401 } else if (FLAG_debug_code) { |
406 __ Cmp(rax, Factory::the_hole_value()); | 402 __ Cmp(rax, Factory::the_hole_value()); |
407 __ Check(not_equal, "DontDelete cells can't contain the hole"); | 403 __ Check(not_equal, "DontDelete cells can't contain the hole"); |
408 } | 404 } |
409 | 405 |
| 406 __ IncrementCounter(&Counters::named_load_global_inline, 1); |
410 __ ret(0); | 407 __ ret(0); |
411 | 408 |
412 __ bind(&miss); | 409 __ bind(&miss); |
413 __ DecrementCounter(&Counters::named_load_global_inline, 1); | |
414 __ IncrementCounter(&Counters::named_load_global_inline_miss, 1); | 410 __ IncrementCounter(&Counters::named_load_global_inline_miss, 1); |
415 GenerateLoadMiss(masm(), Code::LOAD_IC); | 411 GenerateLoadMiss(masm(), Code::LOAD_IC); |
416 | 412 |
417 // Return the generated code. | 413 // Return the generated code. |
418 return GetCode(NORMAL, name); | 414 return GetCode(NORMAL, name); |
419 } | 415 } |
420 | 416 |
421 | 417 |
422 Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 418 Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { |
423 UNIMPLEMENTED(); | 419 UNIMPLEMENTED(); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 // Check that the map of the global has not changed. | 523 // Check that the map of the global has not changed. |
528 __ movq(rbx, Operand(rsp, kPointerSize)); | 524 __ movq(rbx, Operand(rsp, kPointerSize)); |
529 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), | 525 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), |
530 Handle<Map>(object->map())); | 526 Handle<Map>(object->map())); |
531 __ j(not_equal, &miss); | 527 __ j(not_equal, &miss); |
532 | 528 |
533 // Store the value in the cell. | 529 // Store the value in the cell. |
534 __ Move(rcx, Handle<JSGlobalPropertyCell>(cell)); | 530 __ Move(rcx, Handle<JSGlobalPropertyCell>(cell)); |
535 __ movq(FieldOperand(rcx, JSGlobalPropertyCell::kValueOffset), rax); | 531 __ movq(FieldOperand(rcx, JSGlobalPropertyCell::kValueOffset), rax); |
536 | 532 |
| 533 // Return the value (register rax). |
537 __ IncrementCounter(&Counters::named_store_global_inline, 1); | 534 __ IncrementCounter(&Counters::named_store_global_inline, 1); |
538 // Return the value (register rax). | |
539 __ ret(0); | 535 __ ret(0); |
540 | 536 |
541 // Handle store cache miss. | 537 // Handle store cache miss. |
542 __ bind(&miss); | 538 __ bind(&miss); |
543 __ IncrementCounter(&Counters::named_store_global_inline_miss, 1); | 539 __ IncrementCounter(&Counters::named_store_global_inline_miss, 1); |
544 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 540 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); |
545 __ Jump(ic, RelocInfo::CODE_TARGET); | 541 __ Jump(ic, RelocInfo::CODE_TARGET); |
546 | 542 |
547 // Return the generated code. | 543 // Return the generated code. |
548 return GetCode(NORMAL, name); | 544 return GetCode(NORMAL, name); |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 | 897 |
902 // Return the value (register rax). | 898 // Return the value (register rax). |
903 __ ret(0); | 899 __ ret(0); |
904 } | 900 } |
905 | 901 |
906 | 902 |
907 #undef __ | 903 #undef __ |
908 | 904 |
909 | 905 |
910 } } // namespace v8::internal | 906 } } // namespace v8::internal |
OLD | NEW |