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 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 | 309 |
310 Object* LoadStubCompiler::CompileLoadCallback(JSObject* a, | 310 Object* LoadStubCompiler::CompileLoadCallback(JSObject* a, |
311 JSObject* b, | 311 JSObject* b, |
312 AccessorInfo* c, | 312 AccessorInfo* c, |
313 String* d) { | 313 String* d) { |
314 // TODO(X64): Implement a real stub. | 314 // TODO(X64): Implement a real stub. |
315 return Failure::InternalError(); | 315 return Failure::InternalError(); |
316 } | 316 } |
317 | 317 |
318 | 318 |
319 Object* LoadStubCompiler::CompileLoadConstant(JSObject* a, | 319 Object* LoadStubCompiler::CompileLoadConstant(JSObject* object, |
320 JSObject* b, | 320 JSObject* holder, |
321 Object* c, | 321 Object* value, |
322 String* d) { | 322 String* name) { |
323 // TODO(X64): Implement a real stub. | 323 // ----------- S t a t e ------------- |
324 return Failure::InternalError(); | 324 // -- rcx : name |
| 325 // -- rsp[0] : return address |
| 326 // -- rsp[8] : receiver |
| 327 // ----------------------------------- |
| 328 Label miss; |
| 329 |
| 330 __ movq(rax, (Operand(rsp, kPointerSize))); |
| 331 GenerateLoadConstant(object, holder, rax, rbx, rdx, value, name, &miss); |
| 332 __ bind(&miss); |
| 333 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 334 |
| 335 // Return the generated code. |
| 336 return GetCode(CONSTANT_FUNCTION, name); |
325 } | 337 } |
326 | 338 |
327 | 339 |
328 Object* LoadStubCompiler::CompileLoadField(JSObject* a, | 340 Object* LoadStubCompiler::CompileLoadField(JSObject* object, |
329 JSObject* b, | 341 JSObject* holder, |
330 int c, | 342 int index, |
331 String* d) { | 343 String* name) { |
332 // TODO(X64): Implement a real stub. | 344 // ----------- S t a t e ------------- |
333 return Failure::InternalError(); | 345 // -- rcx : name |
| 346 // -- rsp[0] : return address |
| 347 // -- rsp[8] : receiver |
| 348 // ----------------------------------- |
| 349 Label miss; |
| 350 |
| 351 __ movq(rax, (Operand(rsp, kPointerSize))); |
| 352 GenerateLoadField(object, holder, rax, rbx, rdx, index, name, &miss); |
| 353 __ bind(&miss); |
| 354 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 355 |
| 356 // Return the generated code. |
| 357 return GetCode(FIELD, name); |
334 } | 358 } |
335 | 359 |
336 | 360 |
337 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* a, | 361 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* a, |
338 JSObject* b, | 362 JSObject* b, |
339 String* c) { | 363 String* c) { |
340 // TODO(X64): Implement a real stub. | 364 // TODO(X64): Implement a real stub. |
341 return Failure::InternalError(); | 365 return Failure::InternalError(); |
342 } | 366 } |
343 | 367 |
344 | 368 |
345 Object* LoadStubCompiler::CompileLoadGlobal(JSObject* object, | 369 Object* LoadStubCompiler::CompileLoadGlobal(JSObject* object, |
346 GlobalObject* holder, | 370 GlobalObject* holder, |
347 JSGlobalPropertyCell* cell, | 371 JSGlobalPropertyCell* cell, |
348 String* name, | 372 String* name, |
349 bool is_dont_delete) { | 373 bool is_dont_delete) { |
350 // TODO(X64): Implement a real stub. | 374 // ----------- S t a t e ------------- |
351 return Failure::InternalError(); | 375 // -- rcx : name |
| 376 // -- rsp[0] : return address |
| 377 // -- rsp[8] : receiver |
| 378 // ----------------------------------- |
| 379 Label miss; |
| 380 |
| 381 __ IncrementCounter(&Counters::named_load_global_inline, 1); |
| 382 |
| 383 // Get the receiver from the stack. |
| 384 __ movq(rax, (Operand(rsp, kPointerSize))); |
| 385 |
| 386 // 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, |
| 388 // the receiver cannot be a smi. |
| 389 if (object != holder) { |
| 390 __ testl(rax, Immediate(kSmiTagMask)); |
| 391 __ j(zero, &miss); |
| 392 } |
| 393 |
| 394 // Check that the maps haven't changed. |
| 395 CheckPrototypes(object, rax, holder, rbx, rdx, name, &miss); |
| 396 |
| 397 // Get the value from the cell. |
| 398 __ Move(rax, Handle<JSGlobalPropertyCell>(cell)); |
| 399 __ movq(rax, FieldOperand(rax, JSGlobalPropertyCell::kValueOffset)); |
| 400 |
| 401 // Check for deleted property if property can actually be deleted. |
| 402 if (!is_dont_delete) { |
| 403 __ Cmp(rax, Factory::the_hole_value()); |
| 404 __ j(equal, &miss); |
| 405 } else if (FLAG_debug_code) { |
| 406 __ Cmp(rax, Factory::the_hole_value()); |
| 407 __ Check(not_equal, "DontDelete cells can't contain the hole"); |
| 408 } |
| 409 |
| 410 __ ret(0); |
| 411 |
| 412 __ bind(&miss); |
| 413 __ DecrementCounter(&Counters::named_load_global_inline, 1); |
| 414 __ IncrementCounter(&Counters::named_load_global_inline_miss, 1); |
| 415 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 416 |
| 417 // Return the generated code. |
| 418 return GetCode(NORMAL, name); |
352 } | 419 } |
353 | 420 |
354 | 421 |
355 Object* StoreStubCompiler::CompileStoreCallback(JSObject* a, | 422 Object* StoreStubCompiler::CompileStoreCallback(JSObject* a, |
356 AccessorInfo* b, | 423 AccessorInfo* b, |
357 String* c) { | 424 String* c) { |
358 UNIMPLEMENTED(); | 425 UNIMPLEMENTED(); |
359 return NULL; | 426 return NULL; |
360 } | 427 } |
361 | 428 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 Factory::the_hole_value()); | 502 Factory::the_hole_value()); |
436 __ j(not_equal, miss); | 503 __ j(not_equal, miss); |
437 } | 504 } |
438 object = JSObject::cast(object->GetPrototype()); | 505 object = JSObject::cast(object->GetPrototype()); |
439 } | 506 } |
440 | 507 |
441 // Return the register containing the holder. | 508 // Return the register containing the holder. |
442 return result; | 509 return result; |
443 } | 510 } |
444 | 511 |
| 512 |
| 513 void StubCompiler::GenerateLoadField(JSObject* object, |
| 514 JSObject* holder, |
| 515 Register receiver, |
| 516 Register scratch1, |
| 517 Register scratch2, |
| 518 int index, |
| 519 String* name, |
| 520 Label* miss) { |
| 521 // Check that the receiver isn't a smi. |
| 522 __ testl(receiver, Immediate(kSmiTagMask)); |
| 523 __ j(zero, miss); |
| 524 |
| 525 // Check the prototype chain. |
| 526 Register reg = |
| 527 CheckPrototypes(object, receiver, holder, |
| 528 scratch1, scratch2, name, miss); |
| 529 |
| 530 // Get the value from the properties. |
| 531 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); |
| 532 __ ret(0); |
| 533 } |
| 534 |
| 535 |
| 536 void StubCompiler::GenerateLoadConstant(JSObject* object, |
| 537 JSObject* holder, |
| 538 Register receiver, |
| 539 Register scratch1, |
| 540 Register scratch2, |
| 541 Object* value, |
| 542 String* name, |
| 543 Label* miss) { |
| 544 // Check that the receiver isn't a smi. |
| 545 __ testl(receiver, Immediate(kSmiTagMask)); |
| 546 __ j(zero, miss); |
| 547 |
| 548 // Check that the maps haven't changed. |
| 549 Register reg = |
| 550 CheckPrototypes(object, receiver, holder, |
| 551 scratch1, scratch2, name, miss); |
| 552 |
| 553 // Return the constant value. |
| 554 __ Move(rax, Handle<Object>(value)); |
| 555 __ ret(0); |
| 556 } |
| 557 |
| 558 |
445 #undef __ | 559 #undef __ |
446 | 560 |
447 //----------------------------------------------------------------------------- | 561 //----------------------------------------------------------------------------- |
448 // StubCompiler static helper functions | 562 // StubCompiler static helper functions |
449 | 563 |
450 #define __ ACCESS_MASM(masm) | 564 #define __ ACCESS_MASM(masm) |
451 | 565 |
| 566 |
| 567 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { |
| 568 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); |
| 569 Code* code = NULL; |
| 570 if (kind == Code::LOAD_IC) { |
| 571 code = Builtins::builtin(Builtins::LoadIC_Miss); |
| 572 } else { |
| 573 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); |
| 574 } |
| 575 |
| 576 Handle<Code> ic(code); |
| 577 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 578 } |
| 579 |
| 580 |
452 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, | 581 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, |
453 int index, | 582 int index, |
454 Register prototype) { | 583 Register prototype) { |
455 // Load the global or builtins object from the current context. | 584 // Load the global or builtins object from the current context. |
456 __ movq(prototype, | 585 __ movq(prototype, |
457 Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); | 586 Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
458 // Load the global context from the global or builtins object. | 587 // Load the global context from the global or builtins object. |
459 __ movq(prototype, | 588 __ movq(prototype, |
460 FieldOperand(prototype, GlobalObject::kGlobalContextOffset)); | 589 FieldOperand(prototype, GlobalObject::kGlobalContextOffset)); |
461 // Load the function from the global context. | 590 // Load the function from the global context. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 // Cache miss: Fall-through and let caller handle the miss by | 630 // Cache miss: Fall-through and let caller handle the miss by |
502 // entering the runtime system. | 631 // entering the runtime system. |
503 __ bind(&miss); | 632 __ bind(&miss); |
504 } | 633 } |
505 | 634 |
506 | 635 |
507 #undef __ | 636 #undef __ |
508 | 637 |
509 | 638 |
510 } } // namespace v8::internal | 639 } } // namespace v8::internal |
OLD | NEW |