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

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

Issue 6685088: Merge isolates to bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 9 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/ia32/assembler-ia32-inl.h ('k') | src/ia32/codegen-ia32.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kConstructStubOffset)); 93 __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kConstructStubOffset));
94 __ lea(ebx, FieldOperand(ebx, Code::kHeaderSize)); 94 __ lea(ebx, FieldOperand(ebx, Code::kHeaderSize));
95 __ jmp(Operand(ebx)); 95 __ jmp(Operand(ebx));
96 96
97 // edi: called object 97 // edi: called object
98 // eax: number of arguments 98 // eax: number of arguments
99 __ bind(&non_function_call); 99 __ bind(&non_function_call);
100 // Set expected number of arguments to zero (not changing eax). 100 // Set expected number of arguments to zero (not changing eax).
101 __ Set(ebx, Immediate(0)); 101 __ Set(ebx, Immediate(0));
102 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); 102 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
103 __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), 103 __ jmp(Handle<Code>(Isolate::Current()->builtins()->builtin(
104 RelocInfo::CODE_TARGET); 104 ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
105 } 105 }
106 106
107 107
108 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 108 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
109 bool is_api_function, 109 bool is_api_function,
110 bool count_constructions) { 110 bool count_constructions) {
111 // Should never count constructions for api objects. 111 // Should never count constructions for api objects.
112 ASSERT(!is_api_function || !count_constructions); 112 ASSERT(!is_api_function || !count_constructions);
113 113
114 // Enter a construct frame. 114 // Enter a construct frame.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 // edi: constructor 177 // edi: constructor
178 // eax: initial map 178 // eax: initial map
179 __ movzx_b(edi, FieldOperand(eax, Map::kInstanceSizeOffset)); 179 __ movzx_b(edi, FieldOperand(eax, Map::kInstanceSizeOffset));
180 __ shl(edi, kPointerSizeLog2); 180 __ shl(edi, kPointerSizeLog2);
181 __ AllocateInNewSpace(edi, ebx, edi, no_reg, &rt_call, NO_ALLOCATION_FLAGS); 181 __ AllocateInNewSpace(edi, ebx, edi, no_reg, &rt_call, NO_ALLOCATION_FLAGS);
182 // Allocated the JSObject, now initialize the fields. 182 // Allocated the JSObject, now initialize the fields.
183 // eax: initial map 183 // eax: initial map
184 // ebx: JSObject 184 // ebx: JSObject
185 // edi: start of next object 185 // edi: start of next object
186 __ mov(Operand(ebx, JSObject::kMapOffset), eax); 186 __ mov(Operand(ebx, JSObject::kMapOffset), eax);
187 __ mov(ecx, Factory::empty_fixed_array()); 187 __ mov(ecx, FACTORY->empty_fixed_array());
188 __ mov(Operand(ebx, JSObject::kPropertiesOffset), ecx); 188 __ mov(Operand(ebx, JSObject::kPropertiesOffset), ecx);
189 __ mov(Operand(ebx, JSObject::kElementsOffset), ecx); 189 __ mov(Operand(ebx, JSObject::kElementsOffset), ecx);
190 // Set extra fields in the newly allocated object. 190 // Set extra fields in the newly allocated object.
191 // eax: initial map 191 // eax: initial map
192 // ebx: JSObject 192 // ebx: JSObject
193 // edi: start of next object 193 // edi: start of next object
194 { Label loop, entry; 194 { Label loop, entry;
195 // To allow for truncation. 195 // To allow for truncation.
196 if (count_constructions) { 196 if (count_constructions) {
197 __ mov(edx, Factory::one_pointer_filler_map()); 197 __ mov(edx, FACTORY->one_pointer_filler_map());
198 } else { 198 } else {
199 __ mov(edx, Factory::undefined_value()); 199 __ mov(edx, FACTORY->undefined_value());
200 } 200 }
201 __ lea(ecx, Operand(ebx, JSObject::kHeaderSize)); 201 __ lea(ecx, Operand(ebx, JSObject::kHeaderSize));
202 __ jmp(&entry); 202 __ jmp(&entry);
203 __ bind(&loop); 203 __ bind(&loop);
204 __ mov(Operand(ecx, 0), edx); 204 __ mov(Operand(ecx, 0), edx);
205 __ add(Operand(ecx), Immediate(kPointerSize)); 205 __ add(Operand(ecx), Immediate(kPointerSize));
206 __ bind(&entry); 206 __ bind(&entry);
207 __ cmp(ecx, Operand(edi)); 207 __ cmp(ecx, Operand(edi));
208 __ j(less, &loop); 208 __ j(less, &loop);
209 } 209 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 ecx, 245 ecx,
246 no_reg, 246 no_reg,
247 &undo_allocation, 247 &undo_allocation,
248 RESULT_CONTAINS_TOP); 248 RESULT_CONTAINS_TOP);
249 249
250 // Initialize the FixedArray. 250 // Initialize the FixedArray.
251 // ebx: JSObject 251 // ebx: JSObject
252 // edi: FixedArray 252 // edi: FixedArray
253 // edx: number of elements 253 // edx: number of elements
254 // ecx: start of next object 254 // ecx: start of next object
255 __ mov(eax, Factory::fixed_array_map()); 255 __ mov(eax, FACTORY->fixed_array_map());
256 __ mov(Operand(edi, FixedArray::kMapOffset), eax); // setup the map 256 __ mov(Operand(edi, FixedArray::kMapOffset), eax); // setup the map
257 __ SmiTag(edx); 257 __ SmiTag(edx);
258 __ mov(Operand(edi, FixedArray::kLengthOffset), edx); // and length 258 __ mov(Operand(edi, FixedArray::kLengthOffset), edx); // and length
259 259
260 // Initialize the fields to undefined. 260 // Initialize the fields to undefined.
261 // ebx: JSObject 261 // ebx: JSObject
262 // edi: FixedArray 262 // edi: FixedArray
263 // ecx: start of next object 263 // ecx: start of next object
264 { Label loop, entry; 264 { Label loop, entry;
265 __ mov(edx, Factory::undefined_value()); 265 __ mov(edx, FACTORY->undefined_value());
266 __ lea(eax, Operand(edi, FixedArray::kHeaderSize)); 266 __ lea(eax, Operand(edi, FixedArray::kHeaderSize));
267 __ jmp(&entry); 267 __ jmp(&entry);
268 __ bind(&loop); 268 __ bind(&loop);
269 __ mov(Operand(eax, 0), edx); 269 __ mov(Operand(eax, 0), edx);
270 __ add(Operand(eax), Immediate(kPointerSize)); 270 __ add(Operand(eax), Immediate(kPointerSize));
271 __ bind(&entry); 271 __ bind(&entry);
272 __ cmp(eax, Operand(ecx)); 272 __ cmp(eax, Operand(ecx));
273 __ j(below, &loop); 273 __ j(below, &loop);
274 } 274 }
275 275
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 __ bind(&loop); 328 __ bind(&loop);
329 __ push(Operand(ebx, ecx, times_4, 0)); 329 __ push(Operand(ebx, ecx, times_4, 0));
330 __ bind(&entry); 330 __ bind(&entry);
331 __ dec(ecx); 331 __ dec(ecx);
332 __ j(greater_equal, &loop); 332 __ j(greater_equal, &loop);
333 333
334 // Call the function. 334 // Call the function.
335 if (is_api_function) { 335 if (is_api_function) {
336 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 336 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
337 Handle<Code> code = Handle<Code>( 337 Handle<Code> code = Handle<Code>(
338 Builtins::builtin(Builtins::HandleApiCallConstruct)); 338 Isolate::Current()->builtins()->builtin(
339 Builtins::HandleApiCallConstruct));
339 ParameterCount expected(0); 340 ParameterCount expected(0);
340 __ InvokeCode(code, expected, expected, 341 __ InvokeCode(code, expected, expected,
341 RelocInfo::CODE_TARGET, CALL_FUNCTION); 342 RelocInfo::CODE_TARGET, CALL_FUNCTION);
342 } else { 343 } else {
343 ParameterCount actual(eax); 344 ParameterCount actual(eax);
344 __ InvokeFunction(edi, actual, CALL_FUNCTION); 345 __ InvokeFunction(edi, actual, CALL_FUNCTION);
345 } 346 }
346 347
347 // Restore context from the frame. 348 // Restore context from the frame.
348 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 349 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
(...skipping 20 matching lines...) Expand all
369 // Restore the arguments count and leave the construct frame. 370 // Restore the arguments count and leave the construct frame.
370 __ bind(&exit); 371 __ bind(&exit);
371 __ mov(ebx, Operand(esp, kPointerSize)); // get arguments count 372 __ mov(ebx, Operand(esp, kPointerSize)); // get arguments count
372 __ LeaveConstructFrame(); 373 __ LeaveConstructFrame();
373 374
374 // Remove caller arguments from the stack and return. 375 // Remove caller arguments from the stack and return.
375 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); 376 ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
376 __ pop(ecx); 377 __ pop(ecx);
377 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver 378 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver
378 __ push(ecx); 379 __ push(ecx);
379 __ IncrementCounter(&Counters::constructed_objects, 1); 380 __ IncrementCounter(COUNTERS->constructed_objects(), 1);
380 __ ret(0); 381 __ ret(0);
381 } 382 }
382 383
383 384
384 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) { 385 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) {
385 Generate_JSConstructStubHelper(masm, false, true); 386 Generate_JSConstructStubHelper(masm, false, true);
386 } 387 }
387 388
388 389
389 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 390 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 __ inc(Operand(ecx)); 430 __ inc(Operand(ecx));
430 __ bind(&entry); 431 __ bind(&entry);
431 __ cmp(ecx, Operand(eax)); 432 __ cmp(ecx, Operand(eax));
432 __ j(not_equal, &loop); 433 __ j(not_equal, &loop);
433 434
434 // Get the function from the stack and call it. 435 // Get the function from the stack and call it.
435 __ mov(edi, Operand(esp, eax, times_4, +1 * kPointerSize)); // +1 ~ receiver 436 __ mov(edi, Operand(esp, eax, times_4, +1 * kPointerSize)); // +1 ~ receiver
436 437
437 // Invoke the code. 438 // Invoke the code.
438 if (is_construct) { 439 if (is_construct) {
439 __ call(Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)), 440 __ call(Handle<Code>(Isolate::Current()->builtins()->builtin(
440 RelocInfo::CODE_TARGET); 441 Builtins::JSConstructCall)), RelocInfo::CODE_TARGET);
441 } else { 442 } else {
442 ParameterCount actual(eax); 443 ParameterCount actual(eax);
443 __ InvokeFunction(edi, actual, CALL_FUNCTION); 444 __ InvokeFunction(edi, actual, CALL_FUNCTION);
444 } 445 }
445 446
446 // Exit the JS frame. Notice that this also removes the empty 447 // Exit the JS frame. Notice that this also removes the empty
447 // context and the function left on the stack by the code 448 // context and the function left on the stack by the code
448 // invocation. 449 // invocation.
449 __ LeaveInternalFrame(); 450 __ LeaveInternalFrame();
450 __ ret(1 * kPointerSize); // remove receiver 451 __ ret(1 * kPointerSize); // remove receiver
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 __ ret(0); 560 __ ret(0);
560 } 561 }
561 562
562 563
563 void Builtins::Generate_FunctionCall(MacroAssembler* masm) { 564 void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
564 // 1. Make sure we have at least one argument. 565 // 1. Make sure we have at least one argument.
565 { Label done; 566 { Label done;
566 __ test(eax, Operand(eax)); 567 __ test(eax, Operand(eax));
567 __ j(not_zero, &done, taken); 568 __ j(not_zero, &done, taken);
568 __ pop(ebx); 569 __ pop(ebx);
569 __ push(Immediate(Factory::undefined_value())); 570 __ push(Immediate(FACTORY->undefined_value()));
570 __ push(ebx); 571 __ push(ebx);
571 __ inc(eax); 572 __ inc(eax);
572 __ bind(&done); 573 __ bind(&done);
573 } 574 }
574 575
575 // 2. Get the function to call (passed as receiver) from the stack, check 576 // 2. Get the function to call (passed as receiver) from the stack, check
576 // if it is a function. 577 // if it is a function.
577 Label non_function; 578 Label non_function;
578 // 1 ~ return address. 579 // 1 ~ return address.
579 __ mov(edi, Operand(esp, eax, times_4, 1 * kPointerSize)); 580 __ mov(edi, Operand(esp, eax, times_4, 1 * kPointerSize));
(...skipping 13 matching lines...) Expand all
593 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 594 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
594 __ test_b(FieldOperand(ebx, SharedFunctionInfo::kStrictModeByteOffset), 595 __ test_b(FieldOperand(ebx, SharedFunctionInfo::kStrictModeByteOffset),
595 1 << SharedFunctionInfo::kStrictModeBitWithinByte); 596 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
596 __ j(not_equal, &shift_arguments); 597 __ j(not_equal, &shift_arguments);
597 598
598 // Compute the receiver in non-strict mode. 599 // Compute the receiver in non-strict mode.
599 __ mov(ebx, Operand(esp, eax, times_4, 0)); // First argument. 600 __ mov(ebx, Operand(esp, eax, times_4, 0)); // First argument.
600 __ test(ebx, Immediate(kSmiTagMask)); 601 __ test(ebx, Immediate(kSmiTagMask));
601 __ j(zero, &convert_to_object); 602 __ j(zero, &convert_to_object);
602 603
603 __ cmp(ebx, Factory::null_value()); 604 __ cmp(ebx, FACTORY->null_value());
604 __ j(equal, &use_global_receiver); 605 __ j(equal, &use_global_receiver);
605 __ cmp(ebx, Factory::undefined_value()); 606 __ cmp(ebx, FACTORY->undefined_value());
606 __ j(equal, &use_global_receiver); 607 __ j(equal, &use_global_receiver);
607 608
608 // We don't use IsObjectJSObjectType here because we jump on success. 609 // We don't use IsObjectJSObjectType here because we jump on success.
609 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); 610 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
610 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 611 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
611 __ sub(Operand(ecx), Immediate(FIRST_JS_OBJECT_TYPE)); 612 __ sub(Operand(ecx), Immediate(FIRST_JS_OBJECT_TYPE));
612 __ cmp(ecx, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE); 613 __ cmp(ecx, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE);
613 __ j(below_equal, &shift_arguments); 614 __ j(below_equal, &shift_arguments);
614 615
615 __ bind(&convert_to_object); 616 __ bind(&convert_to_object);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 __ pop(ebx); // Discard copy of return address. 668 __ pop(ebx); // Discard copy of return address.
668 __ dec(eax); // One fewer argument (first argument is new receiver). 669 __ dec(eax); // One fewer argument (first argument is new receiver).
669 } 670 }
670 671
671 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. 672 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin.
672 { Label function; 673 { Label function;
673 __ test(edi, Operand(edi)); 674 __ test(edi, Operand(edi));
674 __ j(not_zero, &function, taken); 675 __ j(not_zero, &function, taken);
675 __ Set(ebx, Immediate(0)); 676 __ Set(ebx, Immediate(0));
676 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); 677 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
677 __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), 678 __ jmp(Handle<Code>(Isolate::Current()->builtins()->builtin(
678 RelocInfo::CODE_TARGET); 679 ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
679 __ bind(&function); 680 __ bind(&function);
680 } 681 }
681 682
682 // 5b. Get the code to call from the function and check that the number of 683 // 5b. Get the code to call from the function and check that the number of
683 // expected arguments matches what we're providing. If so, jump 684 // expected arguments matches what we're providing. If so, jump
684 // (tail-call) to the code in register edx without checking arguments. 685 // (tail-call) to the code in register edx without checking arguments.
685 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 686 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
686 __ mov(ebx, 687 __ mov(ebx,
687 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); 688 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
688 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); 689 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset));
689 __ SmiUntag(ebx); 690 __ SmiUntag(ebx);
690 __ cmp(eax, Operand(ebx)); 691 __ cmp(eax, Operand(ebx));
691 __ j(not_equal, Handle<Code>(builtin(ArgumentsAdaptorTrampoline))); 692 __ j(not_equal, Handle<Code>(Isolate::Current()->builtins()->builtin(
693 ArgumentsAdaptorTrampoline)));
692 694
693 ParameterCount expected(0); 695 ParameterCount expected(0);
694 __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION); 696 __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION);
695 } 697 }
696 698
697 699
698 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { 700 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
699 __ EnterInternalFrame(); 701 __ EnterInternalFrame();
700 702
701 __ push(Operand(ebp, 4 * kPointerSize)); // push this 703 __ push(Operand(ebp, 4 * kPointerSize)); // push this
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 748
747 // Do not transform the receiver for strict mode functions. 749 // Do not transform the receiver for strict mode functions.
748 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 750 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
749 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset), 751 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset),
750 1 << SharedFunctionInfo::kStrictModeBitWithinByte); 752 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
751 __ j(not_equal, &push_receiver); 753 __ j(not_equal, &push_receiver);
752 754
753 // Compute the receiver in non-strict mode. 755 // Compute the receiver in non-strict mode.
754 __ test(ebx, Immediate(kSmiTagMask)); 756 __ test(ebx, Immediate(kSmiTagMask));
755 __ j(zero, &call_to_object); 757 __ j(zero, &call_to_object);
756 __ cmp(ebx, Factory::null_value()); 758 __ cmp(ebx, FACTORY->null_value());
757 __ j(equal, &use_global_receiver); 759 __ j(equal, &use_global_receiver);
758 __ cmp(ebx, Factory::undefined_value()); 760 __ cmp(ebx, FACTORY->undefined_value());
759 __ j(equal, &use_global_receiver); 761 __ j(equal, &use_global_receiver);
760 762
761 // If given receiver is already a JavaScript object then there's no 763 // If given receiver is already a JavaScript object then there's no
762 // reason for converting it. 764 // reason for converting it.
763 // We don't use IsObjectJSObjectType here because we jump on success. 765 // We don't use IsObjectJSObjectType here because we jump on success.
764 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); 766 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
765 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 767 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
766 __ sub(Operand(ecx), Immediate(FIRST_JS_OBJECT_TYPE)); 768 __ sub(Operand(ecx), Immediate(FIRST_JS_OBJECT_TYPE));
767 __ cmp(ecx, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE); 769 __ cmp(ecx, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE);
768 __ j(below_equal, &push_receiver); 770 __ j(below_equal, &push_receiver);
(...skipping 19 matching lines...) Expand all
788 __ push(ebx); 790 __ push(ebx);
789 791
790 // Copy all arguments from the array to the stack. 792 // Copy all arguments from the array to the stack.
791 Label entry, loop; 793 Label entry, loop;
792 __ mov(eax, Operand(ebp, kIndexOffset)); 794 __ mov(eax, Operand(ebp, kIndexOffset));
793 __ jmp(&entry); 795 __ jmp(&entry);
794 __ bind(&loop); 796 __ bind(&loop);
795 __ mov(edx, Operand(ebp, 2 * kPointerSize)); // load arguments 797 __ mov(edx, Operand(ebp, 2 * kPointerSize)); // load arguments
796 798
797 // Use inline caching to speed up access to arguments. 799 // Use inline caching to speed up access to arguments.
798 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 800 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
801 Builtins::KeyedLoadIC_Initialize));
799 __ call(ic, RelocInfo::CODE_TARGET); 802 __ call(ic, RelocInfo::CODE_TARGET);
800 // It is important that we do not have a test instruction after the 803 // It is important that we do not have a test instruction after the
801 // call. A test instruction after the call is used to indicate that 804 // call. A test instruction after the call is used to indicate that
802 // we have generated an inline version of the keyed load. In this 805 // we have generated an inline version of the keyed load. In this
803 // case, we know that we are not generating a test instruction next. 806 // case, we know that we are not generating a test instruction next.
804 807
805 // Push the nth argument. 808 // Push the nth argument.
806 __ push(eax); 809 __ push(eax);
807 810
808 // Update the index on the stack and in register eax. 811 // Update the index on the stack and in register eax.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 gc_required, 863 gc_required,
861 TAG_OBJECT); 864 TAG_OBJECT);
862 865
863 // Allocated the JSArray. Now initialize the fields except for the elements 866 // Allocated the JSArray. Now initialize the fields except for the elements
864 // array. 867 // array.
865 // result: JSObject 868 // result: JSObject
866 // scratch1: initial map 869 // scratch1: initial map
867 // scratch2: start of next object 870 // scratch2: start of next object
868 __ mov(FieldOperand(result, JSObject::kMapOffset), scratch1); 871 __ mov(FieldOperand(result, JSObject::kMapOffset), scratch1);
869 __ mov(FieldOperand(result, JSArray::kPropertiesOffset), 872 __ mov(FieldOperand(result, JSArray::kPropertiesOffset),
870 Factory::empty_fixed_array()); 873 FACTORY->empty_fixed_array());
871 // Field JSArray::kElementsOffset is initialized later. 874 // Field JSArray::kElementsOffset is initialized later.
872 __ mov(FieldOperand(result, JSArray::kLengthOffset), Immediate(0)); 875 __ mov(FieldOperand(result, JSArray::kLengthOffset), Immediate(0));
873 876
874 // If no storage is requested for the elements array just set the empty 877 // If no storage is requested for the elements array just set the empty
875 // fixed array. 878 // fixed array.
876 if (initial_capacity == 0) { 879 if (initial_capacity == 0) {
877 __ mov(FieldOperand(result, JSArray::kElementsOffset), 880 __ mov(FieldOperand(result, JSArray::kElementsOffset),
878 Factory::empty_fixed_array()); 881 FACTORY->empty_fixed_array());
879 return; 882 return;
880 } 883 }
881 884
882 // Calculate the location of the elements array and set elements array member 885 // Calculate the location of the elements array and set elements array member
883 // of the JSArray. 886 // of the JSArray.
884 // result: JSObject 887 // result: JSObject
885 // scratch2: start of next object 888 // scratch2: start of next object
886 __ lea(scratch1, Operand(result, JSArray::kSize)); 889 __ lea(scratch1, Operand(result, JSArray::kSize));
887 __ mov(FieldOperand(result, JSArray::kElementsOffset), scratch1); 890 __ mov(FieldOperand(result, JSArray::kElementsOffset), scratch1);
888 891
889 // Initialize the FixedArray and fill it with holes. FixedArray length is 892 // Initialize the FixedArray and fill it with holes. FixedArray length is
890 // stored as a smi. 893 // stored as a smi.
891 // result: JSObject 894 // result: JSObject
892 // scratch1: elements array 895 // scratch1: elements array
893 // scratch2: start of next object 896 // scratch2: start of next object
894 __ mov(FieldOperand(scratch1, FixedArray::kMapOffset), 897 __ mov(FieldOperand(scratch1, FixedArray::kMapOffset),
895 Factory::fixed_array_map()); 898 FACTORY->fixed_array_map());
896 __ mov(FieldOperand(scratch1, FixedArray::kLengthOffset), 899 __ mov(FieldOperand(scratch1, FixedArray::kLengthOffset),
897 Immediate(Smi::FromInt(initial_capacity))); 900 Immediate(Smi::FromInt(initial_capacity)));
898 901
899 // Fill the FixedArray with the hole value. Inline the code if short. 902 // Fill the FixedArray with the hole value. Inline the code if short.
900 // Reconsider loop unfolding if kPreallocatedArrayElements gets changed. 903 // Reconsider loop unfolding if kPreallocatedArrayElements gets changed.
901 static const int kLoopUnfoldLimit = 4; 904 static const int kLoopUnfoldLimit = 4;
902 ASSERT(kPreallocatedArrayElements <= kLoopUnfoldLimit); 905 ASSERT(kPreallocatedArrayElements <= kLoopUnfoldLimit);
903 if (initial_capacity <= kLoopUnfoldLimit) { 906 if (initial_capacity <= kLoopUnfoldLimit) {
904 // Use a scratch register here to have only one reloc info when unfolding 907 // Use a scratch register here to have only one reloc info when unfolding
905 // the loop. 908 // the loop.
906 __ mov(scratch3, Factory::the_hole_value()); 909 __ mov(scratch3, FACTORY->the_hole_value());
907 for (int i = 0; i < initial_capacity; i++) { 910 for (int i = 0; i < initial_capacity; i++) {
908 __ mov(FieldOperand(scratch1, 911 __ mov(FieldOperand(scratch1,
909 FixedArray::kHeaderSize + i * kPointerSize), 912 FixedArray::kHeaderSize + i * kPointerSize),
910 scratch3); 913 scratch3);
911 } 914 }
912 } else { 915 } else {
913 Label loop, entry; 916 Label loop, entry;
914 __ jmp(&entry); 917 __ jmp(&entry);
915 __ bind(&loop); 918 __ bind(&loop);
916 __ mov(Operand(scratch1, 0), Factory::the_hole_value()); 919 __ mov(Operand(scratch1, 0), FACTORY->the_hole_value());
917 __ add(Operand(scratch1), Immediate(kPointerSize)); 920 __ add(Operand(scratch1), Immediate(kPointerSize));
918 __ bind(&entry); 921 __ bind(&entry);
919 __ cmp(scratch1, Operand(scratch2)); 922 __ cmp(scratch1, Operand(scratch2));
920 __ j(below, &loop); 923 __ j(below, &loop);
921 } 924 }
922 } 925 }
923 926
924 927
925 // Allocate a JSArray with the number of elements stored in a register. The 928 // Allocate a JSArray with the number of elements stored in a register. The
926 // register array_function holds the built-in Array function and the register 929 // register array_function holds the built-in Array function and the register
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 gc_required, 964 gc_required,
962 TAG_OBJECT); 965 TAG_OBJECT);
963 966
964 // Allocated the JSArray. Now initialize the fields except for the elements 967 // Allocated the JSArray. Now initialize the fields except for the elements
965 // array. 968 // array.
966 // result: JSObject 969 // result: JSObject
967 // elements_array: initial map 970 // elements_array: initial map
968 // elements_array_end: start of next object 971 // elements_array_end: start of next object
969 // array_size: size of array (smi) 972 // array_size: size of array (smi)
970 __ mov(FieldOperand(result, JSObject::kMapOffset), elements_array); 973 __ mov(FieldOperand(result, JSObject::kMapOffset), elements_array);
971 __ mov(elements_array, Factory::empty_fixed_array()); 974 __ mov(elements_array, FACTORY->empty_fixed_array());
972 __ mov(FieldOperand(result, JSArray::kPropertiesOffset), elements_array); 975 __ mov(FieldOperand(result, JSArray::kPropertiesOffset), elements_array);
973 // Field JSArray::kElementsOffset is initialized later. 976 // Field JSArray::kElementsOffset is initialized later.
974 __ mov(FieldOperand(result, JSArray::kLengthOffset), array_size); 977 __ mov(FieldOperand(result, JSArray::kLengthOffset), array_size);
975 978
976 // Calculate the location of the elements array and set elements array member 979 // Calculate the location of the elements array and set elements array member
977 // of the JSArray. 980 // of the JSArray.
978 // result: JSObject 981 // result: JSObject
979 // elements_array_end: start of next object 982 // elements_array_end: start of next object
980 // array_size: size of array (smi) 983 // array_size: size of array (smi)
981 __ lea(elements_array, Operand(result, JSArray::kSize)); 984 __ lea(elements_array, Operand(result, JSArray::kSize));
982 __ mov(FieldOperand(result, JSArray::kElementsOffset), elements_array); 985 __ mov(FieldOperand(result, JSArray::kElementsOffset), elements_array);
983 986
984 // Initialize the fixed array. FixedArray length is stored as a smi. 987 // Initialize the fixed array. FixedArray length is stored as a smi.
985 // result: JSObject 988 // result: JSObject
986 // elements_array: elements array 989 // elements_array: elements array
987 // elements_array_end: start of next object 990 // elements_array_end: start of next object
988 // array_size: size of array (smi) 991 // array_size: size of array (smi)
989 __ mov(FieldOperand(elements_array, FixedArray::kMapOffset), 992 __ mov(FieldOperand(elements_array, FixedArray::kMapOffset),
990 Factory::fixed_array_map()); 993 FACTORY->fixed_array_map());
991 // For non-empty JSArrays the length of the FixedArray and the JSArray is the 994 // For non-empty JSArrays the length of the FixedArray and the JSArray is the
992 // same. 995 // same.
993 __ mov(FieldOperand(elements_array, FixedArray::kLengthOffset), array_size); 996 __ mov(FieldOperand(elements_array, FixedArray::kLengthOffset), array_size);
994 997
995 // Fill the allocated FixedArray with the hole value if requested. 998 // Fill the allocated FixedArray with the hole value if requested.
996 // result: JSObject 999 // result: JSObject
997 // elements_array: elements array 1000 // elements_array: elements array
998 if (fill_with_hole) { 1001 if (fill_with_hole) {
999 __ SmiUntag(array_size); 1002 __ SmiUntag(array_size);
1000 __ lea(edi, Operand(elements_array, 1003 __ lea(edi, Operand(elements_array,
1001 FixedArray::kHeaderSize - kHeapObjectTag)); 1004 FixedArray::kHeaderSize - kHeapObjectTag));
1002 __ mov(eax, Factory::the_hole_value()); 1005 __ mov(eax, FACTORY->the_hole_value());
1003 __ cld(); 1006 __ cld();
1004 // Do not use rep stos when filling less than kRepStosThreshold 1007 // Do not use rep stos when filling less than kRepStosThreshold
1005 // words. 1008 // words.
1006 const int kRepStosThreshold = 16; 1009 const int kRepStosThreshold = 16;
1007 Label loop, entry, done; 1010 Label loop, entry, done;
1008 __ cmp(ecx, kRepStosThreshold); 1011 __ cmp(ecx, kRepStosThreshold);
1009 __ j(below, &loop); // Note: ecx > 0. 1012 __ j(below, &loop); // Note: ecx > 0.
1010 __ rep_stos(); 1013 __ rep_stos();
1011 __ jmp(&done); 1014 __ jmp(&done);
1012 __ bind(&loop); 1015 __ bind(&loop);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 __ bind(&empty_array); 1059 __ bind(&empty_array);
1057 // Handle construction of an empty array. 1060 // Handle construction of an empty array.
1058 AllocateEmptyJSArray(masm, 1061 AllocateEmptyJSArray(masm,
1059 edi, 1062 edi,
1060 eax, 1063 eax,
1061 ebx, 1064 ebx,
1062 ecx, 1065 ecx,
1063 edi, 1066 edi,
1064 kPreallocatedArrayElements, 1067 kPreallocatedArrayElements,
1065 &prepare_generic_code_call); 1068 &prepare_generic_code_call);
1066 __ IncrementCounter(&Counters::array_function_native, 1); 1069 __ IncrementCounter(COUNTERS->array_function_native(), 1);
1067 __ pop(ebx); 1070 __ pop(ebx);
1068 if (construct_call) { 1071 if (construct_call) {
1069 __ pop(edi); 1072 __ pop(edi);
1070 } 1073 }
1071 __ ret(kPointerSize); 1074 __ ret(kPointerSize);
1072 1075
1073 // Check for one argument. Bail out if argument is not smi or if it is 1076 // Check for one argument. Bail out if argument is not smi or if it is
1074 // negative. 1077 // negative.
1075 __ bind(&argc_one_or_more); 1078 __ bind(&argc_one_or_more);
1076 __ cmp(eax, 1); 1079 __ cmp(eax, 1);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 // esp[C]: argument 1115 // esp[C]: argument
1113 AllocateJSArray(masm, 1116 AllocateJSArray(masm,
1114 edi, 1117 edi,
1115 ecx, 1118 ecx,
1116 ebx, 1119 ebx,
1117 eax, 1120 eax,
1118 edx, 1121 edx,
1119 edi, 1122 edi,
1120 true, 1123 true,
1121 &prepare_generic_code_call); 1124 &prepare_generic_code_call);
1122 __ IncrementCounter(&Counters::array_function_native, 1); 1125 __ IncrementCounter(COUNTERS->array_function_native(), 1);
1123 __ mov(eax, ebx); 1126 __ mov(eax, ebx);
1124 __ pop(ebx); 1127 __ pop(ebx);
1125 if (construct_call) { 1128 if (construct_call) {
1126 __ pop(edi); 1129 __ pop(edi);
1127 } 1130 }
1128 __ ret(2 * kPointerSize); 1131 __ ret(2 * kPointerSize);
1129 1132
1130 // Handle construction of an array from a list of arguments. 1133 // Handle construction of an array from a list of arguments.
1131 __ bind(&argc_two_or_more); 1134 __ bind(&argc_two_or_more);
1132 ASSERT(kSmiTag == 0); 1135 ASSERT(kSmiTag == 0);
1133 __ SmiTag(eax); // Convet argc to a smi. 1136 __ SmiTag(eax); // Convet argc to a smi.
1134 // eax: array_size (smi) 1137 // eax: array_size (smi)
1135 // edi: constructor 1138 // edi: constructor
1136 // esp[0] : argc 1139 // esp[0] : argc
1137 // esp[4]: constructor (only if construct_call) 1140 // esp[4]: constructor (only if construct_call)
1138 // esp[8] : return address 1141 // esp[8] : return address
1139 // esp[C] : last argument 1142 // esp[C] : last argument
1140 AllocateJSArray(masm, 1143 AllocateJSArray(masm,
1141 edi, 1144 edi,
1142 eax, 1145 eax,
1143 ebx, 1146 ebx,
1144 ecx, 1147 ecx,
1145 edx, 1148 edx,
1146 edi, 1149 edi,
1147 false, 1150 false,
1148 &prepare_generic_code_call); 1151 &prepare_generic_code_call);
1149 __ IncrementCounter(&Counters::array_function_native, 1); 1152 __ IncrementCounter(COUNTERS->array_function_native(), 1);
1150 __ mov(eax, ebx); 1153 __ mov(eax, ebx);
1151 __ pop(ebx); 1154 __ pop(ebx);
1152 if (construct_call) { 1155 if (construct_call) {
1153 __ pop(edi); 1156 __ pop(edi);
1154 } 1157 }
1155 __ push(eax); 1158 __ push(eax);
1156 // eax: JSArray 1159 // eax: JSArray
1157 // ebx: argc 1160 // ebx: argc
1158 // edx: elements_array_end (untagged) 1161 // edx: elements_array_end (untagged)
1159 // esp[0]: JSArray 1162 // esp[0]: JSArray
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 __ CmpObjectType(ebx, MAP_TYPE, ecx); 1228 __ CmpObjectType(ebx, MAP_TYPE, ecx);
1226 __ Assert(equal, "Unexpected initial map for Array function"); 1229 __ Assert(equal, "Unexpected initial map for Array function");
1227 } 1230 }
1228 1231
1229 // Run the native code for the Array function called as a normal function. 1232 // Run the native code for the Array function called as a normal function.
1230 ArrayNativeCode(masm, false, &generic_array_code); 1233 ArrayNativeCode(masm, false, &generic_array_code);
1231 1234
1232 // Jump to the generic array code in case the specialized code cannot handle 1235 // Jump to the generic array code in case the specialized code cannot handle
1233 // the construction. 1236 // the construction.
1234 __ bind(&generic_array_code); 1237 __ bind(&generic_array_code);
1235 Code* code = Builtins::builtin(Builtins::ArrayCodeGeneric); 1238 Code* code = Isolate::Current()->builtins()->builtin(
1239 Builtins::ArrayCodeGeneric);
1236 Handle<Code> array_code(code); 1240 Handle<Code> array_code(code);
1237 __ jmp(array_code, RelocInfo::CODE_TARGET); 1241 __ jmp(array_code, RelocInfo::CODE_TARGET);
1238 } 1242 }
1239 1243
1240 1244
1241 void Builtins::Generate_ArrayConstructCode(MacroAssembler* masm) { 1245 void Builtins::Generate_ArrayConstructCode(MacroAssembler* masm) {
1242 // ----------- S t a t e ------------- 1246 // ----------- S t a t e -------------
1243 // -- eax : argc 1247 // -- eax : argc
1244 // -- edi : constructor 1248 // -- edi : constructor
1245 // -- esp[0] : return address 1249 // -- esp[0] : return address
(...skipping 13 matching lines...) Expand all
1259 __ CmpObjectType(ebx, MAP_TYPE, ecx); 1263 __ CmpObjectType(ebx, MAP_TYPE, ecx);
1260 __ Assert(equal, "Unexpected initial map for Array function"); 1264 __ Assert(equal, "Unexpected initial map for Array function");
1261 } 1265 }
1262 1266
1263 // Run the native code for the Array function called as constructor. 1267 // Run the native code for the Array function called as constructor.
1264 ArrayNativeCode(masm, true, &generic_constructor); 1268 ArrayNativeCode(masm, true, &generic_constructor);
1265 1269
1266 // Jump to the generic construct code in case the specialized code cannot 1270 // Jump to the generic construct code in case the specialized code cannot
1267 // handle the construction. 1271 // handle the construction.
1268 __ bind(&generic_constructor); 1272 __ bind(&generic_constructor);
1269 Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric); 1273 Code* code = Isolate::Current()->builtins()->builtin(
1274 Builtins::JSConstructStubGeneric);
1270 Handle<Code> generic_construct_stub(code); 1275 Handle<Code> generic_construct_stub(code);
1271 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 1276 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
1272 } 1277 }
1273 1278
1274 1279
1275 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { 1280 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
1276 // ----------- S t a t e ------------- 1281 // ----------- S t a t e -------------
1277 // -- eax : number of arguments 1282 // -- eax : number of arguments
1278 // -- edi : constructor function 1283 // -- edi : constructor function
1279 // -- esp[0] : return address 1284 // -- esp[0] : return address
1280 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1285 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1281 // -- esp[(argc + 1) * 4] : receiver 1286 // -- esp[(argc + 1) * 4] : receiver
1282 // ----------------------------------- 1287 // -----------------------------------
1283 __ IncrementCounter(&Counters::string_ctor_calls, 1); 1288 __ IncrementCounter(COUNTERS->string_ctor_calls(), 1);
1284 1289
1285 if (FLAG_debug_code) { 1290 if (FLAG_debug_code) {
1286 __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, ecx); 1291 __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, ecx);
1287 __ cmp(edi, Operand(ecx)); 1292 __ cmp(edi, Operand(ecx));
1288 __ Assert(equal, "Unexpected String function"); 1293 __ Assert(equal, "Unexpected String function");
1289 } 1294 }
1290 1295
1291 // Load the first argument into eax and get rid of the rest 1296 // Load the first argument into eax and get rid of the rest
1292 // (including the receiver). 1297 // (including the receiver).
1293 Label no_arguments; 1298 Label no_arguments;
1294 __ test(eax, Operand(eax)); 1299 __ test(eax, Operand(eax));
1295 __ j(zero, &no_arguments); 1300 __ j(zero, &no_arguments);
1296 __ mov(ebx, Operand(esp, eax, times_pointer_size, 0)); 1301 __ mov(ebx, Operand(esp, eax, times_pointer_size, 0));
1297 __ pop(ecx); 1302 __ pop(ecx);
1298 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize)); 1303 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1299 __ push(ecx); 1304 __ push(ecx);
1300 __ mov(eax, ebx); 1305 __ mov(eax, ebx);
1301 1306
1302 // Lookup the argument in the number to string cache. 1307 // Lookup the argument in the number to string cache.
1303 Label not_cached, argument_is_string; 1308 Label not_cached, argument_is_string;
1304 NumberToStringStub::GenerateLookupNumberStringCache( 1309 NumberToStringStub::GenerateLookupNumberStringCache(
1305 masm, 1310 masm,
1306 eax, // Input. 1311 eax, // Input.
1307 ebx, // Result. 1312 ebx, // Result.
1308 ecx, // Scratch 1. 1313 ecx, // Scratch 1.
1309 edx, // Scratch 2. 1314 edx, // Scratch 2.
1310 false, // Input is known to be smi? 1315 false, // Input is known to be smi?
1311 &not_cached); 1316 &not_cached);
1312 __ IncrementCounter(&Counters::string_ctor_cached_number, 1); 1317 __ IncrementCounter(COUNTERS->string_ctor_cached_number(), 1);
1313 __ bind(&argument_is_string); 1318 __ bind(&argument_is_string);
1314 // ----------- S t a t e ------------- 1319 // ----------- S t a t e -------------
1315 // -- ebx : argument converted to string 1320 // -- ebx : argument converted to string
1316 // -- edi : constructor function 1321 // -- edi : constructor function
1317 // -- esp[0] : return address 1322 // -- esp[0] : return address
1318 // ----------------------------------- 1323 // -----------------------------------
1319 1324
1320 // Allocate a JSValue and put the tagged pointer into eax. 1325 // Allocate a JSValue and put the tagged pointer into eax.
1321 Label gc_required; 1326 Label gc_required;
1322 __ AllocateInNewSpace(JSValue::kSize, 1327 __ AllocateInNewSpace(JSValue::kSize,
1323 eax, // Result. 1328 eax, // Result.
1324 ecx, // New allocation top (we ignore it). 1329 ecx, // New allocation top (we ignore it).
1325 no_reg, 1330 no_reg,
1326 &gc_required, 1331 &gc_required,
1327 TAG_OBJECT); 1332 TAG_OBJECT);
1328 1333
1329 // Set the map. 1334 // Set the map.
1330 __ LoadGlobalFunctionInitialMap(edi, ecx); 1335 __ LoadGlobalFunctionInitialMap(edi, ecx);
1331 if (FLAG_debug_code) { 1336 if (FLAG_debug_code) {
1332 __ cmpb(FieldOperand(ecx, Map::kInstanceSizeOffset), 1337 __ cmpb(FieldOperand(ecx, Map::kInstanceSizeOffset),
1333 JSValue::kSize >> kPointerSizeLog2); 1338 JSValue::kSize >> kPointerSizeLog2);
1334 __ Assert(equal, "Unexpected string wrapper instance size"); 1339 __ Assert(equal, "Unexpected string wrapper instance size");
1335 __ cmpb(FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset), 0); 1340 __ cmpb(FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset), 0);
1336 __ Assert(equal, "Unexpected unused properties of string wrapper"); 1341 __ Assert(equal, "Unexpected unused properties of string wrapper");
1337 } 1342 }
1338 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ecx); 1343 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ecx);
1339 1344
1340 // Set properties and elements. 1345 // Set properties and elements.
1341 __ Set(ecx, Immediate(Factory::empty_fixed_array())); 1346 __ Set(ecx, Immediate(FACTORY->empty_fixed_array()));
1342 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ecx); 1347 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ecx);
1343 __ mov(FieldOperand(eax, JSObject::kElementsOffset), ecx); 1348 __ mov(FieldOperand(eax, JSObject::kElementsOffset), ecx);
1344 1349
1345 // Set the value. 1350 // Set the value.
1346 __ mov(FieldOperand(eax, JSValue::kValueOffset), ebx); 1351 __ mov(FieldOperand(eax, JSValue::kValueOffset), ebx);
1347 1352
1348 // Ensure the object is fully initialized. 1353 // Ensure the object is fully initialized.
1349 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); 1354 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
1350 1355
1351 // We're done. Return. 1356 // We're done. Return.
1352 __ ret(0); 1357 __ ret(0);
1353 1358
1354 // The argument was not found in the number to string cache. Check 1359 // The argument was not found in the number to string cache. Check
1355 // if it's a string already before calling the conversion builtin. 1360 // if it's a string already before calling the conversion builtin.
1356 Label convert_argument; 1361 Label convert_argument;
1357 __ bind(&not_cached); 1362 __ bind(&not_cached);
1358 STATIC_ASSERT(kSmiTag == 0); 1363 STATIC_ASSERT(kSmiTag == 0);
1359 __ test(eax, Immediate(kSmiTagMask)); 1364 __ test(eax, Immediate(kSmiTagMask));
1360 __ j(zero, &convert_argument); 1365 __ j(zero, &convert_argument);
1361 Condition is_string = masm->IsObjectStringType(eax, ebx, ecx); 1366 Condition is_string = masm->IsObjectStringType(eax, ebx, ecx);
1362 __ j(NegateCondition(is_string), &convert_argument); 1367 __ j(NegateCondition(is_string), &convert_argument);
1363 __ mov(ebx, eax); 1368 __ mov(ebx, eax);
1364 __ IncrementCounter(&Counters::string_ctor_string_value, 1); 1369 __ IncrementCounter(COUNTERS->string_ctor_string_value(), 1);
1365 __ jmp(&argument_is_string); 1370 __ jmp(&argument_is_string);
1366 1371
1367 // Invoke the conversion builtin and put the result into ebx. 1372 // Invoke the conversion builtin and put the result into ebx.
1368 __ bind(&convert_argument); 1373 __ bind(&convert_argument);
1369 __ IncrementCounter(&Counters::string_ctor_conversions, 1); 1374 __ IncrementCounter(COUNTERS->string_ctor_conversions(), 1);
1370 __ EnterInternalFrame(); 1375 __ EnterInternalFrame();
1371 __ push(edi); // Preserve the function. 1376 __ push(edi); // Preserve the function.
1372 __ push(eax); 1377 __ push(eax);
1373 __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION); 1378 __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
1374 __ pop(edi); 1379 __ pop(edi);
1375 __ LeaveInternalFrame(); 1380 __ LeaveInternalFrame();
1376 __ mov(ebx, eax); 1381 __ mov(ebx, eax);
1377 __ jmp(&argument_is_string); 1382 __ jmp(&argument_is_string);
1378 1383
1379 // Load the empty string into ebx, remove the receiver from the 1384 // Load the empty string into ebx, remove the receiver from the
1380 // stack, and jump back to the case where the argument is a string. 1385 // stack, and jump back to the case where the argument is a string.
1381 __ bind(&no_arguments); 1386 __ bind(&no_arguments);
1382 __ Set(ebx, Immediate(Factory::empty_string())); 1387 __ Set(ebx, Immediate(FACTORY->empty_string()));
1383 __ pop(ecx); 1388 __ pop(ecx);
1384 __ lea(esp, Operand(esp, kPointerSize)); 1389 __ lea(esp, Operand(esp, kPointerSize));
1385 __ push(ecx); 1390 __ push(ecx);
1386 __ jmp(&argument_is_string); 1391 __ jmp(&argument_is_string);
1387 1392
1388 // At this point the argument is already a string. Call runtime to 1393 // At this point the argument is already a string. Call runtime to
1389 // create a string wrapper. 1394 // create a string wrapper.
1390 __ bind(&gc_required); 1395 __ bind(&gc_required);
1391 __ IncrementCounter(&Counters::string_ctor_gc_required, 1); 1396 __ IncrementCounter(COUNTERS->string_ctor_gc_required(), 1);
1392 __ EnterInternalFrame(); 1397 __ EnterInternalFrame();
1393 __ push(ebx); 1398 __ push(ebx);
1394 __ CallRuntime(Runtime::kNewStringWrapper, 1); 1399 __ CallRuntime(Runtime::kNewStringWrapper, 1);
1395 __ LeaveInternalFrame(); 1400 __ LeaveInternalFrame();
1396 __ ret(0); 1401 __ ret(0);
1397 } 1402 }
1398 1403
1399 1404
1400 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { 1405 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
1401 __ push(ebp); 1406 __ push(ebp);
(...skipping 30 matching lines...) Expand all
1432 1437
1433 1438
1434 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { 1439 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
1435 // ----------- S t a t e ------------- 1440 // ----------- S t a t e -------------
1436 // -- eax : actual number of arguments 1441 // -- eax : actual number of arguments
1437 // -- ebx : expected number of arguments 1442 // -- ebx : expected number of arguments
1438 // -- edx : code entry to call 1443 // -- edx : code entry to call
1439 // ----------------------------------- 1444 // -----------------------------------
1440 1445
1441 Label invoke, dont_adapt_arguments; 1446 Label invoke, dont_adapt_arguments;
1442 __ IncrementCounter(&Counters::arguments_adaptors, 1); 1447 __ IncrementCounter(COUNTERS->arguments_adaptors(), 1);
1443 1448
1444 Label enough, too_few; 1449 Label enough, too_few;
1445 __ cmp(eax, Operand(ebx)); 1450 __ cmp(eax, Operand(ebx));
1446 __ j(less, &too_few); 1451 __ j(less, &too_few);
1447 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel); 1452 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel);
1448 __ j(equal, &dont_adapt_arguments); 1453 __ j(equal, &dont_adapt_arguments);
1449 1454
1450 { // Enough parameters: Actual >= expected. 1455 { // Enough parameters: Actual >= expected.
1451 __ bind(&enough); 1456 __ bind(&enough);
1452 EnterArgumentsAdaptorFrame(masm); 1457 EnterArgumentsAdaptorFrame(masm);
(...skipping 27 matching lines...) Expand all
1480 __ inc(ecx); 1485 __ inc(ecx);
1481 __ push(Operand(edi, 0)); 1486 __ push(Operand(edi, 0));
1482 __ sub(Operand(edi), Immediate(kPointerSize)); 1487 __ sub(Operand(edi), Immediate(kPointerSize));
1483 __ cmp(ecx, Operand(eax)); 1488 __ cmp(ecx, Operand(eax));
1484 __ j(less, &copy); 1489 __ j(less, &copy);
1485 1490
1486 // Fill remaining expected arguments with undefined values. 1491 // Fill remaining expected arguments with undefined values.
1487 Label fill; 1492 Label fill;
1488 __ bind(&fill); 1493 __ bind(&fill);
1489 __ inc(ecx); 1494 __ inc(ecx);
1490 __ push(Immediate(Factory::undefined_value())); 1495 __ push(Immediate(FACTORY->undefined_value()));
1491 __ cmp(ecx, Operand(ebx)); 1496 __ cmp(ecx, Operand(ebx));
1492 __ j(less, &fill); 1497 __ j(less, &fill);
1493 1498
1494 // Restore function pointer. 1499 // Restore function pointer.
1495 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1500 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1496 } 1501 }
1497 1502
1498 // Call the entry point. 1503 // Call the entry point.
1499 __ bind(&invoke); 1504 __ bind(&invoke);
1500 __ call(Operand(edx)); 1505 __ call(Operand(edx));
1501 1506
1502 // Leave frame and return. 1507 // Leave frame and return.
1503 LeaveArgumentsAdaptorFrame(masm); 1508 LeaveArgumentsAdaptorFrame(masm);
1504 __ ret(0); 1509 __ ret(0);
1505 1510
1506 // ------------------------------------------- 1511 // -------------------------------------------
1507 // Dont adapt arguments. 1512 // Dont adapt arguments.
1508 // ------------------------------------------- 1513 // -------------------------------------------
1509 __ bind(&dont_adapt_arguments); 1514 __ bind(&dont_adapt_arguments);
1510 __ jmp(Operand(edx)); 1515 __ jmp(Operand(edx));
1511 } 1516 }
1512 1517
1513 1518
1514 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { 1519 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
1515 // We shouldn't be performing on-stack replacement in the first 1520 // We shouldn't be performing on-stack replacement in the first
1516 // place if the CPU features we need for the optimized Crankshaft 1521 // place if the CPU features we need for the optimized Crankshaft
1517 // code aren't supported. 1522 // code aren't supported.
1518 CpuFeatures::Probe(false); 1523 CpuFeatures* cpu_features = Isolate::Current()->cpu_features();
1519 if (!CpuFeatures::IsSupported(SSE2)) { 1524 cpu_features->Probe(false);
1525 if (!cpu_features->IsSupported(SSE2)) {
1520 __ Abort("Unreachable code: Cannot optimize without SSE2 support."); 1526 __ Abort("Unreachable code: Cannot optimize without SSE2 support.");
1521 return; 1527 return;
1522 } 1528 }
1523 1529
1524 // Get the loop depth of the stack guard check. This is recorded in 1530 // Get the loop depth of the stack guard check. This is recorded in
1525 // a test(eax, depth) instruction right after the call. 1531 // a test(eax, depth) instruction right after the call.
1526 Label stack_check; 1532 Label stack_check;
1527 __ mov(ebx, Operand(esp, 0)); // return address 1533 __ mov(ebx, Operand(esp, 0)); // return address
1528 if (FLAG_debug_code) { 1534 if (FLAG_debug_code) {
1529 __ cmpb(Operand(ebx, 0), Assembler::kTestAlByte); 1535 __ cmpb(Operand(ebx, 0), Assembler::kTestAlByte);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); 1585 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR);
1580 generator.Generate(); 1586 generator.Generate();
1581 } 1587 }
1582 1588
1583 1589
1584 #undef __ 1590 #undef __
1585 1591
1586 } } // namespace v8::internal 1592 } } // namespace v8::internal
1587 1593
1588 #endif // V8_TARGET_ARCH_IA32 1594 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/assembler-ia32-inl.h ('k') | src/ia32/codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698