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

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 8086021: Clean up the x86 assembler API. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 __ cmp(name, Operand::StaticArray(offset, times_2, key_offset)); 59 __ cmp(name, Operand::StaticArray(offset, times_2, key_offset));
60 __ j(not_equal, &miss); 60 __ j(not_equal, &miss);
61 61
62 // Check that the flags match what we're looking for. 62 // Check that the flags match what we're looking for.
63 __ mov(offset, FieldOperand(extra, Code::kFlagsOffset)); 63 __ mov(offset, FieldOperand(extra, Code::kFlagsOffset));
64 __ and_(offset, ~Code::kFlagsNotUsedInLookup); 64 __ and_(offset, ~Code::kFlagsNotUsedInLookup);
65 __ cmp(offset, flags); 65 __ cmp(offset, flags);
66 __ j(not_equal, &miss); 66 __ j(not_equal, &miss);
67 67
68 // Jump to the first instruction in the code stub. 68 // Jump to the first instruction in the code stub.
69 __ add(Operand(extra), Immediate(Code::kHeaderSize - kHeapObjectTag)); 69 __ add(extra, Immediate(Code::kHeaderSize - kHeapObjectTag));
70 __ jmp(Operand(extra)); 70 __ jmp(extra);
71 71
72 __ bind(&miss); 72 __ bind(&miss);
73 } else { 73 } else {
74 // Save the offset on the stack. 74 // Save the offset on the stack.
75 __ push(offset); 75 __ push(offset);
76 76
77 // Check that the key in the entry matches the name. 77 // Check that the key in the entry matches the name.
78 __ cmp(name, Operand::StaticArray(offset, times_2, key_offset)); 78 __ cmp(name, Operand::StaticArray(offset, times_2, key_offset));
79 __ j(not_equal, &miss); 79 __ j(not_equal, &miss);
80 80
81 // Get the code entry from the cache. 81 // Get the code entry from the cache.
82 __ mov(offset, Operand::StaticArray(offset, times_2, value_offset)); 82 __ mov(offset, Operand::StaticArray(offset, times_2, value_offset));
83 83
84 // Check that the flags match what we're looking for. 84 // Check that the flags match what we're looking for.
85 __ mov(offset, FieldOperand(offset, Code::kFlagsOffset)); 85 __ mov(offset, FieldOperand(offset, Code::kFlagsOffset));
86 __ and_(offset, ~Code::kFlagsNotUsedInLookup); 86 __ and_(offset, ~Code::kFlagsNotUsedInLookup);
87 __ cmp(offset, flags); 87 __ cmp(offset, flags);
88 __ j(not_equal, &miss); 88 __ j(not_equal, &miss);
89 89
90 // Restore offset and re-load code entry from cache. 90 // Restore offset and re-load code entry from cache.
91 __ pop(offset); 91 __ pop(offset);
92 __ mov(offset, Operand::StaticArray(offset, times_2, value_offset)); 92 __ mov(offset, Operand::StaticArray(offset, times_2, value_offset));
93 93
94 // Jump to the first instruction in the code stub. 94 // Jump to the first instruction in the code stub.
95 __ add(Operand(offset), Immediate(Code::kHeaderSize - kHeapObjectTag)); 95 __ add(offset, Immediate(Code::kHeaderSize - kHeapObjectTag));
96 __ jmp(Operand(offset)); 96 __ jmp(offset);
97 97
98 // Pop at miss. 98 // Pop at miss.
99 __ bind(&miss); 99 __ bind(&miss);
100 __ pop(offset); 100 __ pop(offset);
101 } 101 }
102 } 102 }
103 103
104 104
105 // Helper function used to check that the dictionary doesn't contain 105 // Helper function used to check that the dictionary doesn't contain
106 // the property. This function may return false negatives, so miss_label 106 // the property. This function may return false negatives, so miss_label
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); 197 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize);
198 198
199 // Probe the primary table. 199 // Probe the primary table.
200 ProbeTable(isolate, masm, flags, kPrimary, name, scratch, extra); 200 ProbeTable(isolate, masm, flags, kPrimary, name, scratch, extra);
201 201
202 // Primary miss: Compute hash for secondary probe. 202 // Primary miss: Compute hash for secondary probe.
203 __ mov(scratch, FieldOperand(name, String::kHashFieldOffset)); 203 __ mov(scratch, FieldOperand(name, String::kHashFieldOffset));
204 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); 204 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
205 __ xor_(scratch, flags); 205 __ xor_(scratch, flags);
206 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); 206 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize);
207 __ sub(scratch, Operand(name)); 207 __ sub(scratch, name);
208 __ add(Operand(scratch), Immediate(flags)); 208 __ add(scratch, Immediate(flags));
209 __ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize); 209 __ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize);
210 210
211 // Probe the secondary table. 211 // Probe the secondary table.
212 ProbeTable(isolate, masm, flags, kSecondary, name, scratch, extra); 212 ProbeTable(isolate, masm, flags, kSecondary, name, scratch, extra);
213 213
214 // Cache miss: Fall-through and let caller handle the miss by 214 // Cache miss: Fall-through and let caller handle the miss by
215 // entering the runtime system. 215 // entering the runtime system.
216 __ bind(&miss); 216 __ bind(&miss);
217 } 217 }
218 218
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 } 311 }
312 } 312 }
313 313
314 314
315 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, 315 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,
316 Register receiver, 316 Register receiver,
317 Register scratch1, 317 Register scratch1,
318 Register scratch2, 318 Register scratch2,
319 Label* miss_label) { 319 Label* miss_label) {
320 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 320 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
321 __ mov(eax, Operand(scratch1)); 321 __ mov(eax, scratch1);
322 __ ret(0); 322 __ ret(0);
323 } 323 }
324 324
325 325
326 // Load a fast property out of a holder object (src). In-object properties 326 // Load a fast property out of a holder object (src). In-object properties
327 // are loaded directly otherwise the property is loaded from the properties 327 // are loaded directly otherwise the property is loaded from the properties
328 // fixed array. 328 // fixed array.
329 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 329 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
330 Register dst, Register src, 330 Register dst, Register src,
331 JSObject* holder, int index) { 331 JSObject* holder, int index) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { 399 static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
400 // ----------- S t a t e ------------- 400 // ----------- S t a t e -------------
401 // -- esp[0] : return address. 401 // -- esp[0] : return address.
402 // -- esp[4] : last fast api call extra argument. 402 // -- esp[4] : last fast api call extra argument.
403 // -- ... 403 // -- ...
404 // -- esp[kFastApiCallArguments * 4] : first fast api call extra argument. 404 // -- esp[kFastApiCallArguments * 4] : first fast api call extra argument.
405 // -- esp[kFastApiCallArguments * 4 + 4] : last argument in the internal 405 // -- esp[kFastApiCallArguments * 4 + 4] : last argument in the internal
406 // frame. 406 // frame.
407 // ----------------------------------- 407 // -----------------------------------
408 __ pop(scratch); 408 __ pop(scratch);
409 __ add(Operand(esp), Immediate(kPointerSize * kFastApiCallArguments)); 409 __ add(esp, Immediate(kPointerSize * kFastApiCallArguments));
410 __ push(scratch); 410 __ push(scratch);
411 } 411 }
412 412
413 413
414 // Generates call to API function. 414 // Generates call to API function.
415 static MaybeObject* GenerateFastApiCall(MacroAssembler* masm, 415 static MaybeObject* GenerateFastApiCall(MacroAssembler* masm,
416 const CallOptimization& optimization, 416 const CallOptimization& optimization,
417 int argc) { 417 int argc) {
418 // ----------- S t a t e ------------- 418 // ----------- S t a t e -------------
419 // -- esp[0] : return address 419 // -- esp[0] : return address
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 455
456 const int kApiArgc = 1; // API function gets reference to the v8::Arguments. 456 const int kApiArgc = 1; // API function gets reference to the v8::Arguments.
457 457
458 // Allocate the v8::Arguments structure in the arguments' space since 458 // Allocate the v8::Arguments structure in the arguments' space since
459 // it's not controlled by GC. 459 // it's not controlled by GC.
460 const int kApiStackSpace = 4; 460 const int kApiStackSpace = 4;
461 461
462 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace); 462 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace);
463 463
464 __ mov(ApiParameterOperand(1), eax); // v8::Arguments::implicit_args_. 464 __ mov(ApiParameterOperand(1), eax); // v8::Arguments::implicit_args_.
465 __ add(Operand(eax), Immediate(argc * kPointerSize)); 465 __ add(eax, Immediate(argc * kPointerSize));
466 __ mov(ApiParameterOperand(2), eax); // v8::Arguments::values_. 466 __ mov(ApiParameterOperand(2), eax); // v8::Arguments::values_.
467 __ Set(ApiParameterOperand(3), Immediate(argc)); // v8::Arguments::length_. 467 __ Set(ApiParameterOperand(3), Immediate(argc)); // v8::Arguments::length_.
468 // v8::Arguments::is_construct_call_. 468 // v8::Arguments::is_construct_call_.
469 __ Set(ApiParameterOperand(4), Immediate(0)); 469 __ Set(ApiParameterOperand(4), Immediate(0));
470 470
471 // v8::InvocationCallback's argument. 471 // v8::InvocationCallback's argument.
472 __ lea(eax, ApiParameterOperand(1)); 472 __ lea(eax, ApiParameterOperand(1));
473 __ mov(ApiParameterOperand(0), eax); 473 __ mov(ApiParameterOperand(0), eax);
474 474
475 // Emitting a stub call may try to allocate (if the code is not 475 // Emitting a stub call may try to allocate (if the code is not
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 // object and the number of in-object properties is not going to change. 782 // object and the number of in-object properties is not going to change.
783 index -= object->map()->inobject_properties(); 783 index -= object->map()->inobject_properties();
784 784
785 if (index < 0) { 785 if (index < 0) {
786 // Set the property straight into the object. 786 // Set the property straight into the object.
787 int offset = object->map()->instance_size() + (index * kPointerSize); 787 int offset = object->map()->instance_size() + (index * kPointerSize);
788 __ mov(FieldOperand(receiver_reg, offset), eax); 788 __ mov(FieldOperand(receiver_reg, offset), eax);
789 789
790 // Update the write barrier for the array address. 790 // Update the write barrier for the array address.
791 // Pass the value being stored in the now unused name_reg. 791 // Pass the value being stored in the now unused name_reg.
792 __ mov(name_reg, Operand(eax)); 792 __ mov(name_reg, eax);
793 __ RecordWriteField(receiver_reg, 793 __ RecordWriteField(receiver_reg,
794 offset, 794 offset,
795 name_reg, 795 name_reg,
796 scratch, 796 scratch,
797 kDontSaveFPRegs); 797 kDontSaveFPRegs);
798 } else { 798 } else {
799 // Write to the properties array. 799 // Write to the properties array.
800 int offset = index * kPointerSize + FixedArray::kHeaderSize; 800 int offset = index * kPointerSize + FixedArray::kHeaderSize;
801 // Get the properties array (optimistically). 801 // Get the properties array (optimistically).
802 __ mov(scratch, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 802 __ mov(scratch, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
803 __ mov(FieldOperand(scratch, offset), eax); 803 __ mov(FieldOperand(scratch, offset), eax);
804 804
805 // Update the write barrier for the array address. 805 // Update the write barrier for the array address.
806 // Pass the value being stored in the now unused name_reg. 806 // Pass the value being stored in the now unused name_reg.
807 __ mov(name_reg, Operand(eax)); 807 __ mov(name_reg, eax);
808 __ RecordWriteField(scratch, 808 __ RecordWriteField(scratch,
809 offset, 809 offset,
810 name_reg, 810 name_reg,
811 receiver_reg, 811 receiver_reg,
812 kDontSaveFPRegs); 812 kDontSaveFPRegs);
813 } 813 }
814 814
815 // Return the value (register eax). 815 // Return the value (register eax).
816 __ ret(0); 816 __ ret(0);
817 } 817 }
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 set_failure(Failure::cast(negative_lookup)); 936 set_failure(Failure::cast(negative_lookup));
937 return reg; 937 return reg;
938 } 938 }
939 939
940 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 940 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
941 reg = holder_reg; // from now the object is in holder_reg 941 reg = holder_reg; // from now the object is in holder_reg
942 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 942 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
943 } else if (heap()->InNewSpace(prototype)) { 943 } else if (heap()->InNewSpace(prototype)) {
944 // Get the map of the current object. 944 // Get the map of the current object.
945 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 945 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
946 __ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map()))); 946 __ cmp(scratch1, Immediate(Handle<Map>(current->map())));
947 // Branch on the result of the map check. 947 // Branch on the result of the map check.
948 __ j(not_equal, miss); 948 __ j(not_equal, miss);
949 // Check access rights to the global object. This has to happen 949 // Check access rights to the global object. This has to happen
950 // after the map check so that we know that the object is 950 // after the map check so that we know that the object is
951 // actually a global object. 951 // actually a global object.
952 if (current->IsJSGlobalProxy()) { 952 if (current->IsJSGlobalProxy()) {
953 __ CheckAccessGlobalProxy(reg, scratch1, miss); 953 __ CheckAccessGlobalProxy(reg, scratch1, miss);
954 954
955 // Restore scratch register to be the map of the object. 955 // Restore scratch register to be the map of the object.
956 // We load the prototype from the map in the scratch register. 956 // We load the prototype from the map in the scratch register.
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 CheckPrototypes(object, receiver, holder, scratch1, 1057 CheckPrototypes(object, receiver, holder, scratch1,
1058 scratch2, scratch3, name, miss); 1058 scratch2, scratch3, name, miss);
1059 1059
1060 Handle<AccessorInfo> callback_handle(callback); 1060 Handle<AccessorInfo> callback_handle(callback);
1061 1061
1062 // Insert additional parameters into the stack frame above return address. 1062 // Insert additional parameters into the stack frame above return address.
1063 ASSERT(!scratch3.is(reg)); 1063 ASSERT(!scratch3.is(reg));
1064 __ pop(scratch3); // Get return address to place it below. 1064 __ pop(scratch3); // Get return address to place it below.
1065 1065
1066 __ push(receiver); // receiver 1066 __ push(receiver); // receiver
1067 __ mov(scratch2, Operand(esp)); 1067 __ mov(scratch2, esp);
1068 ASSERT(!scratch2.is(reg)); 1068 ASSERT(!scratch2.is(reg));
1069 __ push(reg); // holder 1069 __ push(reg); // holder
1070 // Push data from AccessorInfo. 1070 // Push data from AccessorInfo.
1071 if (isolate()->heap()->InNewSpace(callback_handle->data())) { 1071 if (isolate()->heap()->InNewSpace(callback_handle->data())) {
1072 __ mov(scratch1, Immediate(callback_handle)); 1072 __ mov(scratch1, Immediate(callback_handle));
1073 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset)); 1073 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset));
1074 } else { 1074 } else {
1075 __ push(Immediate(Handle<Object>(callback_handle->data()))); 1075 __ push(Immediate(Handle<Object>(callback_handle->data())));
1076 } 1076 }
1077 1077
(...skipping 10 matching lines...) Expand all
1088 Address getter_address = v8::ToCData<Address>(callback->getter()); 1088 Address getter_address = v8::ToCData<Address>(callback->getter());
1089 ApiFunction fun(getter_address); 1089 ApiFunction fun(getter_address);
1090 1090
1091 // 3 elements array for v8::Agruments::values_, handler for name and pointer 1091 // 3 elements array for v8::Agruments::values_, handler for name and pointer
1092 // to the values (it considered as smi in GC). 1092 // to the values (it considered as smi in GC).
1093 const int kStackSpace = 5; 1093 const int kStackSpace = 5;
1094 const int kApiArgc = 2; 1094 const int kApiArgc = 2;
1095 1095
1096 __ PrepareCallApiFunction(kApiArgc); 1096 __ PrepareCallApiFunction(kApiArgc);
1097 __ mov(ApiParameterOperand(0), ebx); // name. 1097 __ mov(ApiParameterOperand(0), ebx); // name.
1098 __ add(Operand(ebx), Immediate(kPointerSize)); 1098 __ add(ebx, Immediate(kPointerSize));
1099 __ mov(ApiParameterOperand(1), ebx); // arguments pointer. 1099 __ mov(ApiParameterOperand(1), ebx); // arguments pointer.
1100 1100
1101 // Emitting a stub call may try to allocate (if the code is not 1101 // Emitting a stub call may try to allocate (if the code is not
1102 // already generated). Do not allow the assembler to perform a 1102 // already generated). Do not allow the assembler to perform a
1103 // garbage collection but instead return the allocation failure 1103 // garbage collection but instead return the allocation failure
1104 // object. 1104 // object.
1105 return masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace); 1105 return masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace);
1106 } 1106 }
1107 1107
1108 1108
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1265 ExternalReference ref = 1265 ExternalReference ref =
1266 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), 1266 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
1267 isolate()); 1267 isolate());
1268 __ TailCallExternalReference(ref, 5, 1); 1268 __ TailCallExternalReference(ref, 5, 1);
1269 } 1269 }
1270 } 1270 }
1271 1271
1272 1272
1273 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { 1273 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) {
1274 if (kind_ == Code::KEYED_CALL_IC) { 1274 if (kind_ == Code::KEYED_CALL_IC) {
1275 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); 1275 __ cmp(ecx, Immediate(Handle<String>(name)));
1276 __ j(not_equal, miss); 1276 __ j(not_equal, miss);
1277 } 1277 }
1278 } 1278 }
1279 1279
1280 1280
1281 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, 1281 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object,
1282 JSObject* holder, 1282 JSObject* holder,
1283 String* name, 1283 String* name,
1284 Label* miss) { 1284 Label* miss) {
1285 ASSERT(holder->IsGlobalObject()); 1285 ASSERT(holder->IsGlobalObject());
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1322 // function, we have to verify that it still is a function. 1322 // function, we have to verify that it still is a function.
1323 __ JumpIfSmi(edi, miss); 1323 __ JumpIfSmi(edi, miss);
1324 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); 1324 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1325 __ j(not_equal, miss); 1325 __ j(not_equal, miss);
1326 1326
1327 // Check the shared function info. Make sure it hasn't changed. 1327 // Check the shared function info. Make sure it hasn't changed.
1328 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), 1328 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset),
1329 Immediate(Handle<SharedFunctionInfo>(function->shared()))); 1329 Immediate(Handle<SharedFunctionInfo>(function->shared())));
1330 __ j(not_equal, miss); 1330 __ j(not_equal, miss);
1331 } else { 1331 } else {
1332 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); 1332 __ cmp(edi, Immediate(Handle<JSFunction>(function)));
1333 __ j(not_equal, miss); 1333 __ j(not_equal, miss);
1334 } 1334 }
1335 } 1335 }
1336 1336
1337 1337
1338 MaybeObject* CallStubCompiler::GenerateMissBranch() { 1338 MaybeObject* CallStubCompiler::GenerateMissBranch() {
1339 MaybeObject* maybe_obj = 1339 MaybeObject* maybe_obj =
1340 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), 1340 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1341 kind_, 1341 kind_,
1342 extra_ic_state_); 1342 extra_ic_state_);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 Immediate(factory()->fixed_array_map())); 1453 Immediate(factory()->fixed_array_map()));
1454 __ j(not_equal, &call_builtin); 1454 __ j(not_equal, &call_builtin);
1455 1455
1456 if (argc == 1) { // Otherwise fall through to call builtin. 1456 if (argc == 1) { // Otherwise fall through to call builtin.
1457 Label attempt_to_grow_elements, with_write_barrier; 1457 Label attempt_to_grow_elements, with_write_barrier;
1458 1458
1459 // Get the array's length into eax and calculate new length. 1459 // Get the array's length into eax and calculate new length.
1460 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); 1460 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1461 STATIC_ASSERT(kSmiTagSize == 1); 1461 STATIC_ASSERT(kSmiTagSize == 1);
1462 STATIC_ASSERT(kSmiTag == 0); 1462 STATIC_ASSERT(kSmiTag == 0);
1463 __ add(Operand(eax), Immediate(Smi::FromInt(argc))); 1463 __ add(eax, Immediate(Smi::FromInt(argc)));
1464 1464
1465 // Get the element's length into ecx. 1465 // Get the element's length into ecx.
1466 __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); 1466 __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
1467 1467
1468 // Check if we could survive without allocation. 1468 // Check if we could survive without allocation.
1469 __ cmp(eax, Operand(ecx)); 1469 __ cmp(eax, ecx);
1470 __ j(greater, &attempt_to_grow_elements); 1470 __ j(greater, &attempt_to_grow_elements);
1471 1471
1472 // Check if value is a smi. 1472 // Check if value is a smi.
1473 __ mov(ecx, Operand(esp, argc * kPointerSize)); 1473 __ mov(ecx, Operand(esp, argc * kPointerSize));
1474 __ JumpIfNotSmi(ecx, &with_write_barrier); 1474 __ JumpIfNotSmi(ecx, &with_write_barrier);
1475 1475
1476 // Save new length. 1476 // Save new length.
1477 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax); 1477 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
1478 1478
1479 // Push the element. 1479 // Push the element.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1531 ExternalReference::new_space_allocation_limit_address(isolate()); 1531 ExternalReference::new_space_allocation_limit_address(isolate());
1532 1532
1533 const int kAllocationDelta = 4; 1533 const int kAllocationDelta = 4;
1534 // Load top. 1534 // Load top.
1535 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top)); 1535 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top));
1536 1536
1537 // Check if it's the end of elements. 1537 // Check if it's the end of elements.
1538 __ lea(edx, FieldOperand(ebx, 1538 __ lea(edx, FieldOperand(ebx,
1539 eax, times_half_pointer_size, 1539 eax, times_half_pointer_size,
1540 FixedArray::kHeaderSize - argc * kPointerSize)); 1540 FixedArray::kHeaderSize - argc * kPointerSize));
1541 __ cmp(edx, Operand(ecx)); 1541 __ cmp(edx, ecx);
1542 __ j(not_equal, &call_builtin); 1542 __ j(not_equal, &call_builtin);
1543 __ add(Operand(ecx), Immediate(kAllocationDelta * kPointerSize)); 1543 __ add(ecx, Immediate(kAllocationDelta * kPointerSize));
1544 __ cmp(ecx, Operand::StaticVariable(new_space_allocation_limit)); 1544 __ cmp(ecx, Operand::StaticVariable(new_space_allocation_limit));
1545 __ j(above, &call_builtin); 1545 __ j(above, &call_builtin);
1546 1546
1547 // We fit and could grow elements. 1547 // We fit and could grow elements.
1548 __ mov(Operand::StaticVariable(new_space_allocation_top), ecx); 1548 __ mov(Operand::StaticVariable(new_space_allocation_top), ecx);
1549 1549
1550 // Push the argument... 1550 // Push the argument...
1551 __ mov(Operand(edx, 0), edi); 1551 __ mov(Operand(edx, 0), edi);
1552 // ... and fill the rest with holes. 1552 // ... and fill the rest with holes.
1553 for (int i = 1; i < kAllocationDelta; i++) { 1553 for (int i = 1; i < kAllocationDelta; i++) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1629 // Get the elements array of the object. 1629 // Get the elements array of the object.
1630 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); 1630 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
1631 1631
1632 // Check that the elements are in fast mode and writable. 1632 // Check that the elements are in fast mode and writable.
1633 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 1633 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
1634 Immediate(factory()->fixed_array_map())); 1634 Immediate(factory()->fixed_array_map()));
1635 __ j(not_equal, &call_builtin); 1635 __ j(not_equal, &call_builtin);
1636 1636
1637 // Get the array's length into ecx and calculate new length. 1637 // Get the array's length into ecx and calculate new length.
1638 __ mov(ecx, FieldOperand(edx, JSArray::kLengthOffset)); 1638 __ mov(ecx, FieldOperand(edx, JSArray::kLengthOffset));
1639 __ sub(Operand(ecx), Immediate(Smi::FromInt(1))); 1639 __ sub(ecx, Immediate(Smi::FromInt(1)));
1640 __ j(negative, &return_undefined); 1640 __ j(negative, &return_undefined);
1641 1641
1642 // Get the last element. 1642 // Get the last element.
1643 STATIC_ASSERT(kSmiTagSize == 1); 1643 STATIC_ASSERT(kSmiTagSize == 1);
1644 STATIC_ASSERT(kSmiTag == 0); 1644 STATIC_ASSERT(kSmiTag == 0);
1645 __ mov(eax, FieldOperand(ebx, 1645 __ mov(eax, FieldOperand(ebx,
1646 ecx, times_half_pointer_size, 1646 ecx, times_half_pointer_size,
1647 FixedArray::kHeaderSize)); 1647 FixedArray::kHeaderSize));
1648 __ cmp(Operand(eax), Immediate(factory()->the_hole_value())); 1648 __ cmp(eax, Immediate(factory()->the_hole_value()));
1649 __ j(equal, &call_builtin); 1649 __ j(equal, &call_builtin);
1650 1650
1651 // Set the array's length. 1651 // Set the array's length.
1652 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx); 1652 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx);
1653 1653
1654 // Fill with the hole. 1654 // Fill with the hole.
1655 __ mov(FieldOperand(ebx, 1655 __ mov(FieldOperand(ebx,
1656 ecx, times_half_pointer_size, 1656 ecx, times_half_pointer_size,
1657 FixedArray::kHeaderSize), 1657 FixedArray::kHeaderSize),
1658 Immediate(factory()->the_hole_value())); 1658 Immediate(factory()->the_hole_value()));
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
2102 Label not_smi; 2102 Label not_smi;
2103 STATIC_ASSERT(kSmiTag == 0); 2103 STATIC_ASSERT(kSmiTag == 0);
2104 __ JumpIfNotSmi(eax, &not_smi); 2104 __ JumpIfNotSmi(eax, &not_smi);
2105 2105
2106 // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0 2106 // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0
2107 // otherwise. 2107 // otherwise.
2108 __ mov(ebx, eax); 2108 __ mov(ebx, eax);
2109 __ sar(ebx, kBitsPerInt - 1); 2109 __ sar(ebx, kBitsPerInt - 1);
2110 2110
2111 // Do bitwise not or do nothing depending on ebx. 2111 // Do bitwise not or do nothing depending on ebx.
2112 __ xor_(eax, Operand(ebx)); 2112 __ xor_(eax, ebx);
2113 2113
2114 // Add 1 or do nothing depending on ebx. 2114 // Add 1 or do nothing depending on ebx.
2115 __ sub(eax, Operand(ebx)); 2115 __ sub(eax, ebx);
2116 2116
2117 // If the result is still negative, go to the slow case. 2117 // If the result is still negative, go to the slow case.
2118 // This only happens for the most negative smi. 2118 // This only happens for the most negative smi.
2119 Label slow; 2119 Label slow;
2120 __ j(negative, &slow); 2120 __ j(negative, &slow);
2121 2121
2122 // Smi case done. 2122 // Smi case done.
2123 __ ret(2 * kPointerSize); 2123 __ ret(2 * kPointerSize);
2124 2124
2125 // Check if the argument is a heap number and load its exponent and 2125 // Check if the argument is a heap number and load its exponent and
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2188 2188
2189 // Check that the receiver isn't a smi. 2189 // Check that the receiver isn't a smi.
2190 __ JumpIfSmi(edx, &miss_before_stack_reserved); 2190 __ JumpIfSmi(edx, &miss_before_stack_reserved);
2191 2191
2192 Counters* counters = isolate()->counters(); 2192 Counters* counters = isolate()->counters();
2193 __ IncrementCounter(counters->call_const(), 1); 2193 __ IncrementCounter(counters->call_const(), 1);
2194 __ IncrementCounter(counters->call_const_fast_api(), 1); 2194 __ IncrementCounter(counters->call_const_fast_api(), 1);
2195 2195
2196 // Allocate space for v8::Arguments implicit values. Must be initialized 2196 // Allocate space for v8::Arguments implicit values. Must be initialized
2197 // before calling any runtime function. 2197 // before calling any runtime function.
2198 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); 2198 __ sub(esp, Immediate(kFastApiCallArguments * kPointerSize));
2199 2199
2200 // Check that the maps haven't changed and find a Holder as a side effect. 2200 // Check that the maps haven't changed and find a Holder as a side effect.
2201 CheckPrototypes(JSObject::cast(object), edx, holder, 2201 CheckPrototypes(JSObject::cast(object), edx, holder,
2202 ebx, eax, edi, name, depth, &miss); 2202 ebx, eax, edi, name, depth, &miss);
2203 2203
2204 // Move the return address on top of the stack. 2204 // Move the return address on top of the stack.
2205 __ mov(eax, Operand(esp, 3 * kPointerSize)); 2205 __ mov(eax, Operand(esp, 3 * kPointerSize));
2206 __ mov(Operand(esp, 0 * kPointerSize), eax); 2206 __ mov(Operand(esp, 0 * kPointerSize), eax);
2207 2207
2208 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains 2208 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
2209 // duplicate of return address and will be overwritten. 2209 // duplicate of return address and will be overwritten.
2210 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); 2210 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc);
2211 if (result->IsFailure()) return result; 2211 if (result->IsFailure()) return result;
2212 2212
2213 __ bind(&miss); 2213 __ bind(&miss);
2214 __ add(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); 2214 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize));
2215 2215
2216 __ bind(&miss_before_stack_reserved); 2216 __ bind(&miss_before_stack_reserved);
2217 MaybeObject* maybe_result = GenerateMissBranch(); 2217 MaybeObject* maybe_result = GenerateMissBranch();
2218 if (maybe_result->IsFailure()) return maybe_result; 2218 if (maybe_result->IsFailure()) return maybe_result;
2219 2219
2220 // Return the generated code. 2220 // Return the generated code.
2221 return GetCode(function); 2221 return GetCode(function);
2222 } 2222 }
2223 2223
2224 2224
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
2704 // -- ecx : key 2704 // -- ecx : key
2705 // -- edx : receiver 2705 // -- edx : receiver
2706 // -- esp[0] : return address 2706 // -- esp[0] : return address
2707 // ----------------------------------- 2707 // -----------------------------------
2708 Label miss; 2708 Label miss;
2709 2709
2710 Counters* counters = isolate()->counters(); 2710 Counters* counters = isolate()->counters();
2711 __ IncrementCounter(counters->keyed_store_field(), 1); 2711 __ IncrementCounter(counters->keyed_store_field(), 1);
2712 2712
2713 // Check that the name has not changed. 2713 // Check that the name has not changed.
2714 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); 2714 __ cmp(ecx, Immediate(Handle<String>(name)));
2715 __ j(not_equal, &miss); 2715 __ j(not_equal, &miss);
2716 2716
2717 // Generate store field code. Trashes the name register. 2717 // Generate store field code. Trashes the name register.
2718 GenerateStoreField(masm(), 2718 GenerateStoreField(masm(),
2719 object, 2719 object,
2720 index, 2720 index,
2721 transition, 2721 transition,
2722 edx, ecx, ebx, 2722 edx, ecx, ebx,
2723 &miss); 2723 &miss);
2724 2724
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
2996 // -- eax : key 2996 // -- eax : key
2997 // -- edx : receiver 2997 // -- edx : receiver
2998 // -- esp[0] : return address 2998 // -- esp[0] : return address
2999 // ----------------------------------- 2999 // -----------------------------------
3000 Label miss; 3000 Label miss;
3001 3001
3002 Counters* counters = isolate()->counters(); 3002 Counters* counters = isolate()->counters();
3003 __ IncrementCounter(counters->keyed_load_field(), 1); 3003 __ IncrementCounter(counters->keyed_load_field(), 1);
3004 3004
3005 // Check that the name has not changed. 3005 // Check that the name has not changed.
3006 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3006 __ cmp(eax, Immediate(Handle<String>(name)));
3007 __ j(not_equal, &miss); 3007 __ j(not_equal, &miss);
3008 3008
3009 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); 3009 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss);
3010 3010
3011 __ bind(&miss); 3011 __ bind(&miss);
3012 __ DecrementCounter(counters->keyed_load_field(), 1); 3012 __ DecrementCounter(counters->keyed_load_field(), 1);
3013 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3013 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3014 3014
3015 // Return the generated code. 3015 // Return the generated code.
3016 return GetCode(FIELD, name); 3016 return GetCode(FIELD, name);
3017 } 3017 }
3018 3018
3019 3019
3020 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( 3020 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback(
3021 String* name, 3021 String* name,
3022 JSObject* receiver, 3022 JSObject* receiver,
3023 JSObject* holder, 3023 JSObject* holder,
3024 AccessorInfo* callback) { 3024 AccessorInfo* callback) {
3025 // ----------- S t a t e ------------- 3025 // ----------- S t a t e -------------
3026 // -- eax : key 3026 // -- eax : key
3027 // -- edx : receiver 3027 // -- edx : receiver
3028 // -- esp[0] : return address 3028 // -- esp[0] : return address
3029 // ----------------------------------- 3029 // -----------------------------------
3030 Label miss; 3030 Label miss;
3031 3031
3032 Counters* counters = isolate()->counters(); 3032 Counters* counters = isolate()->counters();
3033 __ IncrementCounter(counters->keyed_load_callback(), 1); 3033 __ IncrementCounter(counters->keyed_load_callback(), 1);
3034 3034
3035 // Check that the name has not changed. 3035 // Check that the name has not changed.
3036 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3036 __ cmp(eax, Immediate(Handle<String>(name)));
3037 __ j(not_equal, &miss); 3037 __ j(not_equal, &miss);
3038 3038
3039 MaybeObject* result = GenerateLoadCallback(receiver, holder, edx, eax, ebx, 3039 MaybeObject* result = GenerateLoadCallback(receiver, holder, edx, eax, ebx,
3040 ecx, edi, callback, name, &miss); 3040 ecx, edi, callback, name, &miss);
3041 if (result->IsFailure()) { 3041 if (result->IsFailure()) {
3042 miss.Unuse(); 3042 miss.Unuse();
3043 return result; 3043 return result;
3044 } 3044 }
3045 3045
3046 __ bind(&miss); 3046 __ bind(&miss);
(...skipping 14 matching lines...) Expand all
3061 // -- eax : key 3061 // -- eax : key
3062 // -- edx : receiver 3062 // -- edx : receiver
3063 // -- esp[0] : return address 3063 // -- esp[0] : return address
3064 // ----------------------------------- 3064 // -----------------------------------
3065 Label miss; 3065 Label miss;
3066 3066
3067 Counters* counters = isolate()->counters(); 3067 Counters* counters = isolate()->counters();
3068 __ IncrementCounter(counters->keyed_load_constant_function(), 1); 3068 __ IncrementCounter(counters->keyed_load_constant_function(), 1);
3069 3069
3070 // Check that the name has not changed. 3070 // Check that the name has not changed.
3071 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3071 __ cmp(eax, Immediate(Handle<String>(name)));
3072 __ j(not_equal, &miss); 3072 __ j(not_equal, &miss);
3073 3073
3074 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi, 3074 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi,
3075 value, name, &miss); 3075 value, name, &miss);
3076 __ bind(&miss); 3076 __ bind(&miss);
3077 __ DecrementCounter(counters->keyed_load_constant_function(), 1); 3077 __ DecrementCounter(counters->keyed_load_constant_function(), 1);
3078 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3078 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3079 3079
3080 // Return the generated code. 3080 // Return the generated code.
3081 return GetCode(CONSTANT_FUNCTION, name); 3081 return GetCode(CONSTANT_FUNCTION, name);
3082 } 3082 }
3083 3083
3084 3084
3085 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, 3085 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
3086 JSObject* holder, 3086 JSObject* holder,
3087 String* name) { 3087 String* name) {
3088 // ----------- S t a t e ------------- 3088 // ----------- S t a t e -------------
3089 // -- eax : key 3089 // -- eax : key
3090 // -- edx : receiver 3090 // -- edx : receiver
3091 // -- esp[0] : return address 3091 // -- esp[0] : return address
3092 // ----------------------------------- 3092 // -----------------------------------
3093 Label miss; 3093 Label miss;
3094 3094
3095 Counters* counters = isolate()->counters(); 3095 Counters* counters = isolate()->counters();
3096 __ IncrementCounter(counters->keyed_load_interceptor(), 1); 3096 __ IncrementCounter(counters->keyed_load_interceptor(), 1);
3097 3097
3098 // Check that the name has not changed. 3098 // Check that the name has not changed.
3099 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3099 __ cmp(eax, Immediate(Handle<String>(name)));
3100 __ j(not_equal, &miss); 3100 __ j(not_equal, &miss);
3101 3101
3102 LookupResult lookup; 3102 LookupResult lookup;
3103 LookupPostInterceptor(holder, name, &lookup); 3103 LookupPostInterceptor(holder, name, &lookup);
3104 GenerateLoadInterceptor(receiver, 3104 GenerateLoadInterceptor(receiver,
3105 holder, 3105 holder,
3106 &lookup, 3106 &lookup,
3107 edx, 3107 edx,
3108 eax, 3108 eax,
3109 ecx, 3109 ecx,
(...skipping 15 matching lines...) Expand all
3125 // -- eax : key 3125 // -- eax : key
3126 // -- edx : receiver 3126 // -- edx : receiver
3127 // -- esp[0] : return address 3127 // -- esp[0] : return address
3128 // ----------------------------------- 3128 // -----------------------------------
3129 Label miss; 3129 Label miss;
3130 3130
3131 Counters* counters = isolate()->counters(); 3131 Counters* counters = isolate()->counters();
3132 __ IncrementCounter(counters->keyed_load_array_length(), 1); 3132 __ IncrementCounter(counters->keyed_load_array_length(), 1);
3133 3133
3134 // Check that the name has not changed. 3134 // Check that the name has not changed.
3135 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3135 __ cmp(eax, Immediate(Handle<String>(name)));
3136 __ j(not_equal, &miss); 3136 __ j(not_equal, &miss);
3137 3137
3138 GenerateLoadArrayLength(masm(), edx, ecx, &miss); 3138 GenerateLoadArrayLength(masm(), edx, ecx, &miss);
3139 __ bind(&miss); 3139 __ bind(&miss);
3140 __ DecrementCounter(counters->keyed_load_array_length(), 1); 3140 __ DecrementCounter(counters->keyed_load_array_length(), 1);
3141 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3141 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3142 3142
3143 // Return the generated code. 3143 // Return the generated code.
3144 return GetCode(CALLBACKS, name); 3144 return GetCode(CALLBACKS, name);
3145 } 3145 }
3146 3146
3147 3147
3148 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { 3148 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
3149 // ----------- S t a t e ------------- 3149 // ----------- S t a t e -------------
3150 // -- eax : key 3150 // -- eax : key
3151 // -- edx : receiver 3151 // -- edx : receiver
3152 // -- esp[0] : return address 3152 // -- esp[0] : return address
3153 // ----------------------------------- 3153 // -----------------------------------
3154 Label miss; 3154 Label miss;
3155 3155
3156 Counters* counters = isolate()->counters(); 3156 Counters* counters = isolate()->counters();
3157 __ IncrementCounter(counters->keyed_load_string_length(), 1); 3157 __ IncrementCounter(counters->keyed_load_string_length(), 1);
3158 3158
3159 // Check that the name has not changed. 3159 // Check that the name has not changed.
3160 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3160 __ cmp(eax, Immediate(Handle<String>(name)));
3161 __ j(not_equal, &miss); 3161 __ j(not_equal, &miss);
3162 3162
3163 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); 3163 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true);
3164 __ bind(&miss); 3164 __ bind(&miss);
3165 __ DecrementCounter(counters->keyed_load_string_length(), 1); 3165 __ DecrementCounter(counters->keyed_load_string_length(), 1);
3166 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3166 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3167 3167
3168 // Return the generated code. 3168 // Return the generated code.
3169 return GetCode(CALLBACKS, name); 3169 return GetCode(CALLBACKS, name);
3170 } 3170 }
3171 3171
3172 3172
3173 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { 3173 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) {
3174 // ----------- S t a t e ------------- 3174 // ----------- S t a t e -------------
3175 // -- eax : key 3175 // -- eax : key
3176 // -- edx : receiver 3176 // -- edx : receiver
3177 // -- esp[0] : return address 3177 // -- esp[0] : return address
3178 // ----------------------------------- 3178 // -----------------------------------
3179 Label miss; 3179 Label miss;
3180 3180
3181 Counters* counters = isolate()->counters(); 3181 Counters* counters = isolate()->counters();
3182 __ IncrementCounter(counters->keyed_load_function_prototype(), 1); 3182 __ IncrementCounter(counters->keyed_load_function_prototype(), 1);
3183 3183
3184 // Check that the name has not changed. 3184 // Check that the name has not changed.
3185 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3185 __ cmp(eax, Immediate(Handle<String>(name)));
3186 __ j(not_equal, &miss); 3186 __ j(not_equal, &miss);
3187 3187
3188 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); 3188 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss);
3189 __ bind(&miss); 3189 __ bind(&miss);
3190 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); 3190 __ DecrementCounter(counters->keyed_load_function_prototype(), 1);
3191 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3191 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3192 3192
3193 // Return the generated code. 3193 // Return the generated code.
3194 return GetCode(CALLBACKS, name); 3194 return GetCode(CALLBACKS, name);
3195 } 3195 }
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
3353 ASSERT(function->has_initial_map()); 3353 ASSERT(function->has_initial_map());
3354 for (int i = shared->this_property_assignments_count(); 3354 for (int i = shared->this_property_assignments_count();
3355 i < function->initial_map()->inobject_properties(); 3355 i < function->initial_map()->inobject_properties();
3356 i++) { 3356 i++) {
3357 __ mov(Operand(edx, i * kPointerSize), edi); 3357 __ mov(Operand(edx, i * kPointerSize), edi);
3358 } 3358 }
3359 3359
3360 // Move argc to ebx and retrieve and tag the JSObject to return. 3360 // Move argc to ebx and retrieve and tag the JSObject to return.
3361 __ mov(ebx, eax); 3361 __ mov(ebx, eax);
3362 __ pop(eax); 3362 __ pop(eax);
3363 __ or_(Operand(eax), Immediate(kHeapObjectTag)); 3363 __ or_(eax, Immediate(kHeapObjectTag));
3364 3364
3365 // Remove caller arguments and receiver from the stack and return. 3365 // Remove caller arguments and receiver from the stack and return.
3366 __ pop(ecx); 3366 __ pop(ecx);
3367 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize)); 3367 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize));
3368 __ push(ecx); 3368 __ push(ecx);
3369 Counters* counters = isolate()->counters(); 3369 Counters* counters = isolate()->counters();
3370 __ IncrementCounter(counters->constructed_objects(), 1); 3370 __ IncrementCounter(counters->constructed_objects(), 1);
3371 __ IncrementCounter(counters->constructed_objects_stub(), 1); 3371 __ IncrementCounter(counters->constructed_objects_stub(), 1);
3372 __ ret(0); 3372 __ ret(0);
3373 3373
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
3734 } 3734 }
3735 } else { 3735 } else {
3736 if (CpuFeatures::IsSupported(SSE3)) { 3736 if (CpuFeatures::IsSupported(SSE3)) {
3737 CpuFeatures::Scope scope(SSE3); 3737 CpuFeatures::Scope scope(SSE3);
3738 // fisttp stores values as signed integers. To represent the 3738 // fisttp stores values as signed integers. To represent the
3739 // entire range of int and unsigned int arrays, store as a 3739 // entire range of int and unsigned int arrays, store as a
3740 // 64-bit int and discard the high 32 bits. 3740 // 64-bit int and discard the high 32 bits.
3741 // If the value is NaN or +/-infinity, the result is 0x80000000, 3741 // If the value is NaN or +/-infinity, the result is 0x80000000,
3742 // which is automatically zero when taken mod 2^n, n < 32. 3742 // which is automatically zero when taken mod 2^n, n < 32.
3743 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3743 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3744 __ sub(Operand(esp), Immediate(2 * kPointerSize)); 3744 __ sub(esp, Immediate(2 * kPointerSize));
3745 __ fisttp_d(Operand(esp, 0)); 3745 __ fisttp_d(Operand(esp, 0));
3746 __ pop(ebx); 3746 __ pop(ebx);
3747 __ add(Operand(esp), Immediate(kPointerSize)); 3747 __ add(esp, Immediate(kPointerSize));
3748 } else { 3748 } else {
3749 ASSERT(CpuFeatures::IsSupported(SSE2)); 3749 ASSERT(CpuFeatures::IsSupported(SSE2));
3750 CpuFeatures::Scope scope(SSE2); 3750 CpuFeatures::Scope scope(SSE2);
3751 // We can easily implement the correct rounding behavior for the 3751 // We can easily implement the correct rounding behavior for the
3752 // range [0, 2^31-1]. For the time being, to keep this code simple, 3752 // range [0, 2^31-1]. For the time being, to keep this code simple,
3753 // make the slow runtime call for values outside this range. 3753 // make the slow runtime call for values outside this range.
3754 // Note: we could do better for signed int arrays. 3754 // Note: we could do better for signed int arrays.
3755 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); 3755 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
3756 // We will need the key if we have to make the slow runtime call. 3756 // We will need the key if we have to make the slow runtime call.
3757 __ push(ebx); 3757 __ push(ebx);
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
3946 ASSERT(elements_kind == FAST_ELEMENTS); 3946 ASSERT(elements_kind == FAST_ELEMENTS);
3947 // Do the store and update the write barrier. 3947 // Do the store and update the write barrier.
3948 // ecx is a smi, use times_half_pointer_size instead of 3948 // ecx is a smi, use times_half_pointer_size instead of
3949 // times_pointer_size 3949 // times_pointer_size
3950 __ lea(ecx, FieldOperand(edi, 3950 __ lea(ecx, FieldOperand(edi,
3951 ecx, 3951 ecx,
3952 times_half_pointer_size, 3952 times_half_pointer_size,
3953 FixedArray::kHeaderSize)); 3953 FixedArray::kHeaderSize));
3954 __ mov(Operand(ecx, 0), eax); 3954 __ mov(Operand(ecx, 0), eax);
3955 // Make sure to preserve the value in register eax. 3955 // Make sure to preserve the value in register eax.
3956 __ mov(edx, Operand(eax)); 3956 __ mov(edx, eax);
3957 __ RecordWrite(edi, ecx, edx, kDontSaveFPRegs); 3957 __ RecordWrite(edi, ecx, edx, kDontSaveFPRegs);
3958 } 3958 }
3959 3959
3960 // Done. 3960 // Done.
3961 __ ret(0); 3961 __ ret(0);
3962 3962
3963 // Handle store cache miss, replacing the ic with the generic stub. 3963 // Handle store cache miss, replacing the ic with the generic stub.
3964 __ bind(&miss_force_generic); 3964 __ bind(&miss_force_generic);
3965 Handle<Code> ic_force_generic = 3965 Handle<Code> ic_force_generic =
3966 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 3966 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
4013 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 4013 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
4014 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); 4014 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
4015 } 4015 }
4016 4016
4017 4017
4018 #undef __ 4018 #undef __
4019 4019
4020 } } // namespace v8::internal 4020 } } // namespace v8::internal
4021 4021
4022 #endif // V8_TARGET_ARCH_IA32 4022 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698