Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 159131: X64: Implement inline caches for loads (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698