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

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

Issue 487017: Refactor Reference so that SetValue and GetValue pop the reference state. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 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/arm/codegen-arm.h ('k') | src/ia32/codegen-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-2009 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
11 // with the distribution. 11 // with the distribution.
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 // subexpression of a typeof. 598 // subexpression of a typeof.
599 LoadFromSlot(variable->slot(), INSIDE_TYPEOF); 599 LoadFromSlot(variable->slot(), INSIDE_TYPEOF);
600 frame_->SpillAll(); 600 frame_->SpillAll();
601 } else { 601 } else {
602 // Anything else can be handled normally. 602 // Anything else can be handled normally.
603 LoadAndSpill(expr); 603 LoadAndSpill(expr);
604 } 604 }
605 } 605 }
606 606
607 607
608 Reference::Reference(CodeGenerator* cgen, Expression* expression) 608 Reference::Reference(CodeGenerator* cgen,
609 : cgen_(cgen), expression_(expression), type_(ILLEGAL) { 609 Expression* expression,
610 bool persist_after_get)
611 : cgen_(cgen),
612 expression_(expression),
613 type_(ILLEGAL),
614 persist_after_get_(persist_after_get) {
610 cgen->LoadReference(this); 615 cgen->LoadReference(this);
611 } 616 }
612 617
613 618
614 Reference::~Reference() { 619 Reference::~Reference() {
615 cgen_->UnloadReference(this); 620 ASSERT(is_unloaded() || is_illegal());
616 } 621 }
617 622
618 623
619 void CodeGenerator::LoadReference(Reference* ref) { 624 void CodeGenerator::LoadReference(Reference* ref) {
620 VirtualFrame::SpilledScope spilled_scope; 625 VirtualFrame::SpilledScope spilled_scope;
621 Comment cmnt(masm_, "[ LoadReference"); 626 Comment cmnt(masm_, "[ LoadReference");
622 Expression* e = ref->expression(); 627 Expression* e = ref->expression();
623 Property* property = e->AsProperty(); 628 Property* property = e->AsProperty();
624 Variable* var = e->AsVariableProxy()->AsVariable(); 629 Variable* var = e->AsVariableProxy()->AsVariable();
625 630
(...skipping 28 matching lines...) Expand all
654 void CodeGenerator::UnloadReference(Reference* ref) { 659 void CodeGenerator::UnloadReference(Reference* ref) {
655 VirtualFrame::SpilledScope spilled_scope; 660 VirtualFrame::SpilledScope spilled_scope;
656 // Pop a reference from the stack while preserving TOS. 661 // Pop a reference from the stack while preserving TOS.
657 Comment cmnt(masm_, "[ UnloadReference"); 662 Comment cmnt(masm_, "[ UnloadReference");
658 int size = ref->size(); 663 int size = ref->size();
659 if (size > 0) { 664 if (size > 0) {
660 frame_->EmitPop(r0); 665 frame_->EmitPop(r0);
661 frame_->Drop(size); 666 frame_->Drop(size);
662 frame_->EmitPush(r0); 667 frame_->EmitPush(r0);
663 } 668 }
669 ref->set_unloaded();
664 } 670 }
665 671
666 672
667 // ECMA-262, section 9.2, page 30: ToBoolean(). Convert the given 673 // ECMA-262, section 9.2, page 30: ToBoolean(). Convert the given
668 // register to a boolean in the condition code register. The code 674 // register to a boolean in the condition code register. The code
669 // may jump to 'false_target' in case the register converts to 'false'. 675 // may jump to 'false_target' in case the register converts to 'false'.
670 void CodeGenerator::ToBoolean(JumpTarget* true_target, 676 void CodeGenerator::ToBoolean(JumpTarget* true_target,
671 JumpTarget* false_target) { 677 JumpTarget* false_target) {
672 VirtualFrame::SpilledScope spilled_scope; 678 VirtualFrame::SpilledScope spilled_scope;
673 // Note: The generated code snippet does not change stack variables. 679 // Note: The generated code snippet does not change stack variables.
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 } else { 1243 } else {
1238 val = node->fun(); // NULL if we don't have a function 1244 val = node->fun(); // NULL if we don't have a function
1239 } 1245 }
1240 1246
1241 if (val != NULL) { 1247 if (val != NULL) {
1242 { 1248 {
1243 // Set initial value. 1249 // Set initial value.
1244 Reference target(this, node->proxy()); 1250 Reference target(this, node->proxy());
1245 LoadAndSpill(val); 1251 LoadAndSpill(val);
1246 target.SetValue(NOT_CONST_INIT); 1252 target.SetValue(NOT_CONST_INIT);
1247 // The reference is removed from the stack (preserving TOS) when
1248 // it goes out of scope.
1249 } 1253 }
1250 // Get rid of the assigned value (declarations are statements). 1254 // Get rid of the assigned value (declarations are statements).
1251 frame_->Drop(); 1255 frame_->Drop();
1252 } 1256 }
1253 ASSERT(frame_->height() == original_height); 1257 ASSERT(frame_->height() == original_height);
1254 } 1258 }
1255 1259
1256 1260
1257 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { 1261 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
1258 #ifdef DEBUG 1262 #ifdef DEBUG
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after
1925 1929
1926 end_del_check.Bind(); 1930 end_del_check.Bind();
1927 // Store the entry in the 'each' expression and take another spin in the 1931 // Store the entry in the 'each' expression and take another spin in the
1928 // loop. r3: i'th entry of the enum cache (or string there of) 1932 // loop. r3: i'th entry of the enum cache (or string there of)
1929 frame_->EmitPush(r3); // push entry 1933 frame_->EmitPush(r3); // push entry
1930 { Reference each(this, node->each()); 1934 { Reference each(this, node->each());
1931 if (!each.is_illegal()) { 1935 if (!each.is_illegal()) {
1932 if (each.size() > 0) { 1936 if (each.size() > 0) {
1933 __ ldr(r0, frame_->ElementAt(each.size())); 1937 __ ldr(r0, frame_->ElementAt(each.size()));
1934 frame_->EmitPush(r0); 1938 frame_->EmitPush(r0);
1935 } 1939 each.SetValue(NOT_CONST_INIT);
1936 // If the reference was to a slot we rely on the convenient property 1940 frame_->Drop(2);
1937 // that it doesn't matter whether a value (eg, r3 pushed above) is 1941 } else {
1938 // right on top of or right underneath a zero-sized reference. 1942 // If the reference was to a slot we rely on the convenient property
1939 each.SetValue(NOT_CONST_INIT); 1943 // that it doesn't matter whether a value (eg, r3 pushed above) is
1940 if (each.size() > 0) { 1944 // right on top of or right underneath a zero-sized reference.
1941 // It's safe to pop the value lying on top of the reference before 1945 each.SetValue(NOT_CONST_INIT);
1942 // unloading the reference itself (which preserves the top of stack, 1946 frame_->Drop();
1943 // ie, now the topmost value of the non-zero sized reference), since
1944 // we will discard the top of stack after unloading the reference
1945 // anyway.
1946 frame_->EmitPop(r0);
1947 } 1947 }
1948 } 1948 }
1949 } 1949 }
1950 // Discard the i'th entry pushed above or else the remainder of the
1951 // reference, whichever is currently on top of the stack.
1952 frame_->Drop();
1953
1954 // Body. 1950 // Body.
1955 CheckStack(); // TODO(1222600): ignore if body contains calls. 1951 CheckStack(); // TODO(1222600): ignore if body contains calls.
1956 VisitAndSpill(node->body()); 1952 VisitAndSpill(node->body());
1957 1953
1958 // Next. Reestablish a spilled frame in case we are coming here via 1954 // Next. Reestablish a spilled frame in case we are coming here via
1959 // a continue in the body. 1955 // a continue in the body.
1960 node->continue_target()->Bind(); 1956 node->continue_target()->Bind();
1961 frame_->SpillAll(); 1957 frame_->SpillAll();
1962 frame_->EmitPop(r0); 1958 frame_->EmitPop(r0);
1963 __ add(r0, r0, Operand(Smi::FromInt(1))); 1959 __ add(r0, r0, Operand(Smi::FromInt(1)));
(...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after
2837 } 2833 }
2838 2834
2839 2835
2840 void CodeGenerator::VisitAssignment(Assignment* node) { 2836 void CodeGenerator::VisitAssignment(Assignment* node) {
2841 #ifdef DEBUG 2837 #ifdef DEBUG
2842 int original_height = frame_->height(); 2838 int original_height = frame_->height();
2843 #endif 2839 #endif
2844 VirtualFrame::SpilledScope spilled_scope; 2840 VirtualFrame::SpilledScope spilled_scope;
2845 Comment cmnt(masm_, "[ Assignment"); 2841 Comment cmnt(masm_, "[ Assignment");
2846 2842
2847 { Reference target(this, node->target()); 2843 { Reference target(this, node->target(), node->is_compound());
2848 if (target.is_illegal()) { 2844 if (target.is_illegal()) {
2849 // Fool the virtual frame into thinking that we left the assignment's 2845 // Fool the virtual frame into thinking that we left the assignment's
2850 // value on the frame. 2846 // value on the frame.
2851 __ mov(r0, Operand(Smi::FromInt(0))); 2847 __ mov(r0, Operand(Smi::FromInt(0)));
2852 frame_->EmitPush(r0); 2848 frame_->EmitPush(r0);
2853 ASSERT(frame_->height() == original_height + 1); 2849 ASSERT(frame_->height() == original_height + 1);
2854 return; 2850 return;
2855 } 2851 }
2856 2852
2857 if (node->op() == Token::ASSIGN || 2853 if (node->op() == Token::ASSIGN ||
2858 node->op() == Token::INIT_VAR || 2854 node->op() == Token::INIT_VAR ||
2859 node->op() == Token::INIT_CONST) { 2855 node->op() == Token::INIT_CONST) {
2860 LoadAndSpill(node->value()); 2856 LoadAndSpill(node->value());
2861 2857
2862 } else { 2858 } else { // Assignment is a compound assignment.
2863 // +=, *= and similar binary assignments.
2864 // Get the old value of the lhs. 2859 // Get the old value of the lhs.
2865 target.GetValueAndSpill(); 2860 target.GetValueAndSpill();
2866 Literal* literal = node->value()->AsLiteral(); 2861 Literal* literal = node->value()->AsLiteral();
2867 bool overwrite = 2862 bool overwrite =
2868 (node->value()->AsBinaryOperation() != NULL && 2863 (node->value()->AsBinaryOperation() != NULL &&
2869 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 2864 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
2870 if (literal != NULL && literal->handle()->IsSmi()) { 2865 if (literal != NULL && literal->handle()->IsSmi()) {
2871 SmiOperation(node->binary_op(), 2866 SmiOperation(node->binary_op(),
2872 literal->handle(), 2867 literal->handle(),
2873 false, 2868 false,
2874 overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE); 2869 overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE);
2875 frame_->EmitPush(r0); 2870 frame_->EmitPush(r0);
2876 2871
2877 } else { 2872 } else {
2878 LoadAndSpill(node->value()); 2873 LoadAndSpill(node->value());
2879 GenericBinaryOperation(node->binary_op(), 2874 GenericBinaryOperation(node->binary_op(),
2880 overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE); 2875 overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE);
2881 frame_->EmitPush(r0); 2876 frame_->EmitPush(r0);
2882 } 2877 }
2883 } 2878 }
2884
2885 Variable* var = node->target()->AsVariableProxy()->AsVariable(); 2879 Variable* var = node->target()->AsVariableProxy()->AsVariable();
2886 if (var != NULL && 2880 if (var != NULL &&
2887 (var->mode() == Variable::CONST) && 2881 (var->mode() == Variable::CONST) &&
2888 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) { 2882 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
2889 // Assignment ignored - leave the value on the stack. 2883 // Assignment ignored - leave the value on the stack.
2890 2884 UnloadReference(&target);
2891 } else { 2885 } else {
2892 CodeForSourcePosition(node->position()); 2886 CodeForSourcePosition(node->position());
2893 if (node->op() == Token::INIT_CONST) { 2887 if (node->op() == Token::INIT_CONST) {
2894 // Dynamic constant initializations must use the function context 2888 // Dynamic constant initializations must use the function context
2895 // and initialize the actual constant declared. Dynamic variable 2889 // and initialize the actual constant declared. Dynamic variable
2896 // initializations are simply assignments and use SetValue. 2890 // initializations are simply assignments and use SetValue.
2897 target.SetValue(CONST_INIT); 2891 target.SetValue(CONST_INIT);
2898 } else { 2892 } else {
2899 target.SetValue(NOT_CONST_INIT); 2893 target.SetValue(NOT_CONST_INIT);
2900 } 2894 }
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
3090 // Remove the function from the stack. 3084 // Remove the function from the stack.
3091 frame_->Drop(); 3085 frame_->Drop();
3092 3086
3093 frame_->EmitPush(r0); // push after get rid of function from the stack 3087 frame_->EmitPush(r0); // push after get rid of function from the stack
3094 3088
3095 } else { 3089 } else {
3096 // ------------------------------------------- 3090 // -------------------------------------------
3097 // JavaScript example: 'array[index](1, 2, 3)' 3091 // JavaScript example: 'array[index](1, 2, 3)'
3098 // ------------------------------------------- 3092 // -------------------------------------------
3099 3093
3100 // Load the function to call from the property through a reference. 3094 LoadAndSpill(property->obj());
3101 Reference ref(this, property); 3095 LoadAndSpill(property->key());
3102 ref.GetValueAndSpill(); // receiver 3096 EmitKeyedLoad(false);
3103 3097 frame_->Drop(); // key
3104 // Pass receiver to called function. 3098 // Put the function below the receiver.
3105 if (property->is_synthetic()) { 3099 if (property->is_synthetic()) {
3100 // Use the global receiver.
3101 frame_->Drop();
3102 frame_->EmitPush(r0);
3106 LoadGlobalReceiver(r0); 3103 LoadGlobalReceiver(r0);
3107 } else { 3104 } else {
3108 __ ldr(r0, frame_->ElementAt(ref.size())); 3105 frame_->EmitPop(r1); // receiver
3109 frame_->EmitPush(r0); 3106 frame_->EmitPush(r0); // function
3107 frame_->EmitPush(r1); // receiver
3110 } 3108 }
3111 3109
3112 // Call the function. 3110 // Call the function.
3113 CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position()); 3111 CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position());
3114 frame_->EmitPush(r0); 3112 frame_->EmitPush(r0);
3115 } 3113 }
3116 3114
3117 } else { 3115 } else {
3118 // ---------------------------------- 3116 // ----------------------------------
3119 // JavaScript example: 'foo(1, 2, 3)' // foo is not global 3117 // JavaScript example: 'foo(1, 2, 3)' // foo is not global
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
3800 3798
3801 Variable* var = node->expression()->AsVariableProxy()->AsVariable(); 3799 Variable* var = node->expression()->AsVariableProxy()->AsVariable();
3802 bool is_const = (var != NULL && var->mode() == Variable::CONST); 3800 bool is_const = (var != NULL && var->mode() == Variable::CONST);
3803 3801
3804 // Postfix: Make room for the result. 3802 // Postfix: Make room for the result.
3805 if (is_postfix) { 3803 if (is_postfix) {
3806 __ mov(r0, Operand(0)); 3804 __ mov(r0, Operand(0));
3807 frame_->EmitPush(r0); 3805 frame_->EmitPush(r0);
3808 } 3806 }
3809 3807
3810 { Reference target(this, node->expression()); 3808 // A constant reference is not saved to, so a constant reference is not a
3809 // compound assignment reference.
3810 { Reference target(this, node->expression(), !is_const);
3811 if (target.is_illegal()) { 3811 if (target.is_illegal()) {
3812 // Spoof the virtual frame to have the expected height (one higher 3812 // Spoof the virtual frame to have the expected height (one higher
3813 // than on entry). 3813 // than on entry).
3814 if (!is_postfix) { 3814 if (!is_postfix) {
3815 __ mov(r0, Operand(Smi::FromInt(0))); 3815 __ mov(r0, Operand(Smi::FromInt(0)));
3816 frame_->EmitPush(r0); 3816 frame_->EmitPush(r0);
3817 } 3817 }
3818 ASSERT(frame_->height() == original_height + 1); 3818 ASSERT(frame_->height() == original_height + 1);
3819 return; 3819 return;
3820 } 3820 }
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
4261 } 4261 }
4262 4262
4263 default: 4263 default:
4264 UNREACHABLE(); 4264 UNREACHABLE();
4265 } 4265 }
4266 ASSERT((has_cc() && frame_->height() == original_height) || 4266 ASSERT((has_cc() && frame_->height() == original_height) ||
4267 (!has_cc() && frame_->height() == original_height + 1)); 4267 (!has_cc() && frame_->height() == original_height + 1));
4268 } 4268 }
4269 4269
4270 4270
4271 void CodeGenerator::EmitKeyedLoad(bool is_global) {
4272 Comment cmnt(masm_, "[ Load from keyed Property");
4273 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
4274 RelocInfo::Mode rmode = is_global
4275 ? RelocInfo::CODE_TARGET_CONTEXT
4276 : RelocInfo::CODE_TARGET;
4277 frame_->CallCodeObject(ic, rmode, 0);
4278 }
4279
4280
4271 #ifdef DEBUG 4281 #ifdef DEBUG
4272 bool CodeGenerator::HasValidEntryRegisters() { return true; } 4282 bool CodeGenerator::HasValidEntryRegisters() { return true; }
4273 #endif 4283 #endif
4274 4284
4275 4285
4276 #undef __ 4286 #undef __
4277 #define __ ACCESS_MASM(masm) 4287 #define __ ACCESS_MASM(masm)
4278 4288
4279 4289
4280 Handle<String> Reference::GetName() { 4290 Handle<String> Reference::GetName() {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
4327 ? RelocInfo::CODE_TARGET 4337 ? RelocInfo::CODE_TARGET
4328 : RelocInfo::CODE_TARGET_CONTEXT; 4338 : RelocInfo::CODE_TARGET_CONTEXT;
4329 frame->CallCodeObject(ic, rmode, &name_reg, 0); 4339 frame->CallCodeObject(ic, rmode, &name_reg, 0);
4330 frame->EmitPush(r0); 4340 frame->EmitPush(r0);
4331 break; 4341 break;
4332 } 4342 }
4333 4343
4334 case KEYED: { 4344 case KEYED: {
4335 // TODO(181): Implement inlined version of array indexing once 4345 // TODO(181): Implement inlined version of array indexing once
4336 // loop nesting is properly tracked on ARM. 4346 // loop nesting is properly tracked on ARM.
4337 VirtualFrame* frame = cgen_->frame();
4338 Comment cmnt(masm, "[ Load from keyed Property");
4339 ASSERT(property != NULL); 4347 ASSERT(property != NULL);
4340 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
4341 Variable* var = expression_->AsVariableProxy()->AsVariable(); 4348 Variable* var = expression_->AsVariableProxy()->AsVariable();
4342 ASSERT(var == NULL || var->is_global()); 4349 ASSERT(var == NULL || var->is_global());
4343 RelocInfo::Mode rmode = (var == NULL) 4350 cgen_->EmitKeyedLoad(var != NULL);
4344 ? RelocInfo::CODE_TARGET 4351 cgen_->frame()->EmitPush(r0);
4345 : RelocInfo::CODE_TARGET_CONTEXT;
4346 frame->CallCodeObject(ic, rmode, 0);
4347 frame->EmitPush(r0);
4348 break; 4352 break;
4349 } 4353 }
4350 4354
4351 default: 4355 default:
4352 UNREACHABLE(); 4356 UNREACHABLE();
4353 } 4357 }
4358
4359 if (!persist_after_get_) {
4360 cgen_->UnloadReference(this);
4361 }
4354 } 4362 }
4355 4363
4356 4364
4357 void Reference::SetValue(InitState init_state) { 4365 void Reference::SetValue(InitState init_state) {
4358 ASSERT(!is_illegal()); 4366 ASSERT(!is_illegal());
4359 ASSERT(!cgen_->has_cc()); 4367 ASSERT(!cgen_->has_cc());
4360 MacroAssembler* masm = cgen_->masm(); 4368 MacroAssembler* masm = cgen_->masm();
4361 VirtualFrame* frame = cgen_->frame(); 4369 VirtualFrame* frame = cgen_->frame();
4362 Property* property = expression_->AsProperty(); 4370 Property* property = expression_->AsProperty();
4363 if (property != NULL) { 4371 if (property != NULL) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4405 Result value(r0); 4413 Result value(r0);
4406 frame->EmitPop(r0); // value 4414 frame->EmitPop(r0); // value
4407 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, &value, 0); 4415 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, &value, 0);
4408 frame->EmitPush(r0); 4416 frame->EmitPush(r0);
4409 break; 4417 break;
4410 } 4418 }
4411 4419
4412 default: 4420 default:
4413 UNREACHABLE(); 4421 UNREACHABLE();
4414 } 4422 }
4423 cgen_->UnloadReference(this);
4415 } 4424 }
4416 4425
4417 4426
4418 void FastNewClosureStub::Generate(MacroAssembler* masm) { 4427 void FastNewClosureStub::Generate(MacroAssembler* masm) {
4419 // Clone the boilerplate in new space. Set the context to the 4428 // Clone the boilerplate in new space. Set the context to the
4420 // current context in cp. 4429 // current context in cp.
4421 Label gc; 4430 Label gc;
4422 4431
4423 // Pop the boilerplate function from the stack. 4432 // Pop the boilerplate function from the stack.
4424 __ pop(r3); 4433 __ pop(r3);
(...skipping 2461 matching lines...) Expand 10 before | Expand all | Expand 10 after
6886 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 6895 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
6887 // tagged as a small integer. 6896 // tagged as a small integer.
6888 __ bind(&runtime); 6897 __ bind(&runtime);
6889 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); 6898 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1);
6890 } 6899 }
6891 6900
6892 6901
6893 #undef __ 6902 #undef __
6894 6903
6895 } } // namespace v8::internal 6904 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/ia32/codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698