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

Side by Side Diff: runtime/vm/stub_code_ia32.cc

Issue 11956004: Fix vm code base so that it can be built for --arch=simarm (no snapshot yet). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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 | « runtime/vm/stub_code_arm.cc ('k') | runtime/vm/stub_code_x64.cc » ('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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/assembler_macros.h" 9 #include "vm/assembler_macros.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. 74 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments.
75 __ call(ECX); 75 __ call(ECX);
76 76
77 // Reset exit frame information in Isolate structure. 77 // Reset exit frame information in Isolate structure.
78 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); 78 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
79 79
80 // Load Context pointer from Isolate structure into ECX. 80 // Load Context pointer from Isolate structure into ECX.
81 __ movl(ECX, Address(CTX, Isolate::top_context_offset())); 81 __ movl(ECX, Address(CTX, Isolate::top_context_offset()));
82 82
83 // Reset Context pointer in Isolate structure. 83 // Reset Context pointer in Isolate structure.
84 const Immediate raw_null = 84 const Immediate& raw_null =
85 Immediate(reinterpret_cast<intptr_t>(Object::null())); 85 Immediate(reinterpret_cast<intptr_t>(Object::null()));
86 __ movl(Address(CTX, Isolate::top_context_offset()), raw_null); 86 __ movl(Address(CTX, Isolate::top_context_offset()), raw_null);
87 87
88 // Cache Context pointer into CTX while executing Dart code. 88 // Cache Context pointer into CTX while executing Dart code.
89 __ movl(CTX, ECX); 89 __ movl(CTX, ECX);
90 90
91 __ LeaveFrame(); 91 __ LeaveFrame();
92 __ ret(); 92 __ ret();
93 } 93 }
94 94
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. 164 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments.
165 __ call(ECX); 165 __ call(ECX);
166 166
167 // Reset exit frame information in Isolate structure. 167 // Reset exit frame information in Isolate structure.
168 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); 168 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
169 169
170 // Load Context pointer from Isolate structure into EDI. 170 // Load Context pointer from Isolate structure into EDI.
171 __ movl(EDI, Address(CTX, Isolate::top_context_offset())); 171 __ movl(EDI, Address(CTX, Isolate::top_context_offset()));
172 172
173 // Reset Context pointer in Isolate structure. 173 // Reset Context pointer in Isolate structure.
174 const Immediate raw_null = 174 const Immediate& raw_null =
175 Immediate(reinterpret_cast<intptr_t>(Object::null())); 175 Immediate(reinterpret_cast<intptr_t>(Object::null()));
176 __ movl(Address(CTX, Isolate::top_context_offset()), raw_null); 176 __ movl(Address(CTX, Isolate::top_context_offset()), raw_null);
177 177
178 // Cache Context pointer into CTX while executing Dart code. 178 // Cache Context pointer into CTX while executing Dart code.
179 __ movl(CTX, EDI); 179 __ movl(CTX, EDI);
180 180
181 __ LeaveFrame(); 181 __ LeaveFrame();
182 __ ret(); 182 __ ret();
183 } 183 }
184 184
185 185
186 // Input parameters: 186 // Input parameters:
187 // EDX: arguments descriptor array. 187 // EDX: arguments descriptor array.
188 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { 188 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
189 const Immediate raw_null = 189 const Immediate& raw_null =
190 Immediate(reinterpret_cast<intptr_t>(Object::null())); 190 Immediate(reinterpret_cast<intptr_t>(Object::null()));
191 AssemblerMacros::EnterStubFrame(assembler); 191 AssemblerMacros::EnterStubFrame(assembler);
192 __ pushl(EDX); // Preserve arguments descriptor array. 192 __ pushl(EDX); // Preserve arguments descriptor array.
193 __ pushl(raw_null); // Setup space on stack for return value. 193 __ pushl(raw_null); // Setup space on stack for return value.
194 __ CallRuntime(kPatchStaticCallRuntimeEntry); 194 __ CallRuntime(kPatchStaticCallRuntimeEntry);
195 __ popl(EAX); // Get Code object result. 195 __ popl(EAX); // Get Code object result.
196 __ popl(EDX); // Restore arguments descriptor array. 196 __ popl(EDX); // Restore arguments descriptor array.
197 // Remove the stub frame as we are about to jump to the dart function. 197 // Remove the stub frame as we are about to jump to the dart function.
198 __ LeaveFrame(); 198 __ LeaveFrame();
199 199
200 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); 200 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset()));
201 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 201 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
202 __ jmp(ECX); 202 __ jmp(ECX);
203 } 203 }
204 204
205 205
206 // Called from a static call only when an invalid code has been entered 206 // Called from a static call only when an invalid code has been entered
207 // (invalid because its function was optimized or deoptimized). 207 // (invalid because its function was optimized or deoptimized).
208 // EDX: arguments descriptor array. 208 // EDX: arguments descriptor array.
209 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { 209 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
210 const Immediate raw_null = 210 const Immediate& raw_null =
211 Immediate(reinterpret_cast<intptr_t>(Object::null())); 211 Immediate(reinterpret_cast<intptr_t>(Object::null()));
212 // Create a stub frame as we are pushing some objects on the stack before 212 // Create a stub frame as we are pushing some objects on the stack before
213 // calling into the runtime. 213 // calling into the runtime.
214 AssemblerMacros::EnterStubFrame(assembler); 214 AssemblerMacros::EnterStubFrame(assembler);
215 __ pushl(EDX); // Preserve arguments descriptor array. 215 __ pushl(EDX); // Preserve arguments descriptor array.
216 __ pushl(raw_null); // Setup space on stack for return value. 216 __ pushl(raw_null); // Setup space on stack for return value.
217 __ CallRuntime(kFixCallersTargetRuntimeEntry); 217 __ CallRuntime(kFixCallersTargetRuntimeEntry);
218 __ popl(EAX); // Get Code object. 218 __ popl(EAX); // Get Code object.
219 __ popl(EDX); // Restore arguments descriptor array. 219 __ popl(EDX); // Restore arguments descriptor array.
220 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); 220 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset()));
221 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 221 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
222 __ LeaveFrame(); 222 __ LeaveFrame();
223 __ jmp(EAX); 223 __ jmp(EAX);
224 __ int3(); 224 __ int3();
225 } 225 }
226 226
227 227
228 // Input parameters: 228 // Input parameters:
229 // EDX: smi-tagged argument count, may be zero. 229 // EDX: smi-tagged argument count, may be zero.
230 // Uses EAX, EBX, ECX, EDX. 230 // Uses EAX, EBX, ECX, EDX.
231 static void PushArgumentsArray(Assembler* assembler, intptr_t arg_offset) { 231 static void PushArgumentsArray(Assembler* assembler, intptr_t arg_offset) {
232 const Immediate raw_null = 232 const Immediate& raw_null =
233 Immediate(reinterpret_cast<intptr_t>(Object::null())); 233 Immediate(reinterpret_cast<intptr_t>(Object::null()));
234 234
235 // Allocate array to store arguments of caller. 235 // Allocate array to store arguments of caller.
236 __ movl(ECX, raw_null); // Null element type for raw Array. 236 __ movl(ECX, raw_null); // Null element type for raw Array.
237 __ call(&StubCode::AllocateArrayLabel()); 237 __ call(&StubCode::AllocateArrayLabel());
238 __ SmiUntag(EDX); 238 __ SmiUntag(EDX);
239 // EAX: newly allocated array. 239 // EAX: newly allocated array.
240 // EDX: length of the array (was preserved by the stub). 240 // EDX: length of the array (was preserved by the stub).
241 __ pushl(EAX); // Array is in EAX and on top of stack. 241 __ pushl(EAX); // Array is in EAX and on top of stack.
242 __ leal(EBX, Address(ESP, EDX, TIMES_4, arg_offset)); // Addr of first arg. 242 __ leal(EBX, Address(ESP, EDX, TIMES_4, arg_offset)); // Addr of first arg.
(...skipping 14 matching lines...) Expand all
257 // Input parameters: 257 // Input parameters:
258 // ECX: ic-data. 258 // ECX: ic-data.
259 // EDX: arguments descriptor array. 259 // EDX: arguments descriptor array.
260 // Note: The receiver object is the first argument to the function being 260 // Note: The receiver object is the first argument to the function being
261 // called, the stub accesses the receiver from this location directly 261 // called, the stub accesses the receiver from this location directly
262 // when trying to resolve the call. 262 // when trying to resolve the call.
263 // Uses EDI. 263 // Uses EDI.
264 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { 264 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) {
265 AssemblerMacros::EnterStubFrame(assembler); 265 AssemblerMacros::EnterStubFrame(assembler);
266 266
267 const Immediate raw_null = 267 const Immediate& raw_null =
268 Immediate(reinterpret_cast<intptr_t>(Object::null())); 268 Immediate(reinterpret_cast<intptr_t>(Object::null()));
269 __ pushl(raw_null); // Space for the return value. 269 __ pushl(raw_null); // Space for the return value.
270 270
271 // Push the receiver as an argument. Load the smi-tagged argument 271 // Push the receiver as an argument. Load the smi-tagged argument
272 // count into EDI to index the receiver in the stack. There are 272 // count into EDI to index the receiver in the stack. There are
273 // three words (null, stub's pc marker, saved fp) above the return 273 // three words (null, stub's pc marker, saved fp) above the return
274 // address. 274 // address.
275 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 275 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
276 __ pushl(Address(ESP, EDI, TIMES_2, (3 * kWordSize))); 276 __ pushl(Address(ESP, EDI, TIMES_2, (3 * kWordSize)));
277 277
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 // Load the receiver into EAX. The argument count in the arguments 427 // Load the receiver into EAX. The argument count in the arguments
428 // descriptor in EDX is a smi. 428 // descriptor in EDX is a smi.
429 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 429 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
430 // Two words (saved fp, stub's pc marker) in the stack above the return 430 // Two words (saved fp, stub's pc marker) in the stack above the return
431 // address. 431 // address.
432 __ movl(EAX, Address(ESP, EAX, TIMES_2, 2 * kWordSize)); 432 __ movl(EAX, Address(ESP, EAX, TIMES_2, 2 * kWordSize));
433 // Preserve IC data and arguments descriptor. 433 // Preserve IC data and arguments descriptor.
434 __ pushl(ECX); 434 __ pushl(ECX);
435 __ pushl(EDX); 435 __ pushl(EDX);
436 436
437 const Immediate raw_null = 437 const Immediate& raw_null =
438 Immediate(reinterpret_cast<intptr_t>(Instructions::null())); 438 Immediate(reinterpret_cast<intptr_t>(Instructions::null()));
439 __ pushl(raw_null); // Space for the result of the runtime call. 439 __ pushl(raw_null); // Space for the result of the runtime call.
440 __ pushl(EAX); // Pass receiver. 440 __ pushl(EAX); // Pass receiver.
441 __ pushl(ECX); // Pass IC data. 441 __ pushl(ECX); // Pass IC data.
442 __ pushl(EDX); // Pass rguments descriptor. 442 __ pushl(EDX); // Pass rguments descriptor.
443 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry); 443 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry);
444 // Discard arguments. 444 // Discard arguments.
445 __ popl(EAX); 445 __ popl(EAX);
446 __ popl(EAX); 446 __ popl(EAX);
447 __ popl(EAX); 447 __ popl(EAX);
(...skipping 15 matching lines...) Expand all
463 463
464 // Called for inline allocation of arrays. 464 // Called for inline allocation of arrays.
465 // Input parameters: 465 // Input parameters:
466 // EDX : Array length as Smi. 466 // EDX : Array length as Smi.
467 // ECX : array element type (either NULL or an instantiated type). 467 // ECX : array element type (either NULL or an instantiated type).
468 // Uses EAX, EBX, ECX, EDI as temporary registers. 468 // Uses EAX, EBX, ECX, EDI as temporary registers.
469 // NOTE: EDX cannot be clobbered here as the caller relies on it being saved. 469 // NOTE: EDX cannot be clobbered here as the caller relies on it being saved.
470 // The newly allocated object is returned in EAX. 470 // The newly allocated object is returned in EAX.
471 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { 471 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
472 Label slow_case; 472 Label slow_case;
473 const Immediate raw_null = 473 const Immediate& raw_null =
474 Immediate(reinterpret_cast<intptr_t>(Object::null())); 474 Immediate(reinterpret_cast<intptr_t>(Object::null()));
475 475
476 if (FLAG_inline_alloc) { 476 if (FLAG_inline_alloc) {
477 // Compute the size to be allocated, it is based on the array length 477 // Compute the size to be allocated, it is based on the array length
478 // and is computed as: 478 // and is computed as:
479 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). 479 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
480 // Assert that length is a Smi. 480 // Assert that length is a Smi.
481 __ testl(EDX, Immediate(kSmiTagSize)); 481 __ testl(EDX, Immediate(kSmiTagSize));
482 if (FLAG_use_slow_path) { 482 if (FLAG_use_slow_path) {
483 __ jmp(&slow_case); 483 __ jmp(&slow_case);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 } 600 }
601 601
602 602
603 // Input parameters: 603 // Input parameters:
604 // EDX: Arguments descriptor array. 604 // EDX: Arguments descriptor array.
605 // Note: The closure object is the first argument to the function being 605 // Note: The closure object is the first argument to the function being
606 // called, the stub accesses the closure from this location directly 606 // called, the stub accesses the closure from this location directly
607 // when trying to resolve the call. 607 // when trying to resolve the call.
608 // Uses EDI. 608 // Uses EDI.
609 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { 609 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) {
610 const Immediate raw_null = 610 const Immediate& raw_null =
611 Immediate(reinterpret_cast<intptr_t>(Object::null())); 611 Immediate(reinterpret_cast<intptr_t>(Object::null()));
612 612
613 // Load num_args. 613 // Load num_args.
614 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 614 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
615 // Load closure object in EDI. 615 // Load closure object in EDI.
616 __ movl(EDI, Address(ESP, EAX, TIMES_2, 0)); // EAX is a Smi. 616 __ movl(EDI, Address(ESP, EAX, TIMES_2, 0)); // EAX is a Smi.
617 617
618 // Verify that EDI is a closure by checking its class. 618 // Verify that EDI is a closure by checking its class.
619 Label not_closure; 619 Label not_closure;
620 __ cmpl(EDI, raw_null); 620 __ cmpl(EDI, raw_null);
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 } 828 }
829 829
830 830
831 // Called for inline allocation of contexts. 831 // Called for inline allocation of contexts.
832 // Input: 832 // Input:
833 // EDX: number of context variables. 833 // EDX: number of context variables.
834 // Output: 834 // Output:
835 // EAX: new allocated RawContext object. 835 // EAX: new allocated RawContext object.
836 // EBX and EDX are destroyed. 836 // EBX and EDX are destroyed.
837 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { 837 void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
838 const Immediate raw_null = 838 const Immediate& raw_null =
839 Immediate(reinterpret_cast<intptr_t>(Object::null())); 839 Immediate(reinterpret_cast<intptr_t>(Object::null()));
840 if (FLAG_inline_alloc) { 840 if (FLAG_inline_alloc) {
841 const Class& context_class = Class::ZoneHandle(Object::context_class()); 841 const Class& context_class = Class::ZoneHandle(Object::context_class());
842 Label slow_case; 842 Label slow_case;
843 Heap* heap = Isolate::Current()->heap(); 843 Heap* heap = Isolate::Current()->heap();
844 // First compute the rounded instance size. 844 // First compute the rounded instance size.
845 // EDX: number of context variables. 845 // EDX: number of context variables.
846 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); 846 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1);
847 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); 847 __ leal(EBX, Address(EDX, TIMES_4, fixed_size));
848 __ andl(EBX, Immediate(-kObjectAlignment)); 848 __ andl(EBX, Immediate(-kObjectAlignment));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); 901 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX);
902 902
903 // Setup isolate field. 903 // Setup isolate field.
904 // Load Isolate pointer from Context structure into EBX. 904 // Load Isolate pointer from Context structure into EBX.
905 // EAX: new object. 905 // EAX: new object.
906 // EDX: number of context variables. 906 // EDX: number of context variables.
907 __ movl(EBX, FieldAddress(CTX, Context::isolate_offset())); 907 __ movl(EBX, FieldAddress(CTX, Context::isolate_offset()));
908 // EBX: Isolate, not an object. 908 // EBX: Isolate, not an object.
909 __ movl(FieldAddress(EAX, Context::isolate_offset()), EBX); 909 __ movl(FieldAddress(EAX, Context::isolate_offset()), EBX);
910 910
911 const Immediate raw_null = 911 const Immediate& raw_null =
912 Immediate(reinterpret_cast<intptr_t>(Object::null())); 912 Immediate(reinterpret_cast<intptr_t>(Object::null()));
913 // Setup the parent field. 913 // Setup the parent field.
914 // EAX: new object. 914 // EAX: new object.
915 // EDX: number of context variables. 915 // EDX: number of context variables.
916 __ movl(FieldAddress(EAX, Context::parent_offset()), raw_null); 916 __ movl(FieldAddress(EAX, Context::parent_offset()), raw_null);
917 917
918 // Initialize the context variables. 918 // Initialize the context variables.
919 // EAX: new object. 919 // EAX: new object.
920 // EDX: number of context variables. 920 // EDX: number of context variables.
921 { 921 {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 // Called for inline allocation of objects. 1012 // Called for inline allocation of objects.
1013 // Input parameters: 1013 // Input parameters:
1014 // ESP + 8 : type arguments object (only if class is parameterized). 1014 // ESP + 8 : type arguments object (only if class is parameterized).
1015 // ESP + 4 : type arguments of instantiator (only if class is parameterized). 1015 // ESP + 4 : type arguments of instantiator (only if class is parameterized).
1016 // ESP : points to return address. 1016 // ESP : points to return address.
1017 // Uses EAX, EBX, ECX, EDX, EDI as temporary registers. 1017 // Uses EAX, EBX, ECX, EDX, EDI as temporary registers.
1018 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, 1018 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
1019 const Class& cls) { 1019 const Class& cls) {
1020 const intptr_t kObjectTypeArgumentsOffset = 2 * kWordSize; 1020 const intptr_t kObjectTypeArgumentsOffset = 2 * kWordSize;
1021 const intptr_t kInstantiatorTypeArgumentsOffset = 1 * kWordSize; 1021 const intptr_t kInstantiatorTypeArgumentsOffset = 1 * kWordSize;
1022 const Immediate raw_null = 1022 const Immediate& raw_null =
1023 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1023 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1024 // The generated code is different if the class is parameterized. 1024 // The generated code is different if the class is parameterized.
1025 const bool is_cls_parameterized = 1025 const bool is_cls_parameterized =
1026 cls.type_arguments_field_offset() != Class::kNoTypeArguments; 1026 cls.type_arguments_field_offset() != Class::kNoTypeArguments;
1027 // kInlineInstanceSize is a constant used as a threshold for determining 1027 // kInlineInstanceSize is a constant used as a threshold for determining
1028 // when the object initialization should be done as a loop or as 1028 // when the object initialization should be done as a loop or as
1029 // straight line code. 1029 // straight line code.
1030 const int kInlineInstanceSize = 12; 1030 const int kInlineInstanceSize = 12;
1031 const intptr_t instance_size = cls.instance_size(); 1031 const intptr_t instance_size = cls.instance_size();
1032 ASSERT(instance_size > 0); 1032 ASSERT(instance_size > 0);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1105 // EDI: new object type arguments (if is_cls_parameterized). 1105 // EDI: new object type arguments (if is_cls_parameterized).
1106 __ LoadObject(EDX, cls); // Load class of object to be allocated. 1106 __ LoadObject(EDX, cls); // Load class of object to be allocated.
1107 // Set the tags. 1107 // Set the tags.
1108 uword tags = 0; 1108 uword tags = 0;
1109 tags = RawObject::SizeTag::update(instance_size, tags); 1109 tags = RawObject::SizeTag::update(instance_size, tags);
1110 ASSERT(cls.id() != kIllegalCid); 1110 ASSERT(cls.id() != kIllegalCid);
1111 tags = RawObject::ClassIdTag::update(cls.id(), tags); 1111 tags = RawObject::ClassIdTag::update(cls.id(), tags);
1112 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); 1112 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags));
1113 1113
1114 // Initialize the remaining words of the object. 1114 // Initialize the remaining words of the object.
1115 const Immediate raw_null = 1115 const Immediate& raw_null =
1116 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1116 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1117 1117
1118 // EAX: new object start. 1118 // EAX: new object start.
1119 // EBX: next object start. 1119 // EBX: next object start.
1120 // EDX: class of the object to be allocated. 1120 // EDX: class of the object to be allocated.
1121 // EDI: new object type arguments (if is_cls_parameterized). 1121 // EDI: new object type arguments (if is_cls_parameterized).
1122 // First try inlining the initialization without a loop. 1122 // First try inlining the initialization without a loop.
1123 if (instance_size < (kInlineInstanceSize * kWordSize)) { 1123 if (instance_size < (kInlineInstanceSize * kWordSize)) {
1124 // Check if the object contains any non-header fields. 1124 // Check if the object contains any non-header fields.
1125 // Small objects are initialized using a consecutive set of writes. 1125 // Small objects are initialized using a consecutive set of writes.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 1186
1187 1187
1188 // Called for inline allocation of closures. 1188 // Called for inline allocation of closures.
1189 // Input parameters: 1189 // Input parameters:
1190 // ESP + 8 : receiver (null if not an implicit instance closure). 1190 // ESP + 8 : receiver (null if not an implicit instance closure).
1191 // ESP + 4 : type arguments object (null if class is no parameterized). 1191 // ESP + 4 : type arguments object (null if class is no parameterized).
1192 // ESP : points to return address. 1192 // ESP : points to return address.
1193 // Uses EAX, EBX, ECX, EDX as temporary registers. 1193 // Uses EAX, EBX, ECX, EDX as temporary registers.
1194 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, 1194 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler,
1195 const Function& func) { 1195 const Function& func) {
1196 const Immediate raw_null = 1196 const Immediate& raw_null =
1197 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1197 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1198 ASSERT(func.IsClosureFunction()); 1198 ASSERT(func.IsClosureFunction());
1199 const bool is_implicit_static_closure = 1199 const bool is_implicit_static_closure =
1200 func.IsImplicitStaticClosureFunction(); 1200 func.IsImplicitStaticClosureFunction();
1201 const bool is_implicit_instance_closure = 1201 const bool is_implicit_instance_closure =
1202 func.IsImplicitInstanceClosureFunction(); 1202 func.IsImplicitInstanceClosureFunction();
1203 const Class& cls = Class::ZoneHandle(func.signature_class()); 1203 const Class& cls = Class::ZoneHandle(func.signature_class());
1204 const bool has_type_arguments = cls.HasTypeArguments(); 1204 const bool has_type_arguments = cls.HasTypeArguments();
1205 const intptr_t kTypeArgumentsOffset = 1 * kWordSize; 1205 const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
1206 const intptr_t kReceiverOffset = 2 * kWordSize; 1206 const intptr_t kReceiverOffset = 2 * kWordSize;
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1343 // EBP : points to previous frame pointer. 1343 // EBP : points to previous frame pointer.
1344 // EBP + 4 : points to return address. 1344 // EBP + 4 : points to return address.
1345 // EBP + 8 : address of last argument (arg n-1). 1345 // EBP + 8 : address of last argument (arg n-1).
1346 // EBP + 8 + 4*(n-1) : address of first argument (arg 0). 1346 // EBP + 8 + 4*(n-1) : address of first argument (arg 0).
1347 // ECX : ic-data. 1347 // ECX : ic-data.
1348 // EDX : arguments descriptor array. 1348 // EDX : arguments descriptor array.
1349 // Uses EAX, EBX, EDI as temporary registers. 1349 // Uses EAX, EBX, EDI as temporary registers.
1350 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 1350 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
1351 // The target function was not found, so invoke method 1351 // The target function was not found, so invoke method
1352 // "dynamic noSuchMethod(InvocationMirror invocation)". 1352 // "dynamic noSuchMethod(InvocationMirror invocation)".
1353 const Immediate raw_null = 1353 const Immediate& raw_null =
1354 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1354 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1355 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 1355 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
1356 __ movl(EAX, Address(EBP, EDI, TIMES_2, kWordSize)); // Get receiver. 1356 __ movl(EAX, Address(EBP, EDI, TIMES_2, kWordSize)); // Get receiver.
1357 1357
1358 // Create a stub frame as we are pushing some objects on the stack before 1358 // Create a stub frame as we are pushing some objects on the stack before
1359 // calling into the runtime. 1359 // calling into the runtime.
1360 AssemblerMacros::EnterStubFrame(assembler); 1360 AssemblerMacros::EnterStubFrame(assembler);
1361 1361
1362 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. 1362 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod.
1363 __ pushl(EAX); // Receiver. 1363 __ pushl(EAX); // Receiver.
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1527 1527
1528 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; 1528 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
1529 __ addl(EBX, Immediate(entry_size)); // Next entry. 1529 __ addl(EBX, Immediate(entry_size)); // Next entry.
1530 __ movl(EDI, Address(EBX, 0)); // Next class ID. 1530 __ movl(EDI, Address(EBX, 0)); // Next class ID.
1531 1531
1532 __ Bind(&test); 1532 __ Bind(&test);
1533 __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid))); // Done? 1533 __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid))); // Done?
1534 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1534 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1535 1535
1536 // IC miss. 1536 // IC miss.
1537 const Immediate raw_null = 1537 const Immediate& raw_null =
1538 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1538 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1539 // Compute address of arguments (first read number of arguments from 1539 // Compute address of arguments (first read number of arguments from
1540 // arguments descriptor array and then compute address on the stack). 1540 // arguments descriptor array and then compute address on the stack).
1541 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 1541 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
1542 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. 1542 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi.
1543 // Create a stub frame as we are pushing some objects on the stack before 1543 // Create a stub frame as we are pushing some objects on the stack before
1544 // calling into the runtime. 1544 // calling into the runtime.
1545 AssemblerMacros::EnterStubFrame(assembler); 1545 AssemblerMacros::EnterStubFrame(assembler);
1546 __ pushl(EDX); // Preserve arguments descriptor array. 1546 __ pushl(EDX); // Preserve arguments descriptor array.
1547 __ pushl(ECX); // Preserve IC data object. 1547 __ pushl(ECX); // Preserve IC data object.
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 } 1689 }
1690 1690
1691 1691
1692 // EDX: Arguments descriptor array. 1692 // EDX: Arguments descriptor array.
1693 // TOS(0): return address (Dart code). 1693 // TOS(0): return address (Dart code).
1694 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { 1694 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
1695 // Create a stub frame as we are pushing some objects on the stack before 1695 // Create a stub frame as we are pushing some objects on the stack before
1696 // calling into the runtime. 1696 // calling into the runtime.
1697 AssemblerMacros::EnterStubFrame(assembler); 1697 AssemblerMacros::EnterStubFrame(assembler);
1698 __ pushl(EDX); // Preserve arguments descriptor. 1698 __ pushl(EDX); // Preserve arguments descriptor.
1699 const Immediate raw_null = 1699 const Immediate& raw_null =
1700 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1700 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1701 __ pushl(raw_null); // Room for result. 1701 __ pushl(raw_null); // Room for result.
1702 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); 1702 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry);
1703 __ popl(EAX); // Code object. 1703 __ popl(EAX); // Code object.
1704 __ popl(EDX); // Restore arguments descriptor. 1704 __ popl(EDX); // Restore arguments descriptor.
1705 __ LeaveFrame(); 1705 __ LeaveFrame();
1706 1706
1707 // Now call the static function. The breakpoint handler function 1707 // Now call the static function. The breakpoint handler function
1708 // ensures that the call target is compiled. 1708 // ensures that the call target is compiled.
1709 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); 1709 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset()));
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1768 // TOS + 0: return address. 1768 // TOS + 0: return address.
1769 // TOS + 1: instantiator type arguments (can be NULL). 1769 // TOS + 1: instantiator type arguments (can be NULL).
1770 // TOS + 2: instance. 1770 // TOS + 2: instance.
1771 // TOS + 3: SubtypeTestCache. 1771 // TOS + 3: SubtypeTestCache.
1772 // Result in ECX: null -> not found, otherwise result (true or false). 1772 // Result in ECX: null -> not found, otherwise result (true or false).
1773 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { 1773 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
1774 ASSERT((1 <= n) && (n <= 3)); 1774 ASSERT((1 <= n) && (n <= 3));
1775 const intptr_t kInstantiatorTypeArgumentsInBytes = 1 * kWordSize; 1775 const intptr_t kInstantiatorTypeArgumentsInBytes = 1 * kWordSize;
1776 const intptr_t kInstanceOffsetInBytes = 2 * kWordSize; 1776 const intptr_t kInstanceOffsetInBytes = 2 * kWordSize;
1777 const intptr_t kCacheOffsetInBytes = 3 * kWordSize; 1777 const intptr_t kCacheOffsetInBytes = 3 * kWordSize;
1778 const Immediate raw_null = 1778 const Immediate& raw_null =
1779 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1779 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1780 __ movl(EAX, Address(ESP, kInstanceOffsetInBytes)); 1780 __ movl(EAX, Address(ESP, kInstanceOffsetInBytes));
1781 if (n > 1) { 1781 if (n > 1) {
1782 // Get instance type arguments. 1782 // Get instance type arguments.
1783 __ LoadClass(ECX, EAX, EBX); 1783 __ LoadClass(ECX, EAX, EBX);
1784 // Compute instance type arguments into EBX. 1784 // Compute instance type arguments into EBX.
1785 Label has_no_type_arguments; 1785 Label has_no_type_arguments;
1786 __ movl(EBX, raw_null); 1786 __ movl(EBX, raw_null);
1787 __ movl(EDI, FieldAddress(ECX, 1787 __ movl(EDI, FieldAddress(ECX,
1788 Class::type_arguments_field_offset_in_words_offset())); 1788 Class::type_arguments_field_offset_in_words_offset()));
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2016 __ LeaveFrame(); 2016 __ LeaveFrame();
2017 2017
2018 __ jmp(&compute_result, Assembler::kNearJump); 2018 __ jmp(&compute_result, Assembler::kNearJump);
2019 } 2019 }
2020 2020
2021 2021
2022 // Calls to runtime to ooptimized give function 2022 // Calls to runtime to ooptimized give function
2023 // EDI: function to be reoptimized. 2023 // EDI: function to be reoptimized.
2024 // EDX: argument descriptor (preserved). 2024 // EDX: argument descriptor (preserved).
2025 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { 2025 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
2026 const Immediate raw_null = 2026 const Immediate& raw_null =
2027 Immediate(reinterpret_cast<intptr_t>(Object::null())); 2027 Immediate(reinterpret_cast<intptr_t>(Object::null()));
2028 AssemblerMacros::EnterStubFrame(assembler); 2028 AssemblerMacros::EnterStubFrame(assembler);
2029 __ pushl(EDX); 2029 __ pushl(EDX);
2030 __ pushl(raw_null); // Setup space on stack for return value. 2030 __ pushl(raw_null); // Setup space on stack for return value.
2031 __ pushl(EDI); 2031 __ pushl(EDI);
2032 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); 2032 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry);
2033 __ popl(EAX); // Discard argument. 2033 __ popl(EAX); // Discard argument.
2034 __ popl(EAX); // Get Code object 2034 __ popl(EAX); // Get Code object
2035 __ popl(EDX); // Restore argument descriptor. 2035 __ popl(EDX); // Restore argument descriptor.
2036 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); 2036 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset()));
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2122 __ Bind(&done); 2122 __ Bind(&done);
2123 __ popl(temp); 2123 __ popl(temp);
2124 __ popl(right); 2124 __ popl(right);
2125 __ popl(left); 2125 __ popl(left);
2126 __ ret(); 2126 __ ret();
2127 } 2127 }
2128 2128
2129 } // namespace dart 2129 } // namespace dart
2130 2130
2131 #endif // defined TARGET_ARCH_IA32 2131 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_arm.cc ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698