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

Side by Side Diff: src/codegen-ia32.cc

Issue 18596: Remove spilled code from SetValue and GetValue (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 11 years, 10 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 | src/virtual-frame-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 2990 matching lines...) Expand 10 before | Expand all | Expand 10 after
3001 case ObjectLiteral::Property::CONSTANT: break; 3001 case ObjectLiteral::Property::CONSTANT: break;
3002 case ObjectLiteral::Property::COMPUTED: { 3002 case ObjectLiteral::Property::COMPUTED: {
3003 Handle<Object> key(property->key()->handle()); 3003 Handle<Object> key(property->key()->handle());
3004 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 3004 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
3005 if (key->IsSymbol()) { 3005 if (key->IsSymbol()) {
3006 __ mov(eax, frame_->Top()); 3006 __ mov(eax, frame_->Top());
3007 frame_->EmitPush(eax); 3007 frame_->EmitPush(eax);
3008 LoadAndSpill(property->value()); 3008 LoadAndSpill(property->value());
3009 frame_->EmitPop(eax); 3009 frame_->EmitPop(eax);
3010 __ Set(ecx, Immediate(key)); 3010 __ Set(ecx, Immediate(key));
3011 frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); 3011 Result name = allocator()->Allocate(ecx);
3012 ASSERT(name.is_valid());
3013 Result value = allocator()->Allocate(eax);
3014 ASSERT(value.is_valid());
3015 frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, &value, &name, 0);
3012 frame_->Drop(); 3016 frame_->Drop();
3013 // Ignore result. 3017 // Ignore result.
3014 break; 3018 break;
3015 } 3019 }
3016 // Fall through 3020 // Fall through
3017 } 3021 }
3018 case ObjectLiteral::Property::PROTOTYPE: { 3022 case ObjectLiteral::Property::PROTOTYPE: {
3019 __ mov(eax, frame_->Top()); 3023 __ mov(eax, frame_->Top());
3020 frame_->EmitPush(eax); 3024 frame_->EmitPush(eax);
3021 LoadAndSpill(property->key()); 3025 LoadAndSpill(property->key());
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
3342 Load(node->expression()); 3346 Load(node->expression());
3343 LoadGlobal(); 3347 LoadGlobal();
3344 3348
3345 // Push the arguments ("left-to-right") on the stack. 3349 // Push the arguments ("left-to-right") on the stack.
3346 ZoneList<Expression*>* args = node->arguments(); 3350 ZoneList<Expression*>* args = node->arguments();
3347 int arg_count = args->length(); 3351 int arg_count = args->length();
3348 for (int i = 0; i < arg_count; i++) { 3352 for (int i = 0; i < arg_count; i++) {
3349 Load(args->at(i)); 3353 Load(args->at(i));
3350 } 3354 }
3351 3355
3352 // TODO(205): Get rid of this spilling. It is only necessary because
3353 // we load the function from the non-virtual stack.
3354 frame_->SpillAll();
3355
3356 // Constructors are called with the number of arguments in register 3356 // Constructors are called with the number of arguments in register
3357 // eax for now. Another option would be to have separate construct 3357 // eax for now. Another option would be to have separate construct
3358 // call trampolines per different arguments counts encountered. 3358 // call trampolines per different arguments counts encountered.
3359 __ Set(eax, Immediate(arg_count)); 3359 Result num_args = allocator()->Allocate(eax);
3360 ASSERT(num_args.is_valid());
3361 __ Set(num_args.reg(), Immediate(arg_count));
3360 3362
3361 // Load the function into temporary function slot as per calling 3363 // Load the function into temporary function slot as per calling
3362 // convention. 3364 // convention.
3363 __ mov(edi, frame_->ElementAt(arg_count + 1)); 3365 frame_->PushElementAt(arg_count + 1);
3366 Result function = frame_->Pop();
3367 function.ToRegister(edi);
3368 ASSERT(function.is_valid());
3364 3369
3365 // Call the construct call builtin that handles allocation and 3370 // Call the construct call builtin that handles allocation and
3366 // constructor invocation. 3371 // constructor invocation.
3367 CodeForSourcePosition(node->position()); 3372 CodeForSourcePosition(node->position());
3368 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall)); 3373 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall));
3369 Result result = frame_->CallCodeObject(ic, 3374 Result result = frame_->CallCodeObject(ic,
3370 RelocInfo::CONSTRUCT_CALL, 3375 RelocInfo::CONSTRUCT_CALL,
3376 &num_args,
3377 &function,
3371 args->length() + 1); 3378 args->length() + 1);
3372 3379
3373 // Replace the function on the stack with the result. 3380 // Replace the function on the stack with the result.
3374 frame_->SetElementAt(0, &result); 3381 frame_->SetElementAt(0, &result);
3375 } 3382 }
3376 3383
3377 3384
3378 void CodeGenerator::VisitCallEval(CallEval* node) { 3385 void CodeGenerator::VisitCallEval(CallEval* node) {
3379 VirtualFrame::SpilledScope spilled_scope(this); 3386 VirtualFrame::SpilledScope spilled_scope(this);
3380 Comment cmnt(masm_, "[ CallEval"); 3387 Comment cmnt(masm_, "[ CallEval");
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
3717 left.Unuse(); 3724 left.Unuse();
3718 true_target()->Branch(equal); 3725 true_target()->Branch(equal);
3719 false_target()->Jump(); 3726 false_target()->Jump();
3720 } 3727 }
3721 3728
3722 3729
3723 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { 3730 void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
3724 if (CheckForInlineRuntimeCall(node)) { 3731 if (CheckForInlineRuntimeCall(node)) {
3725 return; 3732 return;
3726 } 3733 }
3727 VirtualFrame::SpilledScope spilled_scope(this);
3728 3734
3729 ZoneList<Expression*>* args = node->arguments(); 3735 ZoneList<Expression*>* args = node->arguments();
3730 Comment cmnt(masm_, "[ CallRuntime"); 3736 Comment cmnt(masm_, "[ CallRuntime");
3731 Runtime::Function* function = node->function(); 3737 Runtime::Function* function = node->function();
3732 3738
3733 if (function == NULL) { 3739 if (function == NULL) {
3734 // Prepare stack for calling JS runtime function. 3740 // Prepare stack for calling JS runtime function.
3735 frame_->EmitPush(Immediate(node->name())); 3741 frame_->Push(node->name());
3736 // Push the builtins object found in the current global object. 3742 // Push the builtins object found in the current global object.
3737 __ mov(edx, GlobalObject()); 3743 Result temp = allocator()->Allocate();
3738 frame_->EmitPush(FieldOperand(edx, GlobalObject::kBuiltinsOffset)); 3744 ASSERT(temp.is_valid());
3745 __ mov(temp.reg(), GlobalObject());
3746 __ mov(temp.reg(), FieldOperand(temp.reg(), GlobalObject::kBuiltinsOffset));
3747 frame_->Push(&temp);
3739 } 3748 }
3740 3749
3741 // Push the arguments ("left-to-right"). 3750 // Push the arguments ("left-to-right").
3742 int arg_count = args->length(); 3751 int arg_count = args->length();
3743 for (int i = 0; i < arg_count; i++) { 3752 for (int i = 0; i < arg_count; i++) {
3744 LoadAndSpill(args->at(i)); 3753 Load(args->at(i));
3745 } 3754 }
3746 3755
3747 if (function == NULL) { 3756 if (function == NULL) {
3748 // Call the JS runtime function. 3757 // Call the JS runtime function.
3749 Handle<Code> stub = ComputeCallInitialize(arg_count); 3758 Handle<Code> stub = ComputeCallInitialize(arg_count);
3750 __ Set(eax, Immediate(args->length())); 3759
3751 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1); 3760 Result num_args = allocator()->Allocate(eax);
3761 ASSERT(num_args.is_valid());
3762 __ Set(num_args.reg(), Immediate(args->length()));
3763 Result answer = frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET,
3764 &num_args, arg_count + 1);
3752 frame_->RestoreContextRegister(); 3765 frame_->RestoreContextRegister();
3753 __ mov(frame_->Top(), eax); 3766 frame_->SetElementAt(0, &answer);
3754 } else { 3767 } else {
3755 // Call the C runtime function. 3768 // Call the C runtime function.
3756 frame_->CallRuntime(function, arg_count); 3769 Result answer = frame_->CallRuntime(function, arg_count);
3757 frame_->EmitPush(eax); 3770 frame_->Push(&answer);
3758 } 3771 }
3759 } 3772 }
3760 3773
3761 3774
3762 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { 3775 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
3763 // Note that because of NOT and an optimization in comparison of a typeof 3776 // Note that because of NOT and an optimization in comparison of a typeof
3764 // expression to a literal string, this function can fail to leave a value 3777 // expression to a literal string, this function can fail to leave a value
3765 // on top of the frame or in the cc register. 3778 // on top of the frame or in the cc register.
3766 Comment cmnt(masm_, "[ UnaryOperation"); 3779 Comment cmnt(masm_, "[ UnaryOperation");
3767 3780
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
4532 } else { 4545 } else {
4533 Literal* raw_name = property->key()->AsLiteral(); 4546 Literal* raw_name = property->key()->AsLiteral();
4534 ASSERT(raw_name != NULL); 4547 ASSERT(raw_name != NULL);
4535 return Handle<String>(String::cast(*raw_name->handle())); 4548 return Handle<String>(String::cast(*raw_name->handle()));
4536 } 4549 }
4537 } 4550 }
4538 4551
4539 4552
4540 void Reference::GetValue(TypeofState typeof_state) { 4553 void Reference::GetValue(TypeofState typeof_state) {
4541 ASSERT(!cgen_->in_spilled_code()); 4554 ASSERT(!cgen_->in_spilled_code());
4555 ASSERT(cgen_->HasValidEntryRegisters());
4542 ASSERT(!is_illegal()); 4556 ASSERT(!is_illegal());
4543 MacroAssembler* masm = cgen_->masm(); 4557 MacroAssembler* masm = cgen_->masm();
4544 switch (type_) { 4558 switch (type_) {
4545 case SLOT: { 4559 case SLOT: {
4546 Comment cmnt(masm, "[ Load from Slot"); 4560 Comment cmnt(masm, "[ Load from Slot");
4547 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); 4561 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
4548 ASSERT(slot != NULL); 4562 ASSERT(slot != NULL);
4549 cgen_->LoadFromSlot(slot, typeof_state); 4563 cgen_->LoadFromSlot(slot, typeof_state);
4550 break; 4564 break;
4551 } 4565 }
4552 4566
4553 case NAMED: { 4567 case NAMED: {
4554 // TODO(1241834): Make sure that it is safe to ignore the 4568 // TODO(1241834): Make sure that it is safe to ignore the
4555 // distinction between expressions in a typeof and not in a 4569 // distinction between expressions in a typeof and not in a
4556 // typeof. If there is a chance that reference errors can be 4570 // typeof. If there is a chance that reference errors can be
4557 // thrown below, we must distinguish between the two kinds of 4571 // thrown below, we must distinguish between the two kinds of
4558 // loads (typeof expression loads must not throw a reference 4572 // loads (typeof expression loads must not throw a reference
4559 // error). 4573 // error).
4560 VirtualFrame::SpilledScope spilled_scope(cgen_);
4561 VirtualFrame* frame = cgen_->frame(); 4574 VirtualFrame* frame = cgen_->frame();
4562 Comment cmnt(masm, "[ Load from named Property"); 4575 Comment cmnt(masm, "[ Load from named Property");
4563 Handle<String> name(GetName()); 4576 Handle<String> name(GetName());
4564 Variable* var = expression_->AsVariableProxy()->AsVariable(); 4577 Variable* var = expression_->AsVariableProxy()->AsVariable();
4565 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 4578 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
4566 // Setup the name register. 4579 // Setup the name register.
4567 __ mov(ecx, name); 4580 Result name_reg = cgen_->allocator()->Allocate(ecx);
4568 if (var != NULL) { 4581 ASSERT(name_reg.is_valid());
4569 ASSERT(var->is_global()); 4582 __ mov(name_reg.reg(), name);
4570 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET_CONTEXT, 0); 4583 ASSERT(var == NULL || var->is_global());
4571 } else { 4584 RelocInfo::Mode rmode = (var == NULL)
4572 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); 4585 ? RelocInfo::CODE_TARGET
4573 } 4586 : RelocInfo::CODE_TARGET_CONTEXT;
4574 frame->EmitPush(eax); // IC call leaves result in eax, push it out 4587 Result answer = frame->CallCodeObject(ic, rmode, &name_reg, 0);
4588 frame->Push(&answer);
4575 break; 4589 break;
4576 } 4590 }
4577 4591
4578 case KEYED: { 4592 case KEYED: {
4579 // TODO(1241834): Make sure that this it is safe to ignore the 4593 // TODO(1241834): Make sure that this it is safe to ignore the
4580 // distinction between expressions in a typeof and not in a typeof. 4594 // distinction between expressions in a typeof and not in a typeof.
4581 Comment cmnt(masm, "[ Load from keyed Property"); 4595 Comment cmnt(masm, "[ Load from keyed Property");
4582 Variable* var = expression_->AsVariableProxy()->AsVariable(); 4596 Variable* var = expression_->AsVariableProxy()->AsVariable();
4583 bool is_global = var != NULL; 4597 bool is_global = var != NULL;
4584 ASSERT(!is_global || var->is_global()); 4598 ASSERT(!is_global || var->is_global());
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
4654 __ IncrementCounter(&Counters::keyed_load_inline, 1); 4668 __ IncrementCounter(&Counters::keyed_load_inline, 1);
4655 4669
4656 // Restore the receiver and key to the frame and push the 4670 // Restore the receiver and key to the frame and push the
4657 // result on top of it. 4671 // result on top of it.
4658 cgen_->frame()->Push(&receiver); 4672 cgen_->frame()->Push(&receiver);
4659 cgen_->frame()->Push(&key); 4673 cgen_->frame()->Push(&key);
4660 deferred->exit()->Bind(&value); 4674 deferred->exit()->Bind(&value);
4661 cgen_->frame()->Push(&value); 4675 cgen_->frame()->Push(&value);
4662 4676
4663 } else { 4677 } else {
4664 VirtualFrame::SpilledScope spilled_scope(cgen_);
4665 VirtualFrame* frame = cgen_->frame(); 4678 VirtualFrame* frame = cgen_->frame();
4666 Comment cmnt(masm, "[ Load from keyed Property"); 4679 Comment cmnt(masm, "[ Load from keyed Property");
4667 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 4680 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
4668 if (is_global) { 4681 RelocInfo::Mode rmode = is_global
4669 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET_CONTEXT, 0); 4682 ? RelocInfo::CODE_TARGET_CONTEXT
4670 } else { 4683 : RelocInfo::CODE_TARGET;
4671 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); 4684 Result answer = frame->CallCodeObject(ic, rmode, 0);
4672 }
4673 // Make sure that we do not have a test instruction after the 4685 // Make sure that we do not have a test instruction after the
4674 // call. A test instruction after the call is used to 4686 // call. A test instruction after the call is used to
4675 // indicate that we have generated an inline version of the 4687 // indicate that we have generated an inline version of the
4676 // keyed load. The explicit nop instruction is here because 4688 // keyed load. The explicit nop instruction is here because
4677 // the push that follows might be peep-hole optimized away. 4689 // the push that follows might be peep-hole optimized away.
4678 __ nop(); 4690 __ nop();
4679 frame->EmitPush(eax); // IC call leaves result in eax, push it out 4691 frame->Push(&answer);
4680 } 4692 }
4681 break; 4693 break;
4682 } 4694 }
4683 4695
4684 default: 4696 default:
4685 UNREACHABLE(); 4697 UNREACHABLE();
4686 } 4698 }
4687 } 4699 }
4688 4700
4689 4701
(...skipping 21 matching lines...) Expand all
4711 if (slot->type() == Slot::PARAMETER) { 4723 if (slot->type() == Slot::PARAMETER) {
4712 cgen_->frame()->TakeParameterAt(slot->index()); 4724 cgen_->frame()->TakeParameterAt(slot->index());
4713 } else { 4725 } else {
4714 ASSERT(slot->type() == Slot::LOCAL); 4726 ASSERT(slot->type() == Slot::LOCAL);
4715 cgen_->frame()->TakeLocalAt(slot->index()); 4727 cgen_->frame()->TakeLocalAt(slot->index());
4716 } 4728 }
4717 } 4729 }
4718 4730
4719 4731
4720 void Reference::SetValue(InitState init_state) { 4732 void Reference::SetValue(InitState init_state) {
4733 ASSERT(cgen_->HasValidEntryRegisters());
4721 ASSERT(!is_illegal()); 4734 ASSERT(!is_illegal());
4722 MacroAssembler* masm = cgen_->masm(); 4735 MacroAssembler* masm = cgen_->masm();
4723 VirtualFrame* frame = cgen_->frame(); 4736 VirtualFrame* frame = cgen_->frame();
4724 switch (type_) { 4737 switch (type_) {
4725 case SLOT: { 4738 case SLOT: {
4726 Comment cmnt(masm, "[ Store to Slot"); 4739 Comment cmnt(masm, "[ Store to Slot");
4727 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); 4740 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
4728 ASSERT(slot != NULL); 4741 ASSERT(slot != NULL);
4729 cgen_->StoreToSlot(slot, init_state); 4742 cgen_->StoreToSlot(slot, init_state);
4730 break; 4743 break;
4731 } 4744 }
4732 4745
4733 case NAMED: { 4746 case NAMED: {
4734 VirtualFrame::SpilledScope spilled_scope(cgen_);
4735 Comment cmnt(masm, "[ Store to named Property"); 4747 Comment cmnt(masm, "[ Store to named Property");
4736 // Call the appropriate IC code. 4748 // Call the appropriate IC code.
4737 Handle<String> name(GetName()); 4749 Handle<String> name(GetName());
4738 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 4750 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
4739 // TODO(1222589): Make the IC grab the values from the stack. 4751 // TODO(1222589): Make the IC grab the values from the stack.
4740 frame->EmitPop(eax); 4752 Result argument = frame->Pop();
4753 argument.ToRegister(eax);
4754 ASSERT(argument.is_valid());
4755 Result property_name = cgen_->allocator()->Allocate(ecx);
4756 ASSERT(property_name.is_valid());
4741 // Setup the name register. 4757 // Setup the name register.
4742 __ mov(ecx, name); 4758 __ mov(property_name.reg(), name);
4743 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); 4759 Result answer = frame->CallCodeObject(ic, RelocInfo::CODE_TARGET,
4744 frame->EmitPush(eax); // IC call leaves result in eax, push it out 4760 &argument, &property_name, 0);
4761 frame->Push(&answer);
4745 break; 4762 break;
4746 } 4763 }
4747 4764
4748 case KEYED: { 4765 case KEYED: {
4749 VirtualFrame::SpilledScope spilled_scope(cgen_);
4750 Comment cmnt(masm, "[ Store to keyed Property"); 4766 Comment cmnt(masm, "[ Store to keyed Property");
4751 // Call IC code. 4767 // Call IC code.
4752 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 4768 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
4753 // TODO(1222589): Make the IC grab the values from the stack. 4769 // TODO(1222589): Make the IC grab the values from the stack.
4754 frame->EmitPop(eax); 4770 Result arg = frame->Pop();
4755 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); 4771 arg.ToRegister(eax);
4756 frame->EmitPush(eax); // IC call leaves result in eax, push it out 4772 ASSERT(arg.is_valid());
4773 Result answer = frame->CallCodeObject(ic, RelocInfo::CODE_TARGET,
4774 &arg, 0);
4775 frame->Push(&answer);
4757 break; 4776 break;
4758 } 4777 }
4759 4778
4760 default: 4779 default:
4761 UNREACHABLE(); 4780 UNREACHABLE();
4762 } 4781 }
4763 } 4782 }
4764 4783
4765 4784
4766 // NOTE: The stub does not handle the inlined cases (Smis, Booleans, undefined). 4785 // NOTE: The stub does not handle the inlined cases (Smis, Booleans, undefined).
(...skipping 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after
6247 6266
6248 // Slow-case: Go through the JavaScript implementation. 6267 // Slow-case: Go through the JavaScript implementation.
6249 __ bind(&slow); 6268 __ bind(&slow);
6250 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 6269 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
6251 } 6270 }
6252 6271
6253 6272
6254 #undef __ 6273 #undef __
6255 6274
6256 } } // namespace v8::internal 6275 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/virtual-frame-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698