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

Side by Side Diff: src/builtins-ia32.cc

Issue 7223: Introduce a special kind of frames for construct frames, e.g.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 2 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/builtins-arm.cc ('k') | src/frames.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-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 __ JumpToBuiltin(ExternalReference(id)); 49 __ JumpToBuiltin(ExternalReference(id));
50 } 50 }
51 51
52 52
53 void Builtins::Generate_JSConstructCall(MacroAssembler* masm) { 53 void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {
54 // ----------- S t a t e ------------- 54 // ----------- S t a t e -------------
55 // -- eax: number of arguments 55 // -- eax: number of arguments
56 // -- edi: constructor function 56 // -- edi: constructor function
57 // ----------------------------------- 57 // -----------------------------------
58 58
59 // Enter an internal frame. 59 // Enter a construct frame.
60 __ EnterInternalFrame(); 60 __ EnterConstructFrame();
61 61
62 // Store a smi-tagged arguments count on the stack. 62 // Store a smi-tagged arguments count on the stack.
63 __ shl(eax, kSmiTagSize); 63 __ shl(eax, kSmiTagSize);
64 __ push(eax); 64 __ push(eax);
65 65
66 // Push the function to invoke on the stack. 66 // Push the function to invoke on the stack.
67 __ push(edi); 67 __ push(edi);
68 68
69 // Try to allocate the object without transitioning into C code. If any of the 69 // Try to allocate the object without transitioning into C code. If any of the
70 // preconditions is not met, the code bails out to the runtime call. 70 // preconditions is not met, the code bails out to the runtime call.
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 Label loop, entry; 258 Label loop, entry;
259 __ mov(ecx, Operand(eax)); 259 __ mov(ecx, Operand(eax));
260 __ jmp(&entry); 260 __ jmp(&entry);
261 __ bind(&loop); 261 __ bind(&loop);
262 __ push(Operand(ebx, ecx, times_4, 0)); 262 __ push(Operand(ebx, ecx, times_4, 0));
263 __ bind(&entry); 263 __ bind(&entry);
264 __ dec(ecx); 264 __ dec(ecx);
265 __ j(greater_equal, &loop); 265 __ j(greater_equal, &loop);
266 266
267 // Call the function. 267 // Call the function.
268 Label return_site;
269 ParameterCount actual(eax); 268 ParameterCount actual(eax);
270 __ InvokeFunction(edi, actual, CALL_FUNCTION); 269 __ InvokeFunction(edi, actual, CALL_FUNCTION);
271 __ bind(&return_site);
272 270
273 // Restore context from the frame. 271 // Restore context from the frame.
274 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 272 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
275 273
276 // If the result is an object (in the ECMA sense), we should get rid 274 // If the result is an object (in the ECMA sense), we should get rid
277 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 275 // of the receiver and use the result; see ECMA-262 section 13.2.2-7
278 // on page 74. 276 // on page 74.
279 Label use_receiver, exit; 277 Label use_receiver, exit;
280 278
281 // If the result is a smi, it is *not* an object in the ECMA sense. 279 // If the result is a smi, it is *not* an object in the ECMA sense.
282 __ test(eax, Immediate(kSmiTagMask)); 280 __ test(eax, Immediate(kSmiTagMask));
283 __ j(zero, &use_receiver, not_taken); 281 __ j(zero, &use_receiver, not_taken);
284 282
285 // If the type of the result (stored in its map) is less than 283 // If the type of the result (stored in its map) is less than
286 // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense. 284 // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense.
287 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); 285 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
288 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 286 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
289 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); 287 __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
290 __ j(greater_equal, &exit, not_taken); 288 __ j(greater_equal, &exit, not_taken);
291 289
292 // Throw away the result of the constructor invocation and use the 290 // Throw away the result of the constructor invocation and use the
293 // on-stack receiver as the result. 291 // on-stack receiver as the result.
294 __ bind(&use_receiver); 292 __ bind(&use_receiver);
295 __ mov(eax, Operand(esp, 0)); 293 __ mov(eax, Operand(esp, 0));
296 294
297 // Restore the arguments count and exit the internal frame. 295 // Restore the arguments count and leave the construct frame.
298 __ bind(&exit); 296 __ bind(&exit);
299 __ mov(ebx, Operand(esp, kPointerSize)); // get arguments count 297 __ mov(ebx, Operand(esp, kPointerSize)); // get arguments count
300 __ LeaveInternalFrame(); 298 __ LeaveConstructFrame();
301 299
302 // Remove caller arguments from the stack and return. 300 // Remove caller arguments from the stack and return.
303 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); 301 ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
304 __ pop(ecx); 302 __ pop(ecx);
305 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver 303 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver
306 __ push(ecx); 304 __ push(ecx);
307 __ ret(0); 305 __ ret(0);
308
309 // Compute the offset from the beginning of the JSConstructCall
310 // builtin code object to the return address after the call.
311 ASSERT(return_site.is_bound());
312 construct_call_pc_offset_ = return_site.pos() + Code::kHeaderSize;
313 } 306 }
314 307
315 308
316 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, 309 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
317 bool is_construct) { 310 bool is_construct) {
318 // Clear the context before we push it when entering the JS frame. 311 // Clear the context before we push it when entering the JS frame.
319 __ xor_(esi, Operand(esi)); // clear esi 312 __ xor_(esi, Operand(esi)); // clear esi
320 313
321 // Enter an internal frame. 314 // Enter an internal frame.
322 __ EnterInternalFrame(); 315 __ EnterInternalFrame();
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 648
656 // Preserve the number of arguments on the stack. Must preserve both 649 // Preserve the number of arguments on the stack. Must preserve both
657 // eax and ebx because these registers are used when copying the 650 // eax and ebx because these registers are used when copying the
658 // arguments and the receiver. 651 // arguments and the receiver.
659 ASSERT(kSmiTagSize == 1); 652 ASSERT(kSmiTagSize == 1);
660 __ lea(ecx, Operand(eax, eax, times_1, kSmiTag)); 653 __ lea(ecx, Operand(eax, eax, times_1, kSmiTag));
661 __ push(Operand(ecx)); 654 __ push(Operand(ecx));
662 } 655 }
663 656
664 657
665 static void ExitArgumentsAdaptorFrame(MacroAssembler* masm) { 658 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
666 // Retrieve the number of arguments from the stack. 659 // Retrieve the number of arguments from the stack.
667 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset)); 660 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset));
668 661
669 // Leave the frame. 662 // Leave the frame.
670 __ leave(); 663 __ leave();
671 664
672 // Remove caller arguments from the stack. 665 // Remove caller arguments from the stack.
673 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); 666 ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
674 __ pop(ecx); 667 __ pop(ecx);
675 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver 668 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 __ inc(ecx); 728 __ inc(ecx);
736 __ push(Immediate(Factory::undefined_value())); 729 __ push(Immediate(Factory::undefined_value()));
737 __ cmp(ecx, Operand(ebx)); 730 __ cmp(ecx, Operand(ebx));
738 __ j(less, &fill); 731 __ j(less, &fill);
739 732
740 // Restore function pointer. 733 // Restore function pointer.
741 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 734 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
742 } 735 }
743 736
744 // Call the entry point. 737 // Call the entry point.
745 Label return_site;
746 __ bind(&invoke); 738 __ bind(&invoke);
747 __ call(Operand(edx)); 739 __ call(Operand(edx));
748 __ bind(&return_site);
749 740
750 ExitArgumentsAdaptorFrame(masm); 741 // Leave frame and return.
742 LeaveArgumentsAdaptorFrame(masm);
751 __ ret(0); 743 __ ret(0);
752 744
753 // Compute the offset from the beginning of the ArgumentsAdaptorTrampoline
754 // builtin code object to the return address after the call.
755 ASSERT(return_site.is_bound());
756 arguments_adaptor_call_pc_offset_ = return_site.pos() + Code::kHeaderSize;
757
758
759 // ------------------------------------------- 745 // -------------------------------------------
760 // Dont adapt arguments. 746 // Dont adapt arguments.
761 // ------------------------------------------- 747 // -------------------------------------------
762 __ bind(&dont_adapt_arguments); 748 __ bind(&dont_adapt_arguments);
763 __ jmp(Operand(edx)); 749 __ jmp(Operand(edx));
764 } 750 }
765 751
766 752
767 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, 753 static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
768 RegList pointer_regs, 754 RegList pointer_regs,
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 // Register state for stub CallFunction (from CallFunctionStub in ic-ia32.cc). 887 // Register state for stub CallFunction (from CallFunctionStub in ic-ia32.cc).
902 // ----------- S t a t e ------------- 888 // ----------- S t a t e -------------
903 // No registers used on entry. 889 // No registers used on entry.
904 // ----------------------------------- 890 // -----------------------------------
905 Generate_DebugBreakCallHelper(masm, 0, false); 891 Generate_DebugBreakCallHelper(masm, 0, false);
906 } 892 }
907 893
908 #undef __ 894 #undef __
909 895
910 } } // namespace v8::internal 896 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/builtins-arm.cc ('k') | src/frames.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698