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

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

Issue 6392003: Minor cleanup: Use MaybeObject instead of bool and Failure** in... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 11 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 | « src/stub-cache.h ('k') | 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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 // -- rsp[kFastApiCallArguments * 8 + 8] : last argument in the internal 430 // -- rsp[kFastApiCallArguments * 8 + 8] : last argument in the internal
431 // frame. 431 // frame.
432 // ----------------------------------- 432 // -----------------------------------
433 __ movq(scratch, Operand(rsp, 0)); 433 __ movq(scratch, Operand(rsp, 0));
434 __ movq(Operand(rsp, kFastApiCallArguments * kPointerSize), scratch); 434 __ movq(Operand(rsp, kFastApiCallArguments * kPointerSize), scratch);
435 __ addq(rsp, Immediate(kPointerSize * kFastApiCallArguments)); 435 __ addq(rsp, Immediate(kPointerSize * kFastApiCallArguments));
436 } 436 }
437 437
438 438
439 // Generates call to API function. 439 // Generates call to API function.
440 static bool GenerateFastApiCall(MacroAssembler* masm, 440 static MaybeObject* GenerateFastApiCall(MacroAssembler* masm,
441 const CallOptimization& optimization, 441 const CallOptimization& optimization,
442 int argc, 442 int argc) {
443 Failure** failure) {
444 // ----------- S t a t e ------------- 443 // ----------- S t a t e -------------
445 // -- rsp[0] : return address 444 // -- rsp[0] : return address
446 // -- rsp[8] : object passing the type check 445 // -- rsp[8] : object passing the type check
447 // (last fast api call extra argument, 446 // (last fast api call extra argument,
448 // set by CheckPrototypes) 447 // set by CheckPrototypes)
449 // -- rsp[16] : api function 448 // -- rsp[16] : api function
450 // (first fast api call extra argument) 449 // (first fast api call extra argument)
451 // -- rsp[24] : api call data 450 // -- rsp[24] : api call data
452 // -- rsp[32] : last argument 451 // -- rsp[32] : last argument
453 // -- ... 452 // -- ...
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 __ Set(StackSpaceOperand(2), argc); // v8::Arguments::length_. 496 __ Set(StackSpaceOperand(2), argc); // v8::Arguments::length_.
498 // v8::Arguments::is_construct_call_. 497 // v8::Arguments::is_construct_call_.
499 __ Set(StackSpaceOperand(3), 0); 498 __ Set(StackSpaceOperand(3), 0);
500 499
501 // v8::InvocationCallback's argument. 500 // v8::InvocationCallback's argument.
502 __ lea(arguments_arg, StackSpaceOperand(0)); 501 __ lea(arguments_arg, StackSpaceOperand(0));
503 // Emitting a stub call may try to allocate (if the code is not 502 // Emitting a stub call may try to allocate (if the code is not
504 // already generated). Do not allow the assembler to perform a 503 // already generated). Do not allow the assembler to perform a
505 // garbage collection but instead return the allocation failure 504 // garbage collection but instead return the allocation failure
506 // object. 505 // object.
507 MaybeObject* result = 506 return masm->TryCallApiFunctionAndReturn(&fun,
508 masm->TryCallApiFunctionAndReturn(&fun, argc + kFastApiCallArguments + 1); 507 argc + kFastApiCallArguments + 1);
509 if (result->IsFailure()) {
510 *failure = Failure::cast(result);
511 return false;
512 }
513 return true;
514 } 508 }
515 509
516 510
517 class CallInterceptorCompiler BASE_EMBEDDED { 511 class CallInterceptorCompiler BASE_EMBEDDED {
518 public: 512 public:
519 CallInterceptorCompiler(StubCompiler* stub_compiler, 513 CallInterceptorCompiler(StubCompiler* stub_compiler,
520 const ParameterCount& arguments, 514 const ParameterCount& arguments,
521 Register name) 515 Register name)
522 : stub_compiler_(stub_compiler), 516 : stub_compiler_(stub_compiler),
523 arguments_(arguments), 517 arguments_(arguments),
524 name_(name) {} 518 name_(name) {}
525 519
526 bool Compile(MacroAssembler* masm, 520 MaybeObject* Compile(MacroAssembler* masm,
527 JSObject* object, 521 JSObject* object,
528 JSObject* holder, 522 JSObject* holder,
529 String* name, 523 String* name,
530 LookupResult* lookup, 524 LookupResult* lookup,
531 Register receiver, 525 Register receiver,
532 Register scratch1, 526 Register scratch1,
533 Register scratch2, 527 Register scratch2,
534 Register scratch3, 528 Register scratch3,
535 Label* miss, 529 Label* miss) {
536 Failure** failure) {
537 ASSERT(holder->HasNamedInterceptor()); 530 ASSERT(holder->HasNamedInterceptor());
538 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); 531 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
539 532
540 // Check that the receiver isn't a smi. 533 // Check that the receiver isn't a smi.
541 __ JumpIfSmi(receiver, miss); 534 __ JumpIfSmi(receiver, miss);
542 535
543 CallOptimization optimization(lookup); 536 CallOptimization optimization(lookup);
544 537
545 if (optimization.is_constant_call()) { 538 if (optimization.is_constant_call()) {
546 return CompileCacheable(masm, 539 return CompileCacheable(masm,
547 object, 540 object,
548 receiver, 541 receiver,
549 scratch1, 542 scratch1,
550 scratch2, 543 scratch2,
551 scratch3, 544 scratch3,
552 holder, 545 holder,
553 lookup, 546 lookup,
554 name, 547 name,
555 optimization, 548 optimization,
556 miss, 549 miss);
557 failure);
558 } else { 550 } else {
559 CompileRegular(masm, 551 CompileRegular(masm,
560 object, 552 object,
561 receiver, 553 receiver,
562 scratch1, 554 scratch1,
563 scratch2, 555 scratch2,
564 scratch3, 556 scratch3,
565 name, 557 name,
566 holder, 558 holder,
567 miss); 559 miss);
568 return true; 560 return Heap::undefined_value(); // Success.
569 } 561 }
570 } 562 }
571 563
572 private: 564 private:
573 bool CompileCacheable(MacroAssembler* masm, 565 MaybeObject* CompileCacheable(MacroAssembler* masm,
574 JSObject* object, 566 JSObject* object,
575 Register receiver, 567 Register receiver,
576 Register scratch1, 568 Register scratch1,
577 Register scratch2, 569 Register scratch2,
578 Register scratch3, 570 Register scratch3,
579 JSObject* interceptor_holder, 571 JSObject* interceptor_holder,
580 LookupResult* lookup, 572 LookupResult* lookup,
581 String* name, 573 String* name,
582 const CallOptimization& optimization, 574 const CallOptimization& optimization,
583 Label* miss_label, 575 Label* miss_label) {
584 Failure** failure) {
585 ASSERT(optimization.is_constant_call()); 576 ASSERT(optimization.is_constant_call());
586 ASSERT(!lookup->holder()->IsGlobalObject()); 577 ASSERT(!lookup->holder()->IsGlobalObject());
587 578
588 int depth1 = kInvalidProtoDepth; 579 int depth1 = kInvalidProtoDepth;
589 int depth2 = kInvalidProtoDepth; 580 int depth2 = kInvalidProtoDepth;
590 bool can_do_fast_api_call = false; 581 bool can_do_fast_api_call = false;
591 if (optimization.is_simple_api_call() && 582 if (optimization.is_simple_api_call() &&
592 !lookup->holder()->IsGlobalObject()) { 583 !lookup->holder()->IsGlobalObject()) {
593 depth1 = 584 depth1 =
594 optimization.GetPrototypeDepthOfExpectedType(object, 585 optimization.GetPrototypeDepthOfExpectedType(object,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 } else { 627 } else {
637 // CheckPrototypes has a side effect of fetching a 'holder' 628 // CheckPrototypes has a side effect of fetching a 'holder'
638 // for API (object which is instanceof for the signature). It's 629 // for API (object which is instanceof for the signature). It's
639 // safe to omit it here, as if present, it should be fetched 630 // safe to omit it here, as if present, it should be fetched
640 // by the previous CheckPrototypes. 631 // by the previous CheckPrototypes.
641 ASSERT(depth2 == kInvalidProtoDepth); 632 ASSERT(depth2 == kInvalidProtoDepth);
642 } 633 }
643 634
644 // Invoke function. 635 // Invoke function.
645 if (can_do_fast_api_call) { 636 if (can_do_fast_api_call) {
646 bool success = GenerateFastApiCall(masm, 637 MaybeObject* result = GenerateFastApiCall(masm,
647 optimization, 638 optimization,
648 arguments_.immediate(), 639 arguments_.immediate());
649 failure); 640 if (result->IsFailure()) return result;
650 if (!success) {
651 return false;
652 }
653 } else { 641 } else {
654 __ InvokeFunction(optimization.constant_function(), arguments_, 642 __ InvokeFunction(optimization.constant_function(), arguments_,
655 JUMP_FUNCTION); 643 JUMP_FUNCTION);
656 } 644 }
657 645
658 // Deferred code for fast API call case---clean preallocated space. 646 // Deferred code for fast API call case---clean preallocated space.
659 if (can_do_fast_api_call) { 647 if (can_do_fast_api_call) {
660 __ bind(&miss_cleanup); 648 __ bind(&miss_cleanup);
661 FreeSpaceForFastApiCall(masm, scratch1); 649 FreeSpaceForFastApiCall(masm, scratch1);
662 __ jmp(miss_label); 650 __ jmp(miss_label);
663 } 651 }
664 652
665 // Invoke a regular function. 653 // Invoke a regular function.
666 __ bind(&regular_invoke); 654 __ bind(&regular_invoke);
667 if (can_do_fast_api_call) { 655 if (can_do_fast_api_call) {
668 FreeSpaceForFastApiCall(masm, scratch1); 656 FreeSpaceForFastApiCall(masm, scratch1);
669 } 657 }
670 658
671 return true; 659 return Heap::undefined_value(); // Success.
672 } 660 }
673 661
674 void CompileRegular(MacroAssembler* masm, 662 void CompileRegular(MacroAssembler* masm,
675 JSObject* object, 663 JSObject* object,
676 Register receiver, 664 Register receiver,
677 Register scratch1, 665 Register scratch1,
678 Register scratch2, 666 Register scratch2,
679 Register scratch3, 667 Register scratch3,
680 String* name, 668 String* name,
681 JSObject* interceptor_holder, 669 JSObject* interceptor_holder,
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 Register reg = 1002 Register reg =
1015 CheckPrototypes(object, receiver, holder, 1003 CheckPrototypes(object, receiver, holder,
1016 scratch1, scratch2, scratch3, name, miss); 1004 scratch1, scratch2, scratch3, name, miss);
1017 1005
1018 // Get the value from the properties. 1006 // Get the value from the properties.
1019 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); 1007 GenerateFastPropertyLoad(masm(), rax, reg, holder, index);
1020 __ ret(0); 1008 __ ret(0);
1021 } 1009 }
1022 1010
1023 1011
1024 bool StubCompiler::GenerateLoadCallback(JSObject* object, 1012 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object,
1025 JSObject* holder, 1013 JSObject* holder,
1026 Register receiver, 1014 Register receiver,
1027 Register name_reg, 1015 Register name_reg,
1028 Register scratch1, 1016 Register scratch1,
1029 Register scratch2, 1017 Register scratch2,
1030 Register scratch3, 1018 Register scratch3,
1031 AccessorInfo* callback, 1019 AccessorInfo* callback,
1032 String* name, 1020 String* name,
1033 Label* miss, 1021 Label* miss) {
1034 Failure** failure) {
1035 // Check that the receiver isn't a smi. 1022 // Check that the receiver isn't a smi.
1036 __ JumpIfSmi(receiver, miss); 1023 __ JumpIfSmi(receiver, miss);
1037 1024
1038 // Check that the maps haven't changed. 1025 // Check that the maps haven't changed.
1039 Register reg = 1026 Register reg =
1040 CheckPrototypes(object, receiver, holder, scratch1, 1027 CheckPrototypes(object, receiver, holder, scratch1,
1041 scratch2, scratch3, name, miss); 1028 scratch2, scratch3, name, miss);
1042 1029
1043 Handle<AccessorInfo> callback_handle(callback); 1030 Handle<AccessorInfo> callback_handle(callback);
1044 1031
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1088 __ movq(StackSpaceOperand(0), rax); 1075 __ movq(StackSpaceOperand(0), rax);
1089 1076
1090 // The context register (rsi) has been saved in PrepareCallApiFunction and 1077 // The context register (rsi) has been saved in PrepareCallApiFunction and
1091 // could be used to pass arguments. 1078 // could be used to pass arguments.
1092 __ lea(accessor_info_arg, StackSpaceOperand(0)); 1079 __ lea(accessor_info_arg, StackSpaceOperand(0));
1093 1080
1094 // Emitting a stub call may try to allocate (if the code is not 1081 // Emitting a stub call may try to allocate (if the code is not
1095 // already generated). Do not allow the assembler to perform a 1082 // already generated). Do not allow the assembler to perform a
1096 // garbage collection but instead return the allocation failure 1083 // garbage collection but instead return the allocation failure
1097 // object. 1084 // object.
1098 MaybeObject* result = masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace); 1085 return masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace);
1099 if (result->IsFailure()) {
1100 *failure = Failure::cast(result);
1101 return false;
1102 }
1103 return true;
1104 } 1086 }
1105 1087
1106 1088
1107 void StubCompiler::GenerateLoadConstant(JSObject* object, 1089 void StubCompiler::GenerateLoadConstant(JSObject* object,
1108 JSObject* holder, 1090 JSObject* holder,
1109 Register receiver, 1091 Register receiver,
1110 Register scratch1, 1092 Register scratch1,
1111 Register scratch2, 1093 Register scratch2,
1112 Register scratch3, 1094 Register scratch3,
1113 Object* value, 1095 Object* value,
(...skipping 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after
2128 rbx, rdx, rdi, name, &miss); 2110 rbx, rdx, rdi, name, &miss);
2129 } 2111 }
2130 break; 2112 break;
2131 } 2113 }
2132 2114
2133 default: 2115 default:
2134 UNREACHABLE(); 2116 UNREACHABLE();
2135 } 2117 }
2136 2118
2137 if (depth != kInvalidProtoDepth) { 2119 if (depth != kInvalidProtoDepth) {
2138 Failure* failure;
2139 // Move the return address on top of the stack. 2120 // Move the return address on top of the stack.
2140 __ movq(rax, Operand(rsp, 3 * kPointerSize)); 2121 __ movq(rax, Operand(rsp, 3 * kPointerSize));
2141 __ movq(Operand(rsp, 0 * kPointerSize), rax); 2122 __ movq(Operand(rsp, 0 * kPointerSize), rax);
2142 2123
2143 // rsp[2 * kPointerSize] is uninitialized, rsp[3 * kPointerSize] contains 2124 // rsp[2 * kPointerSize] is uninitialized, rsp[3 * kPointerSize] contains
2144 // duplicate of return address and will be overwritten. 2125 // duplicate of return address and will be overwritten.
2145 bool success = GenerateFastApiCall(masm(), optimization, argc, &failure); 2126 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc);
2146 if (!success) { 2127 if (result->IsFailure()) return result;
2147 return failure;
2148 }
2149 } else { 2128 } else {
2150 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); 2129 __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
2151 } 2130 }
2152 2131
2153 // Handle call cache miss. 2132 // Handle call cache miss.
2154 __ bind(&miss); 2133 __ bind(&miss);
2155 if (depth != kInvalidProtoDepth) { 2134 if (depth != kInvalidProtoDepth) {
2156 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2135 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2157 } 2136 }
2158 2137
(...skipping 28 matching lines...) Expand all
2187 // Get the number of arguments. 2166 // Get the number of arguments.
2188 const int argc = arguments().immediate(); 2167 const int argc = arguments().immediate();
2189 2168
2190 LookupResult lookup; 2169 LookupResult lookup;
2191 LookupPostInterceptor(holder, name, &lookup); 2170 LookupPostInterceptor(holder, name, &lookup);
2192 2171
2193 // Get the receiver from the stack. 2172 // Get the receiver from the stack.
2194 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2173 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
2195 2174
2196 CallInterceptorCompiler compiler(this, arguments(), rcx); 2175 CallInterceptorCompiler compiler(this, arguments(), rcx);
2197 Failure* failure; 2176 MaybeObject* result = compiler.Compile(masm(),
2198 bool success = compiler.Compile(masm(), 2177 object,
2199 object, 2178 holder,
2200 holder, 2179 name,
2201 name, 2180 &lookup,
2202 &lookup, 2181 rdx,
2203 rdx, 2182 rbx,
2204 rbx, 2183 rdi,
2205 rdi, 2184 rax,
2206 rax, 2185 &miss);
2207 &miss, 2186 if (result->IsFailure()) return result;
2208 &failure);
2209 if (!success) {
2210 return failure;
2211 }
2212 2187
2213 // Restore receiver. 2188 // Restore receiver.
2214 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2189 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
2215 2190
2216 // Check that the function really is a function. 2191 // Check that the function really is a function.
2217 __ JumpIfSmi(rax, &miss); 2192 __ JumpIfSmi(rax, &miss);
2218 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); 2193 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
2219 __ j(not_equal, &miss); 2194 __ j(not_equal, &miss);
2220 2195
2221 // Patch the receiver on the stack with the global proxy if 2196 // Patch the receiver on the stack with the global proxy if
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
2641 JSObject* object, 2616 JSObject* object,
2642 JSObject* holder, 2617 JSObject* holder,
2643 AccessorInfo* callback) { 2618 AccessorInfo* callback) {
2644 // ----------- S t a t e ------------- 2619 // ----------- S t a t e -------------
2645 // -- rax : receiver 2620 // -- rax : receiver
2646 // -- rcx : name 2621 // -- rcx : name
2647 // -- rsp[0] : return address 2622 // -- rsp[0] : return address
2648 // ----------------------------------- 2623 // -----------------------------------
2649 Label miss; 2624 Label miss;
2650 2625
2651 Failure* failure = Failure::InternalError(); 2626 MaybeObject* result = GenerateLoadCallback(object, holder, rax, rcx, rdx, rbx,
2652 bool success = GenerateLoadCallback(object, holder, rax, rcx, rdx, rbx, rdi, 2627 rdi, callback, name, &miss);
2653 callback, name, &miss, &failure); 2628 if (result->IsFailure()) {
2654 if (!success) {
2655 miss.Unuse(); 2629 miss.Unuse();
2656 return failure; 2630 return result;
2657 } 2631 }
2658 2632
2659 __ bind(&miss); 2633 __ bind(&miss);
2660 GenerateLoadMiss(masm(), Code::LOAD_IC); 2634 GenerateLoadMiss(masm(), Code::LOAD_IC);
2661 2635
2662 // Return the generated code. 2636 // Return the generated code.
2663 return GetCode(CALLBACKS, name); 2637 return GetCode(CALLBACKS, name);
2664 } 2638 }
2665 2639
2666 2640
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
2805 // -- rsp[0] : return address 2779 // -- rsp[0] : return address
2806 // ----------------------------------- 2780 // -----------------------------------
2807 Label miss; 2781 Label miss;
2808 2782
2809 __ IncrementCounter(&Counters::keyed_load_callback, 1); 2783 __ IncrementCounter(&Counters::keyed_load_callback, 1);
2810 2784
2811 // Check that the name has not changed. 2785 // Check that the name has not changed.
2812 __ Cmp(rax, Handle<String>(name)); 2786 __ Cmp(rax, Handle<String>(name));
2813 __ j(not_equal, &miss); 2787 __ j(not_equal, &miss);
2814 2788
2815 Failure* failure = Failure::InternalError(); 2789 MaybeObject* result = GenerateLoadCallback(receiver, holder, rdx, rax, rbx,
2816 bool success = GenerateLoadCallback(receiver, holder, rdx, rax, rbx, rcx, rdi, 2790 rcx, rdi, callback, name, &miss);
2817 callback, name, &miss, &failure); 2791 if (result->IsFailure()) {
2818 if (!success) {
2819 miss.Unuse(); 2792 miss.Unuse();
2820 return failure; 2793 return result;
2821 } 2794 }
2822 2795
2823 __ bind(&miss); 2796 __ bind(&miss);
2824 2797
2825 __ DecrementCounter(&Counters::keyed_load_callback, 1); 2798 __ DecrementCounter(&Counters::keyed_load_callback, 1);
2826 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 2799 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
2827 2800
2828 // Return the generated code. 2801 // Return the generated code.
2829 return GetCode(CALLBACKS, name); 2802 return GetCode(CALLBACKS, name);
2830 } 2803 }
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
3442 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); 3415 __ TailCallRuntime(Runtime::kSetProperty, 3, 1);
3443 3416
3444 return GetCode(flags); 3417 return GetCode(flags);
3445 } 3418 }
3446 3419
3447 #undef __ 3420 #undef __
3448 3421
3449 } } // namespace v8::internal 3422 } } // namespace v8::internal
3450 3423
3451 #endif // V8_TARGET_ARCH_X64 3424 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698