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

Side by Side Diff: src/x64/full-codegen-x64.cc

Issue 7778013: NewGC: Merge bleeding edge up to 9009. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 3 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/x64/frames-x64.h ('k') | src/x64/lithium-codegen-x64.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 kDontSaveFPRegs, 710 kDontSaveFPRegs,
711 EMIT_REMEMBERED_SET, 711 EMIT_REMEMBERED_SET,
712 OMIT_SMI_CHECK); 712 OMIT_SMI_CHECK);
713 } 713 }
714 break; 714 break;
715 715
716 case Slot::LOOKUP: { 716 case Slot::LOOKUP: {
717 __ push(rsi); 717 __ push(rsi);
718 __ Push(variable->name()); 718 __ Push(variable->name());
719 // Declaration nodes are always introduced in one of two modes. 719 // Declaration nodes are always introduced in one of two modes.
720 ASSERT(mode == Variable::VAR || mode == Variable::CONST); 720 ASSERT(mode == Variable::VAR ||
721 PropertyAttributes attr = (mode == Variable::VAR) ? NONE : READ_ONLY; 721 mode == Variable::CONST ||
722 mode == Variable::LET);
723 PropertyAttributes attr = (mode == Variable::CONST) ? READ_ONLY : NONE;
722 __ Push(Smi::FromInt(attr)); 724 __ Push(Smi::FromInt(attr));
723 // Push initial value, if any. 725 // Push initial value, if any.
724 // Note: For variables we must not push an initial value (such as 726 // Note: For variables we must not push an initial value (such as
725 // 'undefined') because we may have a (legal) redeclaration and we 727 // 'undefined') because we may have a (legal) redeclaration and we
726 // must not destroy the current value. 728 // must not destroy the current value.
727 if (mode == Variable::CONST) { 729 if (mode == Variable::CONST) {
728 __ PushRoot(Heap::kTheHoleValueRootIndex); 730 __ PushRoot(Heap::kTheHoleValueRootIndex);
729 } else if (function != NULL) { 731 } else if (function != NULL) {
730 VisitForStackValue(function); 732 VisitForStackValue(function);
731 } else { 733 } else {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 __ j(not_equal, &next_test); 840 __ j(not_equal, &next_test);
839 __ Drop(1); // Switch value is no longer needed. 841 __ Drop(1); // Switch value is no longer needed.
840 __ jmp(clause->body_target()); 842 __ jmp(clause->body_target());
841 } 843 }
842 844
843 // Discard the test value and jump to the default if present, otherwise to 845 // Discard the test value and jump to the default if present, otherwise to
844 // the end of the statement. 846 // the end of the statement.
845 __ bind(&next_test); 847 __ bind(&next_test);
846 __ Drop(1); // Switch value is no longer needed. 848 __ Drop(1); // Switch value is no longer needed.
847 if (default_clause == NULL) { 849 if (default_clause == NULL) {
848 __ jmp(nested_statement.break_target()); 850 __ jmp(nested_statement.break_label());
849 } else { 851 } else {
850 __ jmp(default_clause->body_target()); 852 __ jmp(default_clause->body_target());
851 } 853 }
852 854
853 // Compile all the case bodies. 855 // Compile all the case bodies.
854 for (int i = 0; i < clauses->length(); i++) { 856 for (int i = 0; i < clauses->length(); i++) {
855 Comment cmnt(masm_, "[ Case body"); 857 Comment cmnt(masm_, "[ Case body");
856 CaseClause* clause = clauses->at(i); 858 CaseClause* clause = clauses->at(i);
857 __ bind(clause->body_target()); 859 __ bind(clause->body_target());
858 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); 860 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS);
859 VisitStatements(clause->statements()); 861 VisitStatements(clause->statements());
860 } 862 }
861 863
862 __ bind(nested_statement.break_target()); 864 __ bind(nested_statement.break_label());
863 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 865 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
864 } 866 }
865 867
866 868
867 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 869 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
868 Comment cmnt(masm_, "[ ForInStatement"); 870 Comment cmnt(masm_, "[ ForInStatement");
869 SetStatementPosition(stmt); 871 SetStatementPosition(stmt);
870 872
871 Label loop, exit; 873 Label loop, exit;
872 ForIn loop_statement(this, stmt); 874 ForIn loop_statement(this, stmt);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 __ Push(Smi::FromInt(0)); // Map (0) - force slow check. 980 __ Push(Smi::FromInt(0)); // Map (0) - force slow check.
979 __ push(rax); 981 __ push(rax);
980 __ movq(rax, FieldOperand(rax, FixedArray::kLengthOffset)); 982 __ movq(rax, FieldOperand(rax, FixedArray::kLengthOffset));
981 __ push(rax); // Fixed array length (as smi). 983 __ push(rax); // Fixed array length (as smi).
982 __ Push(Smi::FromInt(0)); // Initial index. 984 __ Push(Smi::FromInt(0)); // Initial index.
983 985
984 // Generate code for doing the condition check. 986 // Generate code for doing the condition check.
985 __ bind(&loop); 987 __ bind(&loop);
986 __ movq(rax, Operand(rsp, 0 * kPointerSize)); // Get the current index. 988 __ movq(rax, Operand(rsp, 0 * kPointerSize)); // Get the current index.
987 __ cmpq(rax, Operand(rsp, 1 * kPointerSize)); // Compare to the array length. 989 __ cmpq(rax, Operand(rsp, 1 * kPointerSize)); // Compare to the array length.
988 __ j(above_equal, loop_statement.break_target()); 990 __ j(above_equal, loop_statement.break_label());
989 991
990 // Get the current entry of the array into register rbx. 992 // Get the current entry of the array into register rbx.
991 __ movq(rbx, Operand(rsp, 2 * kPointerSize)); 993 __ movq(rbx, Operand(rsp, 2 * kPointerSize));
992 SmiIndex index = masm()->SmiToIndex(rax, rax, kPointerSizeLog2); 994 SmiIndex index = masm()->SmiToIndex(rax, rax, kPointerSizeLog2);
993 __ movq(rbx, FieldOperand(rbx, 995 __ movq(rbx, FieldOperand(rbx,
994 index.reg, 996 index.reg,
995 index.scale, 997 index.scale,
996 FixedArray::kHeaderSize)); 998 FixedArray::kHeaderSize));
997 999
998 // Get the expected map from the stack or a zero map in the 1000 // Get the expected map from the stack or a zero map in the
999 // permanent slow case into register rdx. 1001 // permanent slow case into register rdx.
1000 __ movq(rdx, Operand(rsp, 3 * kPointerSize)); 1002 __ movq(rdx, Operand(rsp, 3 * kPointerSize));
1001 1003
1002 // Check if the expected map still matches that of the enumerable. 1004 // Check if the expected map still matches that of the enumerable.
1003 // If not, we have to filter the key. 1005 // If not, we have to filter the key.
1004 Label update_each; 1006 Label update_each;
1005 __ movq(rcx, Operand(rsp, 4 * kPointerSize)); 1007 __ movq(rcx, Operand(rsp, 4 * kPointerSize));
1006 __ cmpq(rdx, FieldOperand(rcx, HeapObject::kMapOffset)); 1008 __ cmpq(rdx, FieldOperand(rcx, HeapObject::kMapOffset));
1007 __ j(equal, &update_each, Label::kNear); 1009 __ j(equal, &update_each, Label::kNear);
1008 1010
1009 // Convert the entry to a string or null if it isn't a property 1011 // Convert the entry to a string or null if it isn't a property
1010 // anymore. If the property has been removed while iterating, we 1012 // anymore. If the property has been removed while iterating, we
1011 // just skip it. 1013 // just skip it.
1012 __ push(rcx); // Enumerable. 1014 __ push(rcx); // Enumerable.
1013 __ push(rbx); // Current entry. 1015 __ push(rbx); // Current entry.
1014 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); 1016 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION);
1015 __ Cmp(rax, Smi::FromInt(0)); 1017 __ Cmp(rax, Smi::FromInt(0));
1016 __ j(equal, loop_statement.continue_target()); 1018 __ j(equal, loop_statement.continue_label());
1017 __ movq(rbx, rax); 1019 __ movq(rbx, rax);
1018 1020
1019 // Update the 'each' property or variable from the possibly filtered 1021 // Update the 'each' property or variable from the possibly filtered
1020 // entry in register rbx. 1022 // entry in register rbx.
1021 __ bind(&update_each); 1023 __ bind(&update_each);
1022 __ movq(result_register(), rbx); 1024 __ movq(result_register(), rbx);
1023 // Perform the assignment as if via '='. 1025 // Perform the assignment as if via '='.
1024 { EffectContext context(this); 1026 { EffectContext context(this);
1025 EmitAssignment(stmt->each(), stmt->AssignmentId()); 1027 EmitAssignment(stmt->each(), stmt->AssignmentId());
1026 } 1028 }
1027 1029
1028 // Generate code for the body of the loop. 1030 // Generate code for the body of the loop.
1029 Visit(stmt->body()); 1031 Visit(stmt->body());
1030 1032
1031 // Generate code for going to the next element by incrementing the 1033 // Generate code for going to the next element by incrementing the
1032 // index (smi) stored on top of the stack. 1034 // index (smi) stored on top of the stack.
1033 __ bind(loop_statement.continue_target()); 1035 __ bind(loop_statement.continue_label());
1034 __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1)); 1036 __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1));
1035 1037
1036 EmitStackCheck(stmt); 1038 EmitStackCheck(stmt);
1037 __ jmp(&loop); 1039 __ jmp(&loop);
1038 1040
1039 // Remove the pointers stored on the stack. 1041 // Remove the pointers stored on the stack.
1040 __ bind(loop_statement.break_target()); 1042 __ bind(loop_statement.break_label());
1041 __ addq(rsp, Immediate(5 * kPointerSize)); 1043 __ addq(rsp, Immediate(5 * kPointerSize));
1042 1044
1043 // Exit and decrement the loop depth. 1045 // Exit and decrement the loop depth.
1044 __ bind(&exit); 1046 __ bind(&exit);
1045 decrement_loop_depth(); 1047 decrement_loop_depth();
1046 } 1048 }
1047 1049
1048 1050
1049 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1051 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1050 bool pretenure) { 1052 bool pretenure) {
(...skipping 2932 matching lines...) Expand 10 before | Expand all | Expand 10 after
3983 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx); 3985 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx);
3984 __ j(above_equal, if_false); 3986 __ j(above_equal, if_false);
3985 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 3987 __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
3986 Immediate(1 << Map::kIsUndetectable)); 3988 Immediate(1 << Map::kIsUndetectable));
3987 Split(zero, if_true, if_false, fall_through); 3989 Split(zero, if_true, if_false, fall_through);
3988 } else if (check->Equals(isolate()->heap()->boolean_symbol())) { 3990 } else if (check->Equals(isolate()->heap()->boolean_symbol())) {
3989 __ CompareRoot(rax, Heap::kTrueValueRootIndex); 3991 __ CompareRoot(rax, Heap::kTrueValueRootIndex);
3990 __ j(equal, if_true); 3992 __ j(equal, if_true);
3991 __ CompareRoot(rax, Heap::kFalseValueRootIndex); 3993 __ CompareRoot(rax, Heap::kFalseValueRootIndex);
3992 Split(equal, if_true, if_false, fall_through); 3994 Split(equal, if_true, if_false, fall_through);
3995 } else if (FLAG_harmony_typeof &&
3996 check->Equals(isolate()->heap()->null_symbol())) {
3997 __ CompareRoot(rax, Heap::kNullValueRootIndex);
3998 Split(equal, if_true, if_false, fall_through);
3993 } else if (check->Equals(isolate()->heap()->undefined_symbol())) { 3999 } else if (check->Equals(isolate()->heap()->undefined_symbol())) {
3994 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 4000 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
3995 __ j(equal, if_true); 4001 __ j(equal, if_true);
3996 __ JumpIfSmi(rax, if_false); 4002 __ JumpIfSmi(rax, if_false);
3997 // Check for undetectable objects => true. 4003 // Check for undetectable objects => true.
3998 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); 4004 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
3999 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 4005 __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
4000 Immediate(1 << Map::kIsUndetectable)); 4006 Immediate(1 << Map::kIsUndetectable));
4001 Split(not_zero, if_true, if_false, fall_through); 4007 Split(not_zero, if_true, if_false, fall_through);
4002 } else if (check->Equals(isolate()->heap()->function_symbol())) { 4008 } else if (check->Equals(isolate()->heap()->function_symbol())) {
4003 __ JumpIfSmi(rax, if_false); 4009 __ JumpIfSmi(rax, if_false);
4004 STATIC_ASSERT(LAST_CALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE); 4010 STATIC_ASSERT(LAST_CALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE);
4005 __ CmpObjectType(rax, FIRST_CALLABLE_SPEC_OBJECT_TYPE, rdx); 4011 __ CmpObjectType(rax, FIRST_CALLABLE_SPEC_OBJECT_TYPE, rdx);
4006 Split(above_equal, if_true, if_false, fall_through); 4012 Split(above_equal, if_true, if_false, fall_through);
4007 } else if (check->Equals(isolate()->heap()->object_symbol())) { 4013 } else if (check->Equals(isolate()->heap()->object_symbol())) {
4008 __ JumpIfSmi(rax, if_false); 4014 __ JumpIfSmi(rax, if_false);
4009 __ CompareRoot(rax, Heap::kNullValueRootIndex); 4015 if (!FLAG_harmony_typeof) {
4010 __ j(equal, if_true); 4016 __ CompareRoot(rax, Heap::kNullValueRootIndex);
4017 __ j(equal, if_true);
4018 }
4011 __ CmpObjectType(rax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, rdx); 4019 __ CmpObjectType(rax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, rdx);
4012 __ j(below, if_false); 4020 __ j(below, if_false);
4013 __ CmpInstanceType(rdx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 4021 __ CmpInstanceType(rdx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
4014 __ j(above, if_false); 4022 __ j(above, if_false);
4015 // Check for undetectable objects => false. 4023 // Check for undetectable objects => false.
4016 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 4024 __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
4017 Immediate(1 << Map::kIsUndetectable)); 4025 Immediate(1 << Map::kIsUndetectable));
4018 Split(zero, if_true, if_false, fall_through); 4026 Split(zero, if_true, if_false, fall_through);
4019 } else { 4027 } else {
4020 if (if_false != fall_through) __ jmp(if_false); 4028 if (if_false != fall_through) __ jmp(if_false);
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
4248 __ jmp(rdx); 4256 __ jmp(rdx);
4249 } 4257 }
4250 4258
4251 4259
4252 #undef __ 4260 #undef __
4253 4261
4254 4262
4255 } } // namespace v8::internal 4263 } } // namespace v8::internal
4256 4264
4257 #endif // V8_TARGET_ARCH_X64 4265 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/frames-x64.h ('k') | src/x64/lithium-codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698