OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 | 344 |
345 } else { | 345 } else { |
346 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); | 346 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); |
347 { Comment cmnt(masm_, "[ Declarations"); | 347 { Comment cmnt(masm_, "[ Declarations"); |
348 // For named function expressions, declare the function name as a | 348 // For named function expressions, declare the function name as a |
349 // constant. | 349 // constant. |
350 if (scope()->is_function_scope() && scope()->function() != NULL) { | 350 if (scope()->is_function_scope() && scope()->function() != NULL) { |
351 VariableDeclaration* function = scope()->function(); | 351 VariableDeclaration* function = scope()->function(); |
352 DCHECK(function->proxy()->var()->mode() == CONST || | 352 DCHECK(function->proxy()->var()->mode() == CONST || |
353 function->proxy()->var()->mode() == CONST_LEGACY); | 353 function->proxy()->var()->mode() == CONST_LEGACY); |
354 DCHECK(function->proxy()->var()->location() != Variable::UNALLOCATED); | 354 DCHECK(!function->proxy()->var()->IsUnallocatedOrGlobalSlot()); |
355 VisitVariableDeclaration(function); | 355 VisitVariableDeclaration(function); |
356 } | 356 } |
357 VisitDeclarations(scope()->declarations()); | 357 VisitDeclarations(scope()->declarations()); |
358 } | 358 } |
359 | 359 |
360 { Comment cmnt(masm_, "[ Stack check"); | 360 { Comment cmnt(masm_, "[ Stack check"); |
361 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); | 361 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); |
362 Label ok; | 362 Label ok; |
363 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); | 363 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); |
364 __ j(above_equal, &ok, Label::kNear); | 364 __ j(above_equal, &ok, Label::kNear); |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 void FullCodeGenerator::VisitVariableDeclaration( | 837 void FullCodeGenerator::VisitVariableDeclaration( |
838 VariableDeclaration* declaration) { | 838 VariableDeclaration* declaration) { |
839 // If it was not possible to allocate the variable at compile time, we | 839 // If it was not possible to allocate the variable at compile time, we |
840 // need to "declare" it at runtime to make sure it actually exists in the | 840 // need to "declare" it at runtime to make sure it actually exists in the |
841 // local context. | 841 // local context. |
842 VariableProxy* proxy = declaration->proxy(); | 842 VariableProxy* proxy = declaration->proxy(); |
843 VariableMode mode = declaration->mode(); | 843 VariableMode mode = declaration->mode(); |
844 Variable* variable = proxy->var(); | 844 Variable* variable = proxy->var(); |
845 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY; | 845 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY; |
846 switch (variable->location()) { | 846 switch (variable->location()) { |
847 case Variable::UNALLOCATED: | 847 case VariableLocation::GLOBAL: |
| 848 case VariableLocation::UNALLOCATED: |
848 globals_->Add(variable->name(), zone()); | 849 globals_->Add(variable->name(), zone()); |
849 globals_->Add(variable->binding_needs_init() | 850 globals_->Add(variable->binding_needs_init() |
850 ? isolate()->factory()->the_hole_value() | 851 ? isolate()->factory()->the_hole_value() |
851 : isolate()->factory()->undefined_value(), | 852 : isolate()->factory()->undefined_value(), |
852 zone()); | 853 zone()); |
853 break; | 854 break; |
854 | 855 |
855 case Variable::PARAMETER: | 856 case VariableLocation::PARAMETER: |
856 case Variable::LOCAL: | 857 case VariableLocation::LOCAL: |
857 if (hole_init) { | 858 if (hole_init) { |
858 Comment cmnt(masm_, "[ VariableDeclaration"); | 859 Comment cmnt(masm_, "[ VariableDeclaration"); |
859 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); | 860 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); |
860 __ movp(StackOperand(variable), kScratchRegister); | 861 __ movp(StackOperand(variable), kScratchRegister); |
861 } | 862 } |
862 break; | 863 break; |
863 | 864 |
864 case Variable::CONTEXT: | 865 case VariableLocation::CONTEXT: |
865 if (hole_init) { | 866 if (hole_init) { |
866 Comment cmnt(masm_, "[ VariableDeclaration"); | 867 Comment cmnt(masm_, "[ VariableDeclaration"); |
867 EmitDebugCheckDeclarationContext(variable); | 868 EmitDebugCheckDeclarationContext(variable); |
868 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); | 869 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); |
869 __ movp(ContextOperand(rsi, variable->index()), kScratchRegister); | 870 __ movp(ContextOperand(rsi, variable->index()), kScratchRegister); |
870 // No write barrier since the hole value is in old space. | 871 // No write barrier since the hole value is in old space. |
871 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 872 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
872 } | 873 } |
873 break; | 874 break; |
874 | 875 |
875 case Variable::LOOKUP: { | 876 case VariableLocation::LOOKUP: { |
876 Comment cmnt(masm_, "[ VariableDeclaration"); | 877 Comment cmnt(masm_, "[ VariableDeclaration"); |
877 __ Push(rsi); | 878 __ Push(rsi); |
878 __ Push(variable->name()); | 879 __ Push(variable->name()); |
879 // Declaration nodes are always introduced in one of four modes. | 880 // Declaration nodes are always introduced in one of four modes. |
880 DCHECK(IsDeclaredVariableMode(mode)); | 881 DCHECK(IsDeclaredVariableMode(mode)); |
881 PropertyAttributes attr = | 882 PropertyAttributes attr = |
882 IsImmutableVariableMode(mode) ? READ_ONLY : NONE; | 883 IsImmutableVariableMode(mode) ? READ_ONLY : NONE; |
883 __ Push(Smi::FromInt(attr)); | 884 __ Push(Smi::FromInt(attr)); |
884 // Push initial value, if any. | 885 // Push initial value, if any. |
885 // Note: For variables we must not push an initial value (such as | 886 // Note: For variables we must not push an initial value (such as |
886 // 'undefined') because we may have a (legal) redeclaration and we | 887 // 'undefined') because we may have a (legal) redeclaration and we |
887 // must not destroy the current value. | 888 // must not destroy the current value. |
888 if (hole_init) { | 889 if (hole_init) { |
889 __ PushRoot(Heap::kTheHoleValueRootIndex); | 890 __ PushRoot(Heap::kTheHoleValueRootIndex); |
890 } else { | 891 } else { |
891 __ Push(Smi::FromInt(0)); // Indicates no initial value. | 892 __ Push(Smi::FromInt(0)); // Indicates no initial value. |
892 } | 893 } |
893 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 894 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
894 break; | 895 break; |
895 } | 896 } |
896 } | 897 } |
897 } | 898 } |
898 | 899 |
899 | 900 |
900 void FullCodeGenerator::VisitFunctionDeclaration( | 901 void FullCodeGenerator::VisitFunctionDeclaration( |
901 FunctionDeclaration* declaration) { | 902 FunctionDeclaration* declaration) { |
902 VariableProxy* proxy = declaration->proxy(); | 903 VariableProxy* proxy = declaration->proxy(); |
903 Variable* variable = proxy->var(); | 904 Variable* variable = proxy->var(); |
904 switch (variable->location()) { | 905 switch (variable->location()) { |
905 case Variable::UNALLOCATED: { | 906 case VariableLocation::GLOBAL: |
| 907 case VariableLocation::UNALLOCATED: { |
906 globals_->Add(variable->name(), zone()); | 908 globals_->Add(variable->name(), zone()); |
907 Handle<SharedFunctionInfo> function = | 909 Handle<SharedFunctionInfo> function = |
908 Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); | 910 Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); |
909 // Check for stack-overflow exception. | 911 // Check for stack-overflow exception. |
910 if (function.is_null()) return SetStackOverflow(); | 912 if (function.is_null()) return SetStackOverflow(); |
911 globals_->Add(function, zone()); | 913 globals_->Add(function, zone()); |
912 break; | 914 break; |
913 } | 915 } |
914 | 916 |
915 case Variable::PARAMETER: | 917 case VariableLocation::PARAMETER: |
916 case Variable::LOCAL: { | 918 case VariableLocation::LOCAL: { |
917 Comment cmnt(masm_, "[ FunctionDeclaration"); | 919 Comment cmnt(masm_, "[ FunctionDeclaration"); |
918 VisitForAccumulatorValue(declaration->fun()); | 920 VisitForAccumulatorValue(declaration->fun()); |
919 __ movp(StackOperand(variable), result_register()); | 921 __ movp(StackOperand(variable), result_register()); |
920 break; | 922 break; |
921 } | 923 } |
922 | 924 |
923 case Variable::CONTEXT: { | 925 case VariableLocation::CONTEXT: { |
924 Comment cmnt(masm_, "[ FunctionDeclaration"); | 926 Comment cmnt(masm_, "[ FunctionDeclaration"); |
925 EmitDebugCheckDeclarationContext(variable); | 927 EmitDebugCheckDeclarationContext(variable); |
926 VisitForAccumulatorValue(declaration->fun()); | 928 VisitForAccumulatorValue(declaration->fun()); |
927 __ movp(ContextOperand(rsi, variable->index()), result_register()); | 929 __ movp(ContextOperand(rsi, variable->index()), result_register()); |
928 int offset = Context::SlotOffset(variable->index()); | 930 int offset = Context::SlotOffset(variable->index()); |
929 // We know that we have written a function, which is not a smi. | 931 // We know that we have written a function, which is not a smi. |
930 __ RecordWriteContextSlot(rsi, | 932 __ RecordWriteContextSlot(rsi, |
931 offset, | 933 offset, |
932 result_register(), | 934 result_register(), |
933 rcx, | 935 rcx, |
934 kDontSaveFPRegs, | 936 kDontSaveFPRegs, |
935 EMIT_REMEMBERED_SET, | 937 EMIT_REMEMBERED_SET, |
936 OMIT_SMI_CHECK); | 938 OMIT_SMI_CHECK); |
937 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 939 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
938 break; | 940 break; |
939 } | 941 } |
940 | 942 |
941 case Variable::LOOKUP: { | 943 case VariableLocation::LOOKUP: { |
942 Comment cmnt(masm_, "[ FunctionDeclaration"); | 944 Comment cmnt(masm_, "[ FunctionDeclaration"); |
943 __ Push(rsi); | 945 __ Push(rsi); |
944 __ Push(variable->name()); | 946 __ Push(variable->name()); |
945 __ Push(Smi::FromInt(NONE)); | 947 __ Push(Smi::FromInt(NONE)); |
946 VisitForStackValue(declaration->fun()); | 948 VisitForStackValue(declaration->fun()); |
947 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 949 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
948 break; | 950 break; |
949 } | 951 } |
950 } | 952 } |
951 } | 953 } |
952 | 954 |
953 | 955 |
954 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { | 956 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { |
955 VariableProxy* proxy = declaration->proxy(); | 957 VariableProxy* proxy = declaration->proxy(); |
956 Variable* variable = proxy->var(); | 958 Variable* variable = proxy->var(); |
957 switch (variable->location()) { | 959 switch (variable->location()) { |
958 case Variable::UNALLOCATED: | 960 case VariableLocation::UNALLOCATED: |
| 961 case VariableLocation::GLOBAL: |
959 // TODO(rossberg) | 962 // TODO(rossberg) |
960 break; | 963 break; |
961 | 964 |
962 case Variable::CONTEXT: { | 965 case VariableLocation::CONTEXT: { |
963 Comment cmnt(masm_, "[ ImportDeclaration"); | 966 Comment cmnt(masm_, "[ ImportDeclaration"); |
964 EmitDebugCheckDeclarationContext(variable); | 967 EmitDebugCheckDeclarationContext(variable); |
965 // TODO(rossberg) | 968 // TODO(rossberg) |
966 break; | 969 break; |
967 } | 970 } |
968 | 971 |
969 case Variable::PARAMETER: | 972 case VariableLocation::PARAMETER: |
970 case Variable::LOCAL: | 973 case VariableLocation::LOCAL: |
971 case Variable::LOOKUP: | 974 case VariableLocation::LOOKUP: |
972 UNREACHABLE(); | 975 UNREACHABLE(); |
973 } | 976 } |
974 } | 977 } |
975 | 978 |
976 | 979 |
977 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { | 980 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { |
978 // TODO(rossberg) | 981 // TODO(rossberg) |
979 } | 982 } |
980 | 983 |
981 | 984 |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1456 | 1459 |
1457 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1460 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
1458 // Record position before possible IC call. | 1461 // Record position before possible IC call. |
1459 SetExpressionPosition(proxy); | 1462 SetExpressionPosition(proxy); |
1460 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); | 1463 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); |
1461 Variable* var = proxy->var(); | 1464 Variable* var = proxy->var(); |
1462 | 1465 |
1463 // Three cases: global variables, lookup variables, and all other types of | 1466 // Three cases: global variables, lookup variables, and all other types of |
1464 // variables. | 1467 // variables. |
1465 switch (var->location()) { | 1468 switch (var->location()) { |
1466 case Variable::UNALLOCATED: { | 1469 case VariableLocation::GLOBAL: |
| 1470 case VariableLocation::UNALLOCATED: { |
1467 Comment cmnt(masm_, "[ Global variable"); | 1471 Comment cmnt(masm_, "[ Global variable"); |
1468 __ Move(LoadDescriptor::NameRegister(), var->name()); | 1472 __ Move(LoadDescriptor::NameRegister(), var->name()); |
1469 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 1473 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
1470 __ Move(LoadDescriptor::SlotRegister(), | 1474 __ Move(LoadDescriptor::SlotRegister(), |
1471 SmiFromSlot(proxy->VariableFeedbackSlot())); | 1475 SmiFromSlot(proxy->VariableFeedbackSlot())); |
1472 CallGlobalLoadIC(var->name()); | 1476 CallGlobalLoadIC(var->name()); |
1473 context()->Plug(rax); | 1477 context()->Plug(rax); |
1474 break; | 1478 break; |
1475 } | 1479 } |
1476 | 1480 |
1477 case Variable::PARAMETER: | 1481 case VariableLocation::PARAMETER: |
1478 case Variable::LOCAL: | 1482 case VariableLocation::LOCAL: |
1479 case Variable::CONTEXT: { | 1483 case VariableLocation::CONTEXT: { |
1480 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot" | 1484 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot" |
1481 : "[ Stack slot"); | 1485 : "[ Stack slot"); |
1482 if (var->binding_needs_init()) { | 1486 if (var->binding_needs_init()) { |
1483 // var->scope() may be NULL when the proxy is located in eval code and | 1487 // var->scope() may be NULL when the proxy is located in eval code and |
1484 // refers to a potential outside binding. Currently those bindings are | 1488 // refers to a potential outside binding. Currently those bindings are |
1485 // always looked up dynamically, i.e. in that case | 1489 // always looked up dynamically, i.e. in that case |
1486 // var->location() == LOOKUP. | 1490 // var->location() == LOOKUP. |
1487 // always holds. | 1491 // always holds. |
1488 DCHECK(var->scope() != NULL); | 1492 DCHECK(var->scope() != NULL); |
1489 | 1493 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1537 } | 1541 } |
1538 __ bind(&done); | 1542 __ bind(&done); |
1539 context()->Plug(rax); | 1543 context()->Plug(rax); |
1540 break; | 1544 break; |
1541 } | 1545 } |
1542 } | 1546 } |
1543 context()->Plug(var); | 1547 context()->Plug(var); |
1544 break; | 1548 break; |
1545 } | 1549 } |
1546 | 1550 |
1547 case Variable::LOOKUP: { | 1551 case VariableLocation::LOOKUP: { |
1548 Comment cmnt(masm_, "[ Lookup slot"); | 1552 Comment cmnt(masm_, "[ Lookup slot"); |
1549 Label done, slow; | 1553 Label done, slow; |
1550 // Generate code for loading from variables potentially shadowed | 1554 // Generate code for loading from variables potentially shadowed |
1551 // by eval-introduced variables. | 1555 // by eval-introduced variables. |
1552 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); | 1556 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); |
1553 __ bind(&slow); | 1557 __ bind(&slow); |
1554 __ Push(rsi); // Context. | 1558 __ Push(rsi); // Context. |
1555 __ Push(var->name()); | 1559 __ Push(var->name()); |
1556 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 1560 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
1557 __ bind(&done); | 1561 __ bind(&done); |
(...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2639 if (var->IsContextSlot()) { | 2643 if (var->IsContextSlot()) { |
2640 __ movp(rdx, rax); | 2644 __ movp(rdx, rax); |
2641 __ RecordWriteContextSlot( | 2645 __ RecordWriteContextSlot( |
2642 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); | 2646 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); |
2643 } | 2647 } |
2644 } | 2648 } |
2645 | 2649 |
2646 | 2650 |
2647 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 2651 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
2648 FeedbackVectorICSlot slot) { | 2652 FeedbackVectorICSlot slot) { |
2649 if (var->IsUnallocated()) { | 2653 if (var->IsUnallocatedOrGlobalSlot()) { |
2650 // Global var, const, or let. | 2654 // Global var, const, or let. |
2651 __ Move(StoreDescriptor::NameRegister(), var->name()); | 2655 __ Move(StoreDescriptor::NameRegister(), var->name()); |
2652 __ movp(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2656 __ movp(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
2653 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 2657 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
2654 CallStoreIC(); | 2658 CallStoreIC(); |
2655 | 2659 |
2656 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2660 } else if (var->mode() == LET && op != Token::INIT_LET) { |
2657 // Non-initializing assignment to let variable needs a write barrier. | 2661 // Non-initializing assignment to let variable needs a write barrier. |
2658 DCHECK(!var->IsLookupSlot()); | 2662 DCHECK(!var->IsLookupSlot()); |
2659 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2663 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
(...skipping 2086 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4746 VisitForStackValue(property->key()); | 4750 VisitForStackValue(property->key()); |
4747 __ Push(Smi::FromInt(language_mode())); | 4751 __ Push(Smi::FromInt(language_mode())); |
4748 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4752 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
4749 context()->Plug(rax); | 4753 context()->Plug(rax); |
4750 } else if (proxy != NULL) { | 4754 } else if (proxy != NULL) { |
4751 Variable* var = proxy->var(); | 4755 Variable* var = proxy->var(); |
4752 // Delete of an unqualified identifier is disallowed in strict mode but | 4756 // Delete of an unqualified identifier is disallowed in strict mode but |
4753 // "delete this" is allowed. | 4757 // "delete this" is allowed. |
4754 bool is_this = var->HasThisName(isolate()); | 4758 bool is_this = var->HasThisName(isolate()); |
4755 DCHECK(is_sloppy(language_mode()) || is_this); | 4759 DCHECK(is_sloppy(language_mode()) || is_this); |
4756 if (var->IsUnallocated()) { | 4760 if (var->IsUnallocatedOrGlobalSlot()) { |
4757 __ Push(GlobalObjectOperand()); | 4761 __ Push(GlobalObjectOperand()); |
4758 __ Push(var->name()); | 4762 __ Push(var->name()); |
4759 __ Push(Smi::FromInt(SLOPPY)); | 4763 __ Push(Smi::FromInt(SLOPPY)); |
4760 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4764 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
4761 context()->Plug(rax); | 4765 context()->Plug(rax); |
4762 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4766 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
4763 // Result of deleting non-global variables is false. 'this' is | 4767 // Result of deleting non-global variables is false. 'this' is |
4764 // not really a variable, though we implement it as one. The | 4768 // not really a variable, though we implement it as one. The |
4765 // subexpression does not have side effects. | 4769 // subexpression does not have side effects. |
4766 context()->Plug(is_this); | 4770 context()->Plug(is_this); |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5106 } | 5110 } |
5107 } | 5111 } |
5108 } | 5112 } |
5109 | 5113 |
5110 | 5114 |
5111 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 5115 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
5112 VariableProxy* proxy = expr->AsVariableProxy(); | 5116 VariableProxy* proxy = expr->AsVariableProxy(); |
5113 DCHECK(!context()->IsEffect()); | 5117 DCHECK(!context()->IsEffect()); |
5114 DCHECK(!context()->IsTest()); | 5118 DCHECK(!context()->IsTest()); |
5115 | 5119 |
5116 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 5120 if (proxy != NULL && proxy->var()->IsUnallocatedOrGlobalSlot()) { |
5117 Comment cmnt(masm_, "[ Global variable"); | 5121 Comment cmnt(masm_, "[ Global variable"); |
5118 __ Move(LoadDescriptor::NameRegister(), proxy->name()); | 5122 __ Move(LoadDescriptor::NameRegister(), proxy->name()); |
5119 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 5123 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
5120 __ Move(LoadDescriptor::SlotRegister(), | 5124 __ Move(LoadDescriptor::SlotRegister(), |
5121 SmiFromSlot(proxy->VariableFeedbackSlot())); | 5125 SmiFromSlot(proxy->VariableFeedbackSlot())); |
5122 // Use a regular load, not a contextual load, to avoid a reference | 5126 // Use a regular load, not a contextual load, to avoid a reference |
5123 // error. | 5127 // error. |
5124 CallLoadIC(NOT_CONTEXTUAL); | 5128 CallLoadIC(NOT_CONTEXTUAL); |
5125 PrepareForBailout(expr, TOS_REG); | 5129 PrepareForBailout(expr, TOS_REG); |
5126 context()->Plug(rax); | 5130 context()->Plug(rax); |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5509 Assembler::target_address_at(call_target_address, | 5513 Assembler::target_address_at(call_target_address, |
5510 unoptimized_code)); | 5514 unoptimized_code)); |
5511 return OSR_AFTER_STACK_CHECK; | 5515 return OSR_AFTER_STACK_CHECK; |
5512 } | 5516 } |
5513 | 5517 |
5514 | 5518 |
5515 } // namespace internal | 5519 } // namespace internal |
5516 } // namespace v8 | 5520 } // namespace v8 |
5517 | 5521 |
5518 #endif // V8_TARGET_ARCH_X64 | 5522 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |