| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 Handle<JSObject> holder_obj) { | 399 Handle<JSObject> holder_obj) { |
| 400 __ push(name); | 400 __ push(name); |
| 401 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); | 401 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); |
| 402 ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); | 402 ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); |
| 403 Register scratch = name; | 403 Register scratch = name; |
| 404 __ mov(scratch, Immediate(interceptor)); | 404 __ mov(scratch, Immediate(interceptor)); |
| 405 __ push(scratch); | 405 __ push(scratch); |
| 406 __ push(receiver); | 406 __ push(receiver); |
| 407 __ push(holder); | 407 __ push(holder); |
| 408 __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset)); | 408 __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset)); |
| 409 __ push(Immediate(reinterpret_cast<int>(masm->isolate()))); |
| 409 } | 410 } |
| 410 | 411 |
| 411 | 412 |
| 412 static void CompileCallLoadPropertyWithInterceptor( | 413 static void CompileCallLoadPropertyWithInterceptor( |
| 413 MacroAssembler* masm, | 414 MacroAssembler* masm, |
| 414 Register receiver, | 415 Register receiver, |
| 415 Register holder, | 416 Register holder, |
| 416 Register name, | 417 Register name, |
| 417 Handle<JSObject> holder_obj) { | 418 Handle<JSObject> holder_obj) { |
| 418 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); | 419 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); |
| 419 __ CallExternalReference( | 420 __ CallExternalReference( |
| 420 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), | 421 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), |
| 421 masm->isolate()), | 422 masm->isolate()), |
| 422 5); | 423 6); |
| 423 } | 424 } |
| 424 | 425 |
| 425 | 426 |
| 426 // Number of pointers to be reserved on stack for fast API call. | 427 // Number of pointers to be reserved on stack for fast API call. |
| 427 static const int kFastApiCallArguments = 3; | 428 static const int kFastApiCallArguments = 4; |
| 428 | 429 |
| 429 | 430 |
| 430 // Reserves space for the extra arguments to API function in the | 431 // Reserves space for the extra arguments to API function in the |
| 431 // caller's frame. | 432 // caller's frame. |
| 432 // | 433 // |
| 433 // These arguments are set by CheckPrototypes and GenerateFastApiCall. | 434 // These arguments are set by CheckPrototypes and GenerateFastApiCall. |
| 434 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { | 435 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { |
| 435 // ----------- S t a t e ------------- | 436 // ----------- S t a t e ------------- |
| 436 // -- esp[0] : return address | 437 // -- esp[0] : return address |
| 437 // -- esp[4] : last argument in the internal frame of the caller | 438 // -- esp[4] : last argument in the internal frame of the caller |
| (...skipping 27 matching lines...) Expand all Loading... |
| 465 const CallOptimization& optimization, | 466 const CallOptimization& optimization, |
| 466 int argc) { | 467 int argc) { |
| 467 // ----------- S t a t e ------------- | 468 // ----------- S t a t e ------------- |
| 468 // -- esp[0] : return address | 469 // -- esp[0] : return address |
| 469 // -- esp[4] : object passing the type check | 470 // -- esp[4] : object passing the type check |
| 470 // (last fast api call extra argument, | 471 // (last fast api call extra argument, |
| 471 // set by CheckPrototypes) | 472 // set by CheckPrototypes) |
| 472 // -- esp[8] : api function | 473 // -- esp[8] : api function |
| 473 // (first fast api call extra argument) | 474 // (first fast api call extra argument) |
| 474 // -- esp[12] : api call data | 475 // -- esp[12] : api call data |
| 475 // -- esp[16] : last argument | 476 // -- esp[16] : isolate |
| 477 // -- esp[20] : last argument |
| 476 // -- ... | 478 // -- ... |
| 477 // -- esp[(argc + 3) * 4] : first argument | 479 // -- esp[(argc + 4) * 4] : first argument |
| 478 // -- esp[(argc + 4) * 4] : receiver | 480 // -- esp[(argc + 5) * 4] : receiver |
| 479 // ----------------------------------- | 481 // ----------------------------------- |
| 480 // Get the function and setup the context. | 482 // Get the function and setup the context. |
| 481 Handle<JSFunction> function = optimization.constant_function(); | 483 Handle<JSFunction> function = optimization.constant_function(); |
| 482 __ LoadHeapObject(edi, function); | 484 __ LoadHeapObject(edi, function); |
| 483 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 485 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
| 484 | 486 |
| 485 // Pass the additional arguments. | 487 // Pass the additional arguments. |
| 486 __ mov(Operand(esp, 2 * kPointerSize), edi); | 488 __ mov(Operand(esp, 2 * kPointerSize), edi); |
| 487 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); | 489 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
| 488 Handle<Object> call_data(api_call_info->data()); | 490 Handle<Object> call_data(api_call_info->data()); |
| 489 if (masm->isolate()->heap()->InNewSpace(*call_data)) { | 491 if (masm->isolate()->heap()->InNewSpace(*call_data)) { |
| 490 __ mov(ecx, api_call_info); | 492 __ mov(ecx, api_call_info); |
| 491 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); | 493 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); |
| 492 __ mov(Operand(esp, 3 * kPointerSize), ebx); | 494 __ mov(Operand(esp, 3 * kPointerSize), ebx); |
| 493 } else { | 495 } else { |
| 494 __ mov(Operand(esp, 3 * kPointerSize), Immediate(call_data)); | 496 __ mov(Operand(esp, 3 * kPointerSize), Immediate(call_data)); |
| 495 } | 497 } |
| 498 __ mov(Operand(esp, 4 * kPointerSize), |
| 499 Immediate(reinterpret_cast<int>(masm->isolate()))); |
| 496 | 500 |
| 497 // Prepare arguments. | 501 // Prepare arguments. |
| 498 __ lea(eax, Operand(esp, 3 * kPointerSize)); | 502 __ lea(eax, Operand(esp, 4 * kPointerSize)); |
| 499 | 503 |
| 500 const int kApiArgc = 1; // API function gets reference to the v8::Arguments. | 504 const int kApiArgc = 1; // API function gets reference to the v8::Arguments. |
| 501 | 505 |
| 502 // Allocate the v8::Arguments structure in the arguments' space since | 506 // Allocate the v8::Arguments structure in the arguments' space since |
| 503 // it's not controlled by GC. | 507 // it's not controlled by GC. |
| 504 const int kApiStackSpace = 4; | 508 const int kApiStackSpace = 4; |
| 505 | 509 |
| 506 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace); | 510 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace); |
| 507 | 511 |
| 508 __ mov(ApiParameterOperand(1), eax); // v8::Arguments::implicit_args_. | 512 __ mov(ApiParameterOperand(1), eax); // v8::Arguments::implicit_args_. |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 | 676 |
| 673 FrameScope scope(masm, StackFrame::INTERNAL); | 677 FrameScope scope(masm, StackFrame::INTERNAL); |
| 674 // Save the name_ register across the call. | 678 // Save the name_ register across the call. |
| 675 __ push(name_); | 679 __ push(name_); |
| 676 | 680 |
| 677 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); | 681 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); |
| 678 | 682 |
| 679 __ CallExternalReference( | 683 __ CallExternalReference( |
| 680 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), | 684 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), |
| 681 masm->isolate()), | 685 masm->isolate()), |
| 682 5); | 686 6); |
| 683 | 687 |
| 684 // Restore the name_ register. | 688 // Restore the name_ register. |
| 685 __ pop(name_); | 689 __ pop(name_); |
| 686 | 690 |
| 687 // Leave the internal frame. | 691 // Leave the internal frame. |
| 688 } | 692 } |
| 689 | 693 |
| 690 void LoadWithInterceptor(MacroAssembler* masm, | 694 void LoadWithInterceptor(MacroAssembler* masm, |
| 691 Register receiver, | 695 Register receiver, |
| 692 Register holder, | 696 Register holder, |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1025 __ mov(scratch2, esp); | 1029 __ mov(scratch2, esp); |
| 1026 ASSERT(!scratch2.is(reg)); | 1030 ASSERT(!scratch2.is(reg)); |
| 1027 __ push(reg); // holder | 1031 __ push(reg); // holder |
| 1028 // Push data from AccessorInfo. | 1032 // Push data from AccessorInfo. |
| 1029 if (isolate()->heap()->InNewSpace(callback->data())) { | 1033 if (isolate()->heap()->InNewSpace(callback->data())) { |
| 1030 __ mov(scratch1, Immediate(callback)); | 1034 __ mov(scratch1, Immediate(callback)); |
| 1031 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset)); | 1035 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset)); |
| 1032 } else { | 1036 } else { |
| 1033 __ push(Immediate(Handle<Object>(callback->data()))); | 1037 __ push(Immediate(Handle<Object>(callback->data()))); |
| 1034 } | 1038 } |
| 1039 __ push(Immediate(reinterpret_cast<int>(isolate()))); |
| 1035 | 1040 |
| 1036 // Save a pointer to where we pushed the arguments pointer. | 1041 // Save a pointer to where we pushed the arguments pointer. |
| 1037 // This will be passed as the const AccessorInfo& to the C++ callback. | 1042 // This will be passed as the const AccessorInfo& to the C++ callback. |
| 1038 __ push(scratch2); | 1043 __ push(scratch2); |
| 1039 | 1044 |
| 1040 __ push(name_reg); // name | 1045 __ push(name_reg); // name |
| 1041 __ mov(ebx, esp); // esp points to reference to name (handler). | 1046 __ mov(ebx, esp); // esp points to reference to name (handler). |
| 1042 | 1047 |
| 1043 __ push(scratch3); // Restore return address. | 1048 __ push(scratch3); // Restore return address. |
| 1044 | 1049 |
| 1045 // 3 elements array for v8::Arguments::values_, handler for name and pointer | 1050 // 4 elements array for v8::Arguments::values_, handler for name and pointer |
| 1046 // to the values (it considered as smi in GC). | 1051 // to the values (it considered as smi in GC). |
| 1047 const int kStackSpace = 5; | 1052 const int kStackSpace = 6; |
| 1048 const int kApiArgc = 2; | 1053 const int kApiArgc = 2; |
| 1049 | 1054 |
| 1050 __ PrepareCallApiFunction(kApiArgc); | 1055 __ PrepareCallApiFunction(kApiArgc); |
| 1051 __ mov(ApiParameterOperand(0), ebx); // name. | 1056 __ mov(ApiParameterOperand(0), ebx); // name. |
| 1052 __ add(ebx, Immediate(kPointerSize)); | 1057 __ add(ebx, Immediate(kPointerSize)); |
| 1053 __ mov(ApiParameterOperand(1), ebx); // arguments pointer. | 1058 __ mov(ApiParameterOperand(1), ebx); // arguments pointer. |
| 1054 | 1059 |
| 1055 // Emitting a stub call may try to allocate (if the code is not | 1060 // Emitting a stub call may try to allocate (if the code is not |
| 1056 // already generated). Do not allow the assembler to perform a | 1061 // already generated). Do not allow the assembler to perform a |
| 1057 // garbage collection but instead return the allocation failure | 1062 // garbage collection but instead return the allocation failure |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1190 ASSERT(callback->getter() != NULL); | 1195 ASSERT(callback->getter() != NULL); |
| 1191 | 1196 |
| 1192 // Tail call to runtime. | 1197 // Tail call to runtime. |
| 1193 // Important invariant in CALLBACKS case: the code above must be | 1198 // Important invariant in CALLBACKS case: the code above must be |
| 1194 // structured to never clobber |receiver| register. | 1199 // structured to never clobber |receiver| register. |
| 1195 __ pop(scratch2); // return address | 1200 __ pop(scratch2); // return address |
| 1196 __ push(receiver); | 1201 __ push(receiver); |
| 1197 __ push(holder_reg); | 1202 __ push(holder_reg); |
| 1198 __ mov(holder_reg, Immediate(callback)); | 1203 __ mov(holder_reg, Immediate(callback)); |
| 1199 __ push(FieldOperand(holder_reg, AccessorInfo::kDataOffset)); | 1204 __ push(FieldOperand(holder_reg, AccessorInfo::kDataOffset)); |
| 1205 __ push(Immediate(reinterpret_cast<int>(isolate()))); |
| 1200 __ push(holder_reg); | 1206 __ push(holder_reg); |
| 1201 __ push(name_reg); | 1207 __ push(name_reg); |
| 1202 __ push(scratch2); // restore return address | 1208 __ push(scratch2); // restore return address |
| 1203 | 1209 |
| 1204 ExternalReference ref = | 1210 ExternalReference ref = |
| 1205 ExternalReference(IC_Utility(IC::kLoadCallbackProperty), | 1211 ExternalReference(IC_Utility(IC::kLoadCallbackProperty), |
| 1206 masm()->isolate()); | 1212 masm()->isolate()); |
| 1207 __ TailCallExternalReference(ref, 5, 1); | 1213 __ TailCallExternalReference(ref, 6, 1); |
| 1208 } | 1214 } |
| 1209 } else { // !compile_followup_inline | 1215 } else { // !compile_followup_inline |
| 1210 // Call the runtime system to load the interceptor. | 1216 // Call the runtime system to load the interceptor. |
| 1211 // Check that the maps haven't changed. | 1217 // Check that the maps haven't changed. |
| 1212 Register holder_reg = | 1218 Register holder_reg = |
| 1213 CheckPrototypes(object, receiver, interceptor_holder, | 1219 CheckPrototypes(object, receiver, interceptor_holder, |
| 1214 scratch1, scratch2, scratch3, name, miss); | 1220 scratch1, scratch2, scratch3, name, miss); |
| 1215 __ pop(scratch2); // save old return address | 1221 __ pop(scratch2); // save old return address |
| 1216 PushInterceptorArguments(masm(), receiver, holder_reg, | 1222 PushInterceptorArguments(masm(), receiver, holder_reg, |
| 1217 name_reg, interceptor_holder); | 1223 name_reg, interceptor_holder); |
| 1218 __ push(scratch2); // restore old return address | 1224 __ push(scratch2); // restore old return address |
| 1219 | 1225 |
| 1220 ExternalReference ref = | 1226 ExternalReference ref = |
| 1221 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), | 1227 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), |
| 1222 isolate()); | 1228 isolate()); |
| 1223 __ TailCallExternalReference(ref, 5, 1); | 1229 __ TailCallExternalReference(ref, 6, 1); |
| 1224 } | 1230 } |
| 1225 } | 1231 } |
| 1226 | 1232 |
| 1227 | 1233 |
| 1228 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { | 1234 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { |
| 1229 if (kind_ == Code::KEYED_CALL_IC) { | 1235 if (kind_ == Code::KEYED_CALL_IC) { |
| 1230 __ cmp(ecx, Immediate(name)); | 1236 __ cmp(ecx, Immediate(name)); |
| 1231 __ j(not_equal, miss); | 1237 __ j(not_equal, miss); |
| 1232 } | 1238 } |
| 1233 } | 1239 } |
| (...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2151 | 2157 |
| 2152 // Allocate space for v8::Arguments implicit values. Must be initialized | 2158 // Allocate space for v8::Arguments implicit values. Must be initialized |
| 2153 // before calling any runtime function. | 2159 // before calling any runtime function. |
| 2154 __ sub(esp, Immediate(kFastApiCallArguments * kPointerSize)); | 2160 __ sub(esp, Immediate(kFastApiCallArguments * kPointerSize)); |
| 2155 | 2161 |
| 2156 // Check that the maps haven't changed and find a Holder as a side effect. | 2162 // Check that the maps haven't changed and find a Holder as a side effect. |
| 2157 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, | 2163 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, |
| 2158 name, depth, &miss); | 2164 name, depth, &miss); |
| 2159 | 2165 |
| 2160 // Move the return address on top of the stack. | 2166 // Move the return address on top of the stack. |
| 2161 __ mov(eax, Operand(esp, 3 * kPointerSize)); | 2167 __ mov(eax, Operand(esp, 4 * kPointerSize)); |
| 2162 __ mov(Operand(esp, 0 * kPointerSize), eax); | 2168 __ mov(Operand(esp, 0 * kPointerSize), eax); |
| 2163 | 2169 |
| 2164 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains | 2170 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains |
| 2165 // duplicate of return address and will be overwritten. | 2171 // duplicate of return address and will be overwritten. |
| 2166 GenerateFastApiCall(masm(), optimization, argc); | 2172 GenerateFastApiCall(masm(), optimization, argc); |
| 2167 | 2173 |
| 2168 __ bind(&miss); | 2174 __ bind(&miss); |
| 2169 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); | 2175 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); |
| 2170 | 2176 |
| 2171 __ bind(&miss_before_stack_reserved); | 2177 __ bind(&miss_before_stack_reserved); |
| (...skipping 1898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4070 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | 4076 __ jmp(ic_slow, RelocInfo::CODE_TARGET); |
| 4071 } | 4077 } |
| 4072 } | 4078 } |
| 4073 | 4079 |
| 4074 | 4080 |
| 4075 #undef __ | 4081 #undef __ |
| 4076 | 4082 |
| 4077 } } // namespace v8::internal | 4083 } } // namespace v8::internal |
| 4078 | 4084 |
| 4079 #endif // V8_TARGET_ARCH_IA32 | 4085 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |