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

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 11818021: Allocation Info Tracking, continued. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 7 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 19 matching lines...) Expand all
30 #if defined(V8_TARGET_ARCH_IA32) 30 #if defined(V8_TARGET_ARCH_IA32)
31 31
32 #include "bootstrapper.h" 32 #include "bootstrapper.h"
33 #include "code-stubs.h" 33 #include "code-stubs.h"
34 #include "isolate.h" 34 #include "isolate.h"
35 #include "jsregexp.h" 35 #include "jsregexp.h"
36 #include "regexp-macro-assembler.h" 36 #include "regexp-macro-assembler.h"
37 #include "runtime.h" 37 #include "runtime.h"
38 #include "stub-cache.h" 38 #include "stub-cache.h"
39 #include "codegen.h" 39 #include "codegen.h"
40 #include "runtime.h"
40 41
41 namespace v8 { 42 namespace v8 {
42 namespace internal { 43 namespace internal {
43 44
44 45
45 void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( 46 void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
46 Isolate* isolate, 47 Isolate* isolate,
47 CodeStubInterfaceDescriptor* descriptor) { 48 CodeStubInterfaceDescriptor* descriptor) {
48 static Register registers[] = { edx, ecx }; 49 static Register registers[] = { edx, ecx };
49 descriptor->register_param_count_ = 2; 50 descriptor->register_param_count_ = 2;
51 descriptor->stack_parameter_count_ = NULL;
Toon Verwaest 2013/02/13 15:14:51 Unnecessary move.
50 descriptor->register_params_ = registers; 52 descriptor->register_params_ = registers;
51 descriptor->stack_parameter_count_ = NULL;
52 descriptor->deoptimization_handler_ = 53 descriptor->deoptimization_handler_ =
53 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); 54 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure);
54 } 55 }
55 56
56 57
57 void TransitionElementsKindStub::InitializeInterfaceDescriptor( 58 void TransitionElementsKindStub::InitializeInterfaceDescriptor(
58 Isolate* isolate, 59 Isolate* isolate,
59 CodeStubInterfaceDescriptor* descriptor) { 60 CodeStubInterfaceDescriptor* descriptor) {
60 static Register registers[] = { eax, ebx }; 61 static Register registers[] = { eax, ebx };
Toon Verwaest 2013/02/13 15:14:51 Please write a comment above identifying the purpo
mvstanton 2013/02/19 11:04:08 I addressed this in the new function below, Initia
61 descriptor->register_param_count_ = 2; 62 descriptor->register_param_count_ = 2;
62 descriptor->register_params_ = registers; 63 descriptor->register_params_ = registers;
63 descriptor->deoptimization_handler_ = 64 descriptor->deoptimization_handler_ =
64 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry; 65 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry;
65 } 66 }
66 67
67 68
69 static void InitializeArrayConstructorDescriptor(Isolate* isolate,
70 CodeStubInterfaceDescriptor* descriptor) {
71 static Register registers[] = { edi, ebx };
72 descriptor->register_param_count_ = 2;
73 // stack param count needs (constructor pointer, and single argument)
74 descriptor->stack_parameter_count_ = &eax;
75 descriptor->register_params_ = registers;
76 descriptor->extra_expression_stack_count_ = 1;
77 descriptor->deoptimization_handler_ =
78 FUNCTION_ADDR(ArrayConstructor_StubFailure);
79 }
80
81
82 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
83 Isolate* isolate,
84 CodeStubInterfaceDescriptor* descriptor) {
85 InitializeArrayConstructorDescriptor(isolate, descriptor);
86 }
87
88
89 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
90 Isolate* isolate,
91 CodeStubInterfaceDescriptor* descriptor) {
92 InitializeArrayConstructorDescriptor(isolate, descriptor);
93 }
94
95
96 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
97 Isolate* isolate,
98 CodeStubInterfaceDescriptor* descriptor) {
99 InitializeArrayConstructorDescriptor(isolate, descriptor);
100 }
101
102
68 #define __ ACCESS_MASM(masm) 103 #define __ ACCESS_MASM(masm)
69 104
70 void ToNumberStub::Generate(MacroAssembler* masm) { 105 void ToNumberStub::Generate(MacroAssembler* masm) {
71 // The ToNumber stub takes one argument in eax. 106 // The ToNumber stub takes one argument in eax.
72 Label check_heap_number, call_builtin; 107 Label check_heap_number, call_builtin;
73 __ JumpIfNotSmi(eax, &check_heap_number, Label::kNear); 108 __ JumpIfNotSmi(eax, &check_heap_number, Label::kNear);
74 __ ret(0); 109 __ ret(0);
75 110
76 __ bind(&check_heap_number); 111 __ bind(&check_heap_number);
77 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 112 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
(...skipping 4725 matching lines...) Expand 10 before | Expand all | Expand 10 after
4803 } 4838 }
4804 4839
4805 4840
4806 static void GenerateRecordCallTarget(MacroAssembler* masm) { 4841 static void GenerateRecordCallTarget(MacroAssembler* masm) {
4807 // Cache the called function in a global property cell. Cache states 4842 // Cache the called function in a global property cell. Cache states
4808 // are uninitialized, monomorphic (indicated by a JSFunction), and 4843 // are uninitialized, monomorphic (indicated by a JSFunction), and
4809 // megamorphic. 4844 // megamorphic.
4810 // ebx : cache cell for call target 4845 // ebx : cache cell for call target
4811 // edi : the function to call 4846 // edi : the function to call
4812 Isolate* isolate = masm->isolate(); 4847 Isolate* isolate = masm->isolate();
4813 Label initialize, done; 4848 Label initialize, done, miss, megamorphic, not_array_function;
4814 4849
4815 // Load the cache state into ecx. 4850 // Load the cache state into ecx.
4816 __ mov(ecx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); 4851 __ mov(ecx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset));
4817 4852
4818 // A monomorphic cache hit or an already megamorphic state: invoke the 4853 // A monomorphic cache hit or an already megamorphic state: invoke the
4819 // function without changing the state. 4854 // function without changing the state.
4820 __ cmp(ecx, edi); 4855 __ cmp(ecx, edi);
4821 __ j(equal, &done, Label::kNear); 4856 __ j(equal, &done, Label::kFar);
Toon Verwaest 2013/02/13 15:14:51 I believe Label::kFar is the default, you can omit
mvstanton 2013/02/19 11:04:08 Done.
4822 __ cmp(ecx, Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate))); 4857 __ cmp(ecx, Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate)));
4823 __ j(equal, &done, Label::kNear); 4858 __ j(equal, &done, Label::kFar);
4859
4860 // Special handling of the Array() function, which caches not only the
4861 // monomorphic Array function but the initial ElementsKind with special
4862 // sentinels
4863 Handle<Object> terminal_kind_sentinel =
4864 TypeFeedbackCells::MonomorphicArraySentinel(LAST_FAST_ELEMENTS_KIND);
4865 __ cmp(ecx, Immediate(terminal_kind_sentinel));
4866 __ j(above, &miss, Label::kFar);
Toon Verwaest 2013/02/13 15:14:51 If you move this below the cmp, you can probably m
mvstanton 2013/02/19 11:04:08 I looked more carefully and it didn't seem possibl
4867 // Load the global or builtins object from the current context
4868 __ mov(ecx, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
4869 __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalContextOffset));
4870 // Make sure the function is the Array() function
4871 __ cmp(edi, Operand(ecx,
4872 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
4873 Label megamorphic_pre;
4874 __ j(not_equal, &megamorphic_pre, Label::kFar);
Toon Verwaest 2013/02/13 15:14:51 Jump to megamorphic directly.
mvstanton 2013/02/19 11:04:08 Done.
4875 __ jmp(&done);
4876
4877 __ bind(&megamorphic_pre);
4878 __ jmp(&megamorphic, Label::kFar);
4879
4880 __ bind(&miss);
4824 4881
4825 // A monomorphic miss (i.e, here the cache is not uninitialized) goes 4882 // A monomorphic miss (i.e, here the cache is not uninitialized) goes
4826 // megamorphic. 4883 // megamorphic.
4827 __ cmp(ecx, Immediate(TypeFeedbackCells::UninitializedSentinel(isolate))); 4884 __ cmp(ecx, Immediate(TypeFeedbackCells::UninitializedSentinel(isolate)));
4828 __ j(equal, &initialize, Label::kNear); 4885 __ j(equal, &initialize, Label::kFar);
4829 // MegamorphicSentinel is an immortal immovable object (undefined) so no 4886 // MegamorphicSentinel is an immortal immovable object (undefined) so no
4830 // write-barrier is needed. 4887 // write-barrier is needed.
4888 __ bind(&megamorphic);
4831 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), 4889 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
4832 Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate))); 4890 Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate)));
4833 __ jmp(&done, Label::kNear); 4891 __ jmp(&done, Label::kNear);
4834 4892
4835 // An uninitialized cache is patched with the function. 4893 // An uninitialized cache is patched with the function or sentinel to
4894 // indicate the ElementsKind if function is the Array constructor.
4836 __ bind(&initialize); 4895 __ bind(&initialize);
4896 __ mov(ecx, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
4897 __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalContextOffset));
Toon Verwaest 2013/02/13 15:14:51 Check if this can be folded together with the code
mvstanton 2013/02/19 11:04:08 Not foldable, but I have a new macro method: LoadG
4898 // Make sure the function is the Array() function
4899 __ cmp(edi, Operand(ecx,
4900 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
4901 __ j(not_equal, &not_array_function);
4902
4903 // The target function is the Array constructor, install a sentinel value in
4904 // the constructor's type info cell that will track the initial ElementsKind
4905 // that should be used for the array when its constructed.
4906 Handle<Object> initial_kind_sentinel =
4907 TypeFeedbackCells::MonomorphicArraySentinel(
4908 GetInitialFastElementsKind());
4909 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
4910 Immediate(initial_kind_sentinel));
4911 __ jmp(&done);
4912
4913 __ bind(&not_array_function);
4837 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), edi); 4914 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), edi);
4838 // No need for a write barrier here - cells are rescanned. 4915 // No need for a write barrier here - cells are rescanned.
4839 4916
4840 __ bind(&done); 4917 __ bind(&done);
4841 } 4918 }
4842 4919
4843 4920
4844 void CallFunctionStub::Generate(MacroAssembler* masm) { 4921 void CallFunctionStub::Generate(MacroAssembler* masm) {
4845 // ebx : cache cell for call target 4922 // ebx : cache cell for call target
4846 // edi : the function to call 4923 // edi : the function to call
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
4942 __ JumpIfSmi(edi, &non_function_call); 5019 __ JumpIfSmi(edi, &non_function_call);
4943 // Check that function is a JSFunction. 5020 // Check that function is a JSFunction.
4944 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 5021 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
4945 __ j(not_equal, &slow); 5022 __ j(not_equal, &slow);
4946 5023
4947 if (RecordCallTarget()) { 5024 if (RecordCallTarget()) {
4948 GenerateRecordCallTarget(masm); 5025 GenerateRecordCallTarget(masm);
4949 } 5026 }
4950 5027
4951 // Jump to the function-specific construct stub. 5028 // Jump to the function-specific construct stub.
4952 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 5029 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
4953 __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kConstructStubOffset)); 5030 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset));
4954 __ lea(ebx, FieldOperand(ebx, Code::kHeaderSize)); 5031 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
4955 __ jmp(ebx); 5032 __ jmp(ecx);
4956 5033
4957 // edi: called object 5034 // edi: called object
4958 // eax: number of arguments 5035 // eax: number of arguments
4959 // ecx: object map 5036 // ecx: object map
4960 Label do_call; 5037 Label do_call;
4961 __ bind(&slow); 5038 __ bind(&slow);
4962 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); 5039 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE);
4963 __ j(not_equal, &non_function_call); 5040 __ j(not_equal, &non_function_call);
4964 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); 5041 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
4965 __ jmp(&do_call); 5042 __ jmp(&do_call);
(...skipping 2732 matching lines...) Expand 10 before | Expand all | Expand 10 after
7698 // Restore ecx. 7775 // Restore ecx.
7699 __ pop(ecx); 7776 __ pop(ecx);
7700 __ ret(0); 7777 __ ret(0);
7701 } 7778 }
7702 7779
7703 #undef __ 7780 #undef __
7704 7781
7705 } } // namespace v8::internal 7782 } } // namespace v8::internal
7706 7783
7707 #endif // V8_TARGET_ARCH_IA32 7784 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698