OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 Register prototype) { | 268 Register prototype) { |
269 __ LoadGlobalFunction(index, prototype); | 269 __ LoadGlobalFunction(index, prototype); |
270 __ LoadGlobalFunctionInitialMap(prototype, prototype); | 270 __ LoadGlobalFunctionInitialMap(prototype, prototype); |
271 // Load the prototype from the initial map. | 271 // Load the prototype from the initial map. |
272 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); | 272 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); |
273 } | 273 } |
274 | 274 |
275 | 275 |
276 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( | 276 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( |
277 MacroAssembler* masm, int index, Register prototype, Label* miss) { | 277 MacroAssembler* masm, int index, Register prototype, Label* miss) { |
278 Isolate* isolate = masm->isolate(); | |
279 // Check we're still in the same context. | 278 // Check we're still in the same context. |
280 __ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)), | 279 __ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)), |
281 isolate->global()); | 280 masm->isolate()->global()); |
282 __ j(not_equal, miss); | 281 __ j(not_equal, miss); |
283 // Get the global function with the given index. | 282 // Get the global function with the given index. |
284 JSFunction* function = | 283 JSFunction* function = |
285 JSFunction::cast(isolate->global_context()->get(index)); | 284 JSFunction::cast(masm->isolate()->global_context()->get(index)); |
286 // Load its initial map. The global functions all have initial maps. | 285 // Load its initial map. The global functions all have initial maps. |
287 __ Set(prototype, Immediate(Handle<Map>(function->initial_map()))); | 286 __ Set(prototype, Immediate(Handle<Map>(function->initial_map()))); |
288 // Load the prototype from the initial map. | 287 // Load the prototype from the initial map. |
289 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); | 288 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); |
290 } | 289 } |
291 | 290 |
292 | 291 |
293 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, | 292 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, |
294 Register receiver, | 293 Register receiver, |
295 Register scratch, | 294 Register scratch, |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 } | 392 } |
394 | 393 |
395 | 394 |
396 static void PushInterceptorArguments(MacroAssembler* masm, | 395 static void PushInterceptorArguments(MacroAssembler* masm, |
397 Register receiver, | 396 Register receiver, |
398 Register holder, | 397 Register holder, |
399 Register name, | 398 Register name, |
400 JSObject* holder_obj) { | 399 JSObject* holder_obj) { |
401 __ push(name); | 400 __ push(name); |
402 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); | 401 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); |
403 ASSERT(!HEAP->InNewSpace(interceptor)); | 402 ASSERT(!masm->isolate()->heap()->InNewSpace(interceptor)); |
404 Register scratch = name; | 403 Register scratch = name; |
405 __ mov(scratch, Immediate(Handle<Object>(interceptor))); | 404 __ mov(scratch, Immediate(Handle<Object>(interceptor))); |
406 __ push(scratch); | 405 __ push(scratch); |
407 __ push(receiver); | 406 __ push(receiver); |
408 __ push(holder); | 407 __ push(holder); |
409 __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset)); | 408 __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset)); |
410 } | 409 } |
411 | 410 |
412 | 411 |
413 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, | 412 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 // ----------------------------------- | 478 // ----------------------------------- |
480 // Get the function and setup the context. | 479 // Get the function and setup the context. |
481 JSFunction* function = optimization.constant_function(); | 480 JSFunction* function = optimization.constant_function(); |
482 __ mov(edi, Immediate(Handle<JSFunction>(function))); | 481 __ mov(edi, Immediate(Handle<JSFunction>(function))); |
483 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 482 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
484 | 483 |
485 // Pass the additional arguments. | 484 // Pass the additional arguments. |
486 __ mov(Operand(esp, 2 * kPointerSize), edi); | 485 __ mov(Operand(esp, 2 * kPointerSize), edi); |
487 Object* call_data = optimization.api_call_info()->data(); | 486 Object* call_data = optimization.api_call_info()->data(); |
488 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info()); | 487 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info()); |
489 if (HEAP->InNewSpace(call_data)) { | 488 if (masm->isolate()->heap()->InNewSpace(call_data)) { |
490 __ mov(ecx, api_call_info_handle); | 489 __ mov(ecx, api_call_info_handle); |
491 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); | 490 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); |
492 __ mov(Operand(esp, 3 * kPointerSize), ebx); | 491 __ mov(Operand(esp, 3 * kPointerSize), ebx); |
493 } else { | 492 } else { |
494 __ mov(Operand(esp, 3 * kPointerSize), | 493 __ mov(Operand(esp, 3 * kPointerSize), |
495 Immediate(Handle<Object>(call_data))); | 494 Immediate(Handle<Object>(call_data))); |
496 } | 495 } |
497 | 496 |
498 // Prepare arguments. | 497 // Prepare arguments. |
499 __ lea(eax, Operand(esp, 3 * kPointerSize)); | 498 __ lea(eax, Operand(esp, 3 * kPointerSize)); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 } else { | 572 } else { |
574 CompileRegular(masm, | 573 CompileRegular(masm, |
575 object, | 574 object, |
576 receiver, | 575 receiver, |
577 scratch1, | 576 scratch1, |
578 scratch2, | 577 scratch2, |
579 scratch3, | 578 scratch3, |
580 name, | 579 name, |
581 holder, | 580 holder, |
582 miss); | 581 miss); |
583 return HEAP->undefined_value(); // Success. | 582 return masm->isolate()->heap()->undefined_value(); // Success. |
584 } | 583 } |
585 } | 584 } |
586 | 585 |
587 private: | 586 private: |
588 MaybeObject* CompileCacheable(MacroAssembler* masm, | 587 MaybeObject* CompileCacheable(MacroAssembler* masm, |
589 JSObject* object, | 588 JSObject* object, |
590 Register receiver, | 589 Register receiver, |
591 Register scratch1, | 590 Register scratch1, |
592 Register scratch2, | 591 Register scratch2, |
593 Register scratch3, | 592 Register scratch3, |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
672 FreeSpaceForFastApiCall(masm, scratch1); | 671 FreeSpaceForFastApiCall(masm, scratch1); |
673 __ jmp(miss_label); | 672 __ jmp(miss_label); |
674 } | 673 } |
675 | 674 |
676 // Invoke a regular function. | 675 // Invoke a regular function. |
677 __ bind(®ular_invoke); | 676 __ bind(®ular_invoke); |
678 if (can_do_fast_api_call) { | 677 if (can_do_fast_api_call) { |
679 FreeSpaceForFastApiCall(masm, scratch1); | 678 FreeSpaceForFastApiCall(masm, scratch1); |
680 } | 679 } |
681 | 680 |
682 return HEAP->undefined_value(); // Success. | 681 return masm->isolate()->heap()->undefined_value(); // Success. |
683 } | 682 } |
684 | 683 |
685 void CompileRegular(MacroAssembler* masm, | 684 void CompileRegular(MacroAssembler* masm, |
686 JSObject* object, | 685 JSObject* object, |
687 Register receiver, | 686 Register receiver, |
688 Register scratch1, | 687 Register scratch1, |
689 Register scratch2, | 688 Register scratch2, |
690 Register scratch3, | 689 Register scratch3, |
691 String* name, | 690 String* name, |
692 JSObject* interceptor_holder, | 691 JSObject* interceptor_holder, |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 Register holder_reg, | 908 Register holder_reg, |
910 Register scratch1, | 909 Register scratch1, |
911 Register scratch2, | 910 Register scratch2, |
912 String* name, | 911 String* name, |
913 int save_at_depth, | 912 int save_at_depth, |
914 Label* miss) { | 913 Label* miss) { |
915 // Make sure there's no overlap between holder and object registers. | 914 // Make sure there's no overlap between holder and object registers. |
916 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 915 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
917 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 916 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
918 && !scratch2.is(scratch1)); | 917 && !scratch2.is(scratch1)); |
| 918 |
| 919 Heap* heap = isolate()->heap(); |
| 920 |
919 // Keep track of the current object in register reg. | 921 // Keep track of the current object in register reg. |
920 Register reg = object_reg; | 922 Register reg = object_reg; |
921 JSObject* current = object; | 923 JSObject* current = object; |
922 int depth = 0; | 924 int depth = 0; |
923 | 925 |
924 if (save_at_depth == depth) { | 926 if (save_at_depth == depth) { |
925 __ mov(Operand(esp, kPointerSize), reg); | 927 __ mov(Operand(esp, kPointerSize), reg); |
926 } | 928 } |
927 | 929 |
928 // Traverse the prototype chain and check the maps in the prototype chain for | 930 // Traverse the prototype chain and check the maps in the prototype chain for |
929 // fast and global objects or do negative lookup for normal objects. | 931 // fast and global objects or do negative lookup for normal objects. |
930 while (current != holder) { | 932 while (current != holder) { |
931 depth++; | 933 depth++; |
932 | 934 |
933 // Only global objects and objects that do not require access | 935 // Only global objects and objects that do not require access |
934 // checks are allowed in stubs. | 936 // checks are allowed in stubs. |
935 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 937 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
936 | 938 |
937 ASSERT(current->GetPrototype()->IsJSObject()); | 939 ASSERT(current->GetPrototype()->IsJSObject()); |
938 JSObject* prototype = JSObject::cast(current->GetPrototype()); | 940 JSObject* prototype = JSObject::cast(current->GetPrototype()); |
939 if (!current->HasFastProperties() && | 941 if (!current->HasFastProperties() && |
940 !current->IsJSGlobalObject() && | 942 !current->IsJSGlobalObject() && |
941 !current->IsJSGlobalProxy()) { | 943 !current->IsJSGlobalProxy()) { |
942 if (!name->IsSymbol()) { | 944 if (!name->IsSymbol()) { |
943 MaybeObject* maybe_lookup_result = HEAP->LookupSymbol(name); | 945 MaybeObject* maybe_lookup_result = heap->LookupSymbol(name); |
944 Object* lookup_result = NULL; // Initialization to please compiler. | 946 Object* lookup_result = NULL; // Initialization to please compiler. |
945 if (!maybe_lookup_result->ToObject(&lookup_result)) { | 947 if (!maybe_lookup_result->ToObject(&lookup_result)) { |
946 set_failure(Failure::cast(maybe_lookup_result)); | 948 set_failure(Failure::cast(maybe_lookup_result)); |
947 return reg; | 949 return reg; |
948 } | 950 } |
949 name = String::cast(lookup_result); | 951 name = String::cast(lookup_result); |
950 } | 952 } |
951 ASSERT(current->property_dictionary()->FindEntry(name) == | 953 ASSERT(current->property_dictionary()->FindEntry(name) == |
952 StringDictionary::kNotFound); | 954 StringDictionary::kNotFound); |
953 | 955 |
954 GenerateDictionaryNegativeLookup(masm(), | 956 GenerateDictionaryNegativeLookup(masm(), |
955 miss, | 957 miss, |
956 reg, | 958 reg, |
957 name, | 959 name, |
958 scratch1, | 960 scratch1, |
959 scratch2); | 961 scratch2); |
960 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 962 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
961 reg = holder_reg; // from now the object is in holder_reg | 963 reg = holder_reg; // from now the object is in holder_reg |
962 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 964 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
963 } else if (HEAP->InNewSpace(prototype)) { | 965 } else if (heap->InNewSpace(prototype)) { |
964 // Get the map of the current object. | 966 // Get the map of the current object. |
965 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 967 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
966 __ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map()))); | 968 __ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map()))); |
967 // Branch on the result of the map check. | 969 // Branch on the result of the map check. |
968 __ j(not_equal, miss, not_taken); | 970 __ j(not_equal, miss, not_taken); |
969 // Check access rights to the global object. This has to happen | 971 // Check access rights to the global object. This has to happen |
970 // after the map check so that we know that the object is | 972 // after the map check so that we know that the object is |
971 // actually a global object. | 973 // actually a global object. |
972 if (current->IsJSGlobalProxy()) { | 974 if (current->IsJSGlobalProxy()) { |
973 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 975 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 | 1085 |
1084 // Insert additional parameters into the stack frame above return address. | 1086 // Insert additional parameters into the stack frame above return address. |
1085 ASSERT(!scratch3.is(reg)); | 1087 ASSERT(!scratch3.is(reg)); |
1086 __ pop(scratch3); // Get return address to place it below. | 1088 __ pop(scratch3); // Get return address to place it below. |
1087 | 1089 |
1088 __ push(receiver); // receiver | 1090 __ push(receiver); // receiver |
1089 __ mov(scratch2, Operand(esp)); | 1091 __ mov(scratch2, Operand(esp)); |
1090 ASSERT(!scratch2.is(reg)); | 1092 ASSERT(!scratch2.is(reg)); |
1091 __ push(reg); // holder | 1093 __ push(reg); // holder |
1092 // Push data from AccessorInfo. | 1094 // Push data from AccessorInfo. |
1093 if (HEAP->InNewSpace(callback_handle->data())) { | 1095 if (isolate()->heap()->InNewSpace(callback_handle->data())) { |
1094 __ mov(scratch1, Immediate(callback_handle)); | 1096 __ mov(scratch1, Immediate(callback_handle)); |
1095 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset)); | 1097 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset)); |
1096 } else { | 1098 } else { |
1097 __ push(Immediate(Handle<Object>(callback_handle->data()))); | 1099 __ push(Immediate(Handle<Object>(callback_handle->data()))); |
1098 } | 1100 } |
1099 | 1101 |
1100 // Save a pointer to where we pushed the arguments pointer. | 1102 // Save a pointer to where we pushed the arguments pointer. |
1101 // This will be passed as the const AccessorInfo& to the C++ callback. | 1103 // This will be passed as the const AccessorInfo& to the C++ callback. |
1102 __ push(scratch2); | 1104 __ push(scratch2); |
1103 | 1105 |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1279 Register holder_reg = | 1281 Register holder_reg = |
1280 CheckPrototypes(object, receiver, interceptor_holder, | 1282 CheckPrototypes(object, receiver, interceptor_holder, |
1281 scratch1, scratch2, scratch3, name, miss); | 1283 scratch1, scratch2, scratch3, name, miss); |
1282 __ pop(scratch2); // save old return address | 1284 __ pop(scratch2); // save old return address |
1283 PushInterceptorArguments(masm(), receiver, holder_reg, | 1285 PushInterceptorArguments(masm(), receiver, holder_reg, |
1284 name_reg, interceptor_holder); | 1286 name_reg, interceptor_holder); |
1285 __ push(scratch2); // restore old return address | 1287 __ push(scratch2); // restore old return address |
1286 | 1288 |
1287 ExternalReference ref = | 1289 ExternalReference ref = |
1288 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), | 1290 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), |
1289 masm()->isolate()); | 1291 isolate()); |
1290 __ TailCallExternalReference(ref, 5, 1); | 1292 __ TailCallExternalReference(ref, 5, 1); |
1291 } | 1293 } |
1292 } | 1294 } |
1293 | 1295 |
1294 | 1296 |
1295 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { | 1297 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { |
1296 if (kind_ == Code::KEYED_CALL_IC) { | 1298 if (kind_ == Code::KEYED_CALL_IC) { |
1297 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); | 1299 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); |
1298 __ j(not_equal, miss, not_taken); | 1300 __ j(not_equal, miss, not_taken); |
1299 } | 1301 } |
(...skipping 30 matching lines...) Expand all Loading... |
1330 Label* miss) { | 1332 Label* miss) { |
1331 // Get the value from the cell. | 1333 // Get the value from the cell. |
1332 if (Serializer::enabled()) { | 1334 if (Serializer::enabled()) { |
1333 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); | 1335 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); |
1334 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); | 1336 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); |
1335 } else { | 1337 } else { |
1336 __ mov(edi, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); | 1338 __ mov(edi, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); |
1337 } | 1339 } |
1338 | 1340 |
1339 // Check that the cell contains the same function. | 1341 // Check that the cell contains the same function. |
1340 if (HEAP->InNewSpace(function)) { | 1342 if (isolate()->heap()->InNewSpace(function)) { |
1341 // We can't embed a pointer to a function in new space so we have | 1343 // We can't embed a pointer to a function in new space so we have |
1342 // to verify that the shared function info is unchanged. This has | 1344 // to verify that the shared function info is unchanged. This has |
1343 // the nice side effect that multiple closures based on the same | 1345 // the nice side effect that multiple closures based on the same |
1344 // function can all use this call IC. Before we load through the | 1346 // function can all use this call IC. Before we load through the |
1345 // function, we have to verify that it still is a function. | 1347 // function, we have to verify that it still is a function. |
1346 __ test(edi, Immediate(kSmiTagMask)); | 1348 __ test(edi, Immediate(kSmiTagMask)); |
1347 __ j(zero, miss, not_taken); | 1349 __ j(zero, miss, not_taken); |
1348 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); | 1350 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); |
1349 __ j(not_equal, miss, not_taken); | 1351 __ j(not_equal, miss, not_taken); |
1350 | 1352 |
1351 // Check the shared function info. Make sure it hasn't changed. | 1353 // Check the shared function info. Make sure it hasn't changed. |
1352 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), | 1354 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), |
1353 Immediate(Handle<SharedFunctionInfo>(function->shared()))); | 1355 Immediate(Handle<SharedFunctionInfo>(function->shared()))); |
1354 __ j(not_equal, miss, not_taken); | 1356 __ j(not_equal, miss, not_taken); |
1355 } else { | 1357 } else { |
1356 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); | 1358 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); |
1357 __ j(not_equal, miss, not_taken); | 1359 __ j(not_equal, miss, not_taken); |
1358 } | 1360 } |
1359 } | 1361 } |
1360 | 1362 |
1361 | 1363 |
1362 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1364 MaybeObject* CallStubCompiler::GenerateMissBranch() { |
1363 MaybeObject* maybe_obj = | 1365 MaybeObject* maybe_obj = |
1364 masm()->isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 1366 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), |
1365 kind_); | 1367 kind_); |
1366 Object* obj; | 1368 Object* obj; |
1367 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1369 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1368 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1370 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
1369 return obj; | 1371 return obj; |
1370 } | 1372 } |
1371 | 1373 |
1372 | 1374 |
1373 MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField( | 1375 MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField( |
1374 JSObject* object, | 1376 JSObject* object, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1433 String* name) { | 1435 String* name) { |
1434 // ----------- S t a t e ------------- | 1436 // ----------- S t a t e ------------- |
1435 // -- ecx : name | 1437 // -- ecx : name |
1436 // -- esp[0] : return address | 1438 // -- esp[0] : return address |
1437 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1439 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1438 // -- ... | 1440 // -- ... |
1439 // -- esp[(argc + 1) * 4] : receiver | 1441 // -- esp[(argc + 1) * 4] : receiver |
1440 // ----------------------------------- | 1442 // ----------------------------------- |
1441 | 1443 |
1442 // If object is not an array, bail out to regular call. | 1444 // If object is not an array, bail out to regular call. |
1443 if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value(); | 1445 if (!object->IsJSArray() || cell != NULL) { |
| 1446 return isolate()->heap()->undefined_value(); |
| 1447 } |
1444 | 1448 |
1445 Label miss; | 1449 Label miss; |
1446 | 1450 |
1447 GenerateNameCheck(name, &miss); | 1451 GenerateNameCheck(name, &miss); |
1448 | 1452 |
1449 // Get the receiver from the stack. | 1453 // Get the receiver from the stack. |
1450 const int argc = arguments().immediate(); | 1454 const int argc = arguments().immediate(); |
1451 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1455 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1452 | 1456 |
1453 // Check that the receiver isn't a smi. | 1457 // Check that the receiver isn't a smi. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1511 __ InNewSpace(ebx, ecx, equal, &exit); | 1515 __ InNewSpace(ebx, ecx, equal, &exit); |
1512 | 1516 |
1513 __ RecordWriteHelper(ebx, edx, ecx); | 1517 __ RecordWriteHelper(ebx, edx, ecx); |
1514 __ ret((argc + 1) * kPointerSize); | 1518 __ ret((argc + 1) * kPointerSize); |
1515 | 1519 |
1516 __ bind(&attempt_to_grow_elements); | 1520 __ bind(&attempt_to_grow_elements); |
1517 if (!FLAG_inline_new) { | 1521 if (!FLAG_inline_new) { |
1518 __ jmp(&call_builtin); | 1522 __ jmp(&call_builtin); |
1519 } | 1523 } |
1520 | 1524 |
1521 Isolate* isolate = masm()->isolate(); | |
1522 ExternalReference new_space_allocation_top = | 1525 ExternalReference new_space_allocation_top = |
1523 ExternalReference::new_space_allocation_top_address(isolate); | 1526 ExternalReference::new_space_allocation_top_address(isolate()); |
1524 ExternalReference new_space_allocation_limit = | 1527 ExternalReference new_space_allocation_limit = |
1525 ExternalReference::new_space_allocation_limit_address(isolate); | 1528 ExternalReference::new_space_allocation_limit_address(isolate()); |
1526 | 1529 |
1527 const int kAllocationDelta = 4; | 1530 const int kAllocationDelta = 4; |
1528 // Load top. | 1531 // Load top. |
1529 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top)); | 1532 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top)); |
1530 | 1533 |
1531 // Check if it's the end of elements. | 1534 // Check if it's the end of elements. |
1532 __ lea(edx, FieldOperand(ebx, | 1535 __ lea(edx, FieldOperand(ebx, |
1533 eax, times_half_pointer_size, | 1536 eax, times_half_pointer_size, |
1534 FixedArray::kHeaderSize - argc * kPointerSize)); | 1537 FixedArray::kHeaderSize - argc * kPointerSize)); |
1535 __ cmp(edx, Operand(ecx)); | 1538 __ cmp(edx, Operand(ecx)); |
(...skipping 21 matching lines...) Expand all Loading... |
1557 __ add(FieldOperand(ebx, FixedArray::kLengthOffset), | 1560 __ add(FieldOperand(ebx, FixedArray::kLengthOffset), |
1558 Immediate(Smi::FromInt(kAllocationDelta))); | 1561 Immediate(Smi::FromInt(kAllocationDelta))); |
1559 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax); | 1562 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax); |
1560 | 1563 |
1561 // Elements are in new space, so write barrier is not required. | 1564 // Elements are in new space, so write barrier is not required. |
1562 __ ret((argc + 1) * kPointerSize); | 1565 __ ret((argc + 1) * kPointerSize); |
1563 } | 1566 } |
1564 | 1567 |
1565 __ bind(&call_builtin); | 1568 __ bind(&call_builtin); |
1566 __ TailCallExternalReference( | 1569 __ TailCallExternalReference( |
1567 ExternalReference(Builtins::c_ArrayPush, masm()->isolate()), | 1570 ExternalReference(Builtins::c_ArrayPush, isolate()), |
1568 argc + 1, | 1571 argc + 1, |
1569 1); | 1572 1); |
1570 } | 1573 } |
1571 | 1574 |
1572 __ bind(&miss); | 1575 __ bind(&miss); |
1573 MaybeObject* maybe_result = GenerateMissBranch(); | 1576 MaybeObject* maybe_result = GenerateMissBranch(); |
1574 if (maybe_result->IsFailure()) return maybe_result; | 1577 if (maybe_result->IsFailure()) return maybe_result; |
1575 | 1578 |
1576 // Return the generated code. | 1579 // Return the generated code. |
1577 return GetCode(function); | 1580 return GetCode(function); |
1578 } | 1581 } |
1579 | 1582 |
1580 | 1583 |
1581 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, | 1584 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, |
1582 JSObject* holder, | 1585 JSObject* holder, |
1583 JSGlobalPropertyCell* cell, | 1586 JSGlobalPropertyCell* cell, |
1584 JSFunction* function, | 1587 JSFunction* function, |
1585 String* name) { | 1588 String* name) { |
1586 // ----------- S t a t e ------------- | 1589 // ----------- S t a t e ------------- |
1587 // -- ecx : name | 1590 // -- ecx : name |
1588 // -- esp[0] : return address | 1591 // -- esp[0] : return address |
1589 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1592 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1590 // -- ... | 1593 // -- ... |
1591 // -- esp[(argc + 1) * 4] : receiver | 1594 // -- esp[(argc + 1) * 4] : receiver |
1592 // ----------------------------------- | 1595 // ----------------------------------- |
1593 | 1596 |
1594 // If object is not an array, bail out to regular call. | 1597 // If object is not an array, bail out to regular call. |
1595 if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value(); | 1598 if (!object->IsJSArray() || cell != NULL) { |
| 1599 return isolate()->heap()->undefined_value(); |
| 1600 } |
1596 | 1601 |
1597 Label miss, return_undefined, call_builtin; | 1602 Label miss, return_undefined, call_builtin; |
1598 | 1603 |
1599 GenerateNameCheck(name, &miss); | 1604 GenerateNameCheck(name, &miss); |
1600 | 1605 |
1601 // Get the receiver from the stack. | 1606 // Get the receiver from the stack. |
1602 const int argc = arguments().immediate(); | 1607 const int argc = arguments().immediate(); |
1603 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1608 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1604 | 1609 |
1605 // Check that the receiver isn't a smi. | 1610 // Check that the receiver isn't a smi. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1640 FixedArray::kHeaderSize), | 1645 FixedArray::kHeaderSize), |
1641 Immediate(FACTORY->the_hole_value())); | 1646 Immediate(FACTORY->the_hole_value())); |
1642 __ ret((argc + 1) * kPointerSize); | 1647 __ ret((argc + 1) * kPointerSize); |
1643 | 1648 |
1644 __ bind(&return_undefined); | 1649 __ bind(&return_undefined); |
1645 __ mov(eax, Immediate(FACTORY->undefined_value())); | 1650 __ mov(eax, Immediate(FACTORY->undefined_value())); |
1646 __ ret((argc + 1) * kPointerSize); | 1651 __ ret((argc + 1) * kPointerSize); |
1647 | 1652 |
1648 __ bind(&call_builtin); | 1653 __ bind(&call_builtin); |
1649 __ TailCallExternalReference( | 1654 __ TailCallExternalReference( |
1650 ExternalReference(Builtins::c_ArrayPop, masm()->isolate()), | 1655 ExternalReference(Builtins::c_ArrayPop, isolate()), |
1651 argc + 1, | 1656 argc + 1, |
1652 1); | 1657 1); |
1653 | 1658 |
1654 __ bind(&miss); | 1659 __ bind(&miss); |
1655 MaybeObject* maybe_result = GenerateMissBranch(); | 1660 MaybeObject* maybe_result = GenerateMissBranch(); |
1656 if (maybe_result->IsFailure()) return maybe_result; | 1661 if (maybe_result->IsFailure()) return maybe_result; |
1657 | 1662 |
1658 // Return the generated code. | 1663 // Return the generated code. |
1659 return GetCode(function); | 1664 return GetCode(function); |
1660 } | 1665 } |
1661 | 1666 |
1662 | 1667 |
1663 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( | 1668 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( |
1664 Object* object, | 1669 Object* object, |
1665 JSObject* holder, | 1670 JSObject* holder, |
1666 JSGlobalPropertyCell* cell, | 1671 JSGlobalPropertyCell* cell, |
1667 JSFunction* function, | 1672 JSFunction* function, |
1668 String* name) { | 1673 String* name) { |
1669 // ----------- S t a t e ------------- | 1674 // ----------- S t a t e ------------- |
1670 // -- ecx : function name | 1675 // -- ecx : function name |
1671 // -- esp[0] : return address | 1676 // -- esp[0] : return address |
1672 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1677 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1673 // -- ... | 1678 // -- ... |
1674 // -- esp[(argc + 1) * 4] : receiver | 1679 // -- esp[(argc + 1) * 4] : receiver |
1675 // ----------------------------------- | 1680 // ----------------------------------- |
1676 | 1681 |
1677 // If object is not a string, bail out to regular call. | 1682 // If object is not a string, bail out to regular call. |
1678 if (!object->IsString() || cell != NULL) { | 1683 if (!object->IsString() || cell != NULL) { |
1679 return masm()->isolate()->heap()->undefined_value(); | 1684 return isolate()->heap()->undefined_value(); |
1680 } | 1685 } |
1681 | 1686 |
1682 const int argc = arguments().immediate(); | 1687 const int argc = arguments().immediate(); |
1683 | 1688 |
1684 Label miss; | 1689 Label miss; |
1685 Label name_miss; | 1690 Label name_miss; |
1686 Label index_out_of_range; | 1691 Label index_out_of_range; |
1687 Label* index_out_of_range_label = &index_out_of_range; | 1692 Label* index_out_of_range_label = &index_out_of_range; |
1688 | 1693 |
1689 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { | 1694 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1752 String* name) { | 1757 String* name) { |
1753 // ----------- S t a t e ------------- | 1758 // ----------- S t a t e ------------- |
1754 // -- ecx : function name | 1759 // -- ecx : function name |
1755 // -- esp[0] : return address | 1760 // -- esp[0] : return address |
1756 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1761 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1757 // -- ... | 1762 // -- ... |
1758 // -- esp[(argc + 1) * 4] : receiver | 1763 // -- esp[(argc + 1) * 4] : receiver |
1759 // ----------------------------------- | 1764 // ----------------------------------- |
1760 | 1765 |
1761 // If object is not a string, bail out to regular call. | 1766 // If object is not a string, bail out to regular call. |
1762 if (!object->IsString() || cell != NULL) return HEAP->undefined_value(); | 1767 if (!object->IsString() || cell != NULL) { |
| 1768 return isolate()->heap()->undefined_value(); |
| 1769 } |
1763 | 1770 |
1764 const int argc = arguments().immediate(); | 1771 const int argc = arguments().immediate(); |
1765 | 1772 |
1766 Label miss; | 1773 Label miss; |
1767 Label name_miss; | 1774 Label name_miss; |
1768 Label index_out_of_range; | 1775 Label index_out_of_range; |
1769 Label* index_out_of_range_label = &index_out_of_range; | 1776 Label* index_out_of_range_label = &index_out_of_range; |
1770 | 1777 |
1771 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { | 1778 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { |
1772 index_out_of_range_label = &miss; | 1779 index_out_of_range_label = &miss; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1839 // -- esp[0] : return address | 1846 // -- esp[0] : return address |
1840 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1847 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1841 // -- ... | 1848 // -- ... |
1842 // -- esp[(argc + 1) * 4] : receiver | 1849 // -- esp[(argc + 1) * 4] : receiver |
1843 // ----------------------------------- | 1850 // ----------------------------------- |
1844 | 1851 |
1845 const int argc = arguments().immediate(); | 1852 const int argc = arguments().immediate(); |
1846 | 1853 |
1847 // If the object is not a JSObject or we got an unexpected number of | 1854 // If the object is not a JSObject or we got an unexpected number of |
1848 // arguments, bail out to the regular call. | 1855 // arguments, bail out to the regular call. |
1849 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value(); | 1856 if (!object->IsJSObject() || argc != 1) { |
| 1857 return isolate()->heap()->undefined_value(); |
| 1858 } |
1850 | 1859 |
1851 Label miss; | 1860 Label miss; |
1852 GenerateNameCheck(name, &miss); | 1861 GenerateNameCheck(name, &miss); |
1853 | 1862 |
1854 if (cell == NULL) { | 1863 if (cell == NULL) { |
1855 __ mov(edx, Operand(esp, 2 * kPointerSize)); | 1864 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
1856 | 1865 |
1857 STATIC_ASSERT(kSmiTag == 0); | 1866 STATIC_ASSERT(kSmiTag == 0); |
1858 __ test(edx, Immediate(kSmiTagMask)); | 1867 __ test(edx, Immediate(kSmiTagMask)); |
1859 __ j(zero, &miss); | 1868 __ j(zero, &miss); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1907 JSFunction* function, | 1916 JSFunction* function, |
1908 String* name) { | 1917 String* name) { |
1909 // ----------- S t a t e ------------- | 1918 // ----------- S t a t e ------------- |
1910 // -- ecx : name | 1919 // -- ecx : name |
1911 // -- esp[0] : return address | 1920 // -- esp[0] : return address |
1912 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1921 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1913 // -- ... | 1922 // -- ... |
1914 // -- esp[(argc + 1) * 4] : receiver | 1923 // -- esp[(argc + 1) * 4] : receiver |
1915 // ----------------------------------- | 1924 // ----------------------------------- |
1916 | 1925 |
1917 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) | 1926 if (isolate()->cpu_features()->IsSupported(SSE2)) { |
1918 return HEAP->undefined_value(); | 1927 return isolate()->heap()->undefined_value(); |
| 1928 } |
| 1929 |
1919 CpuFeatures::Scope use_sse2(SSE2); | 1930 CpuFeatures::Scope use_sse2(SSE2); |
1920 | 1931 |
1921 const int argc = arguments().immediate(); | 1932 const int argc = arguments().immediate(); |
1922 | 1933 |
1923 // If the object is not a JSObject or we got an unexpected number of | 1934 // If the object is not a JSObject or we got an unexpected number of |
1924 // arguments, bail out to the regular call. | 1935 // arguments, bail out to the regular call. |
1925 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value(); | 1936 if (!object->IsJSObject() || argc != 1) { |
| 1937 return isolate()->heap()->undefined_value(); |
| 1938 } |
1926 | 1939 |
1927 Label miss; | 1940 Label miss; |
1928 GenerateNameCheck(name, &miss); | 1941 GenerateNameCheck(name, &miss); |
1929 | 1942 |
1930 if (cell == NULL) { | 1943 if (cell == NULL) { |
1931 __ mov(edx, Operand(esp, 2 * kPointerSize)); | 1944 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
1932 | 1945 |
1933 STATIC_ASSERT(kSmiTag == 0); | 1946 STATIC_ASSERT(kSmiTag == 0); |
1934 __ test(edx, Immediate(kSmiTagMask)); | 1947 __ test(edx, Immediate(kSmiTagMask)); |
1935 __ j(zero, &miss); | 1948 __ j(zero, &miss); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2037 // -- esp[0] : return address | 2050 // -- esp[0] : return address |
2038 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2051 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
2039 // -- ... | 2052 // -- ... |
2040 // -- esp[(argc + 1) * 4] : receiver | 2053 // -- esp[(argc + 1) * 4] : receiver |
2041 // ----------------------------------- | 2054 // ----------------------------------- |
2042 | 2055 |
2043 const int argc = arguments().immediate(); | 2056 const int argc = arguments().immediate(); |
2044 | 2057 |
2045 // If the object is not a JSObject or we got an unexpected number of | 2058 // If the object is not a JSObject or we got an unexpected number of |
2046 // arguments, bail out to the regular call. | 2059 // arguments, bail out to the regular call. |
2047 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value(); | 2060 if (!object->IsJSObject() || argc != 1) { |
| 2061 return isolate()->heap()->undefined_value(); |
| 2062 } |
2048 | 2063 |
2049 Label miss; | 2064 Label miss; |
2050 GenerateNameCheck(name, &miss); | 2065 GenerateNameCheck(name, &miss); |
2051 | 2066 |
2052 if (cell == NULL) { | 2067 if (cell == NULL) { |
2053 __ mov(edx, Operand(esp, 2 * kPointerSize)); | 2068 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
2054 | 2069 |
2055 STATIC_ASSERT(kSmiTag == 0); | 2070 STATIC_ASSERT(kSmiTag == 0); |
2056 __ test(edx, Immediate(kSmiTagMask)); | 2071 __ test(edx, Immediate(kSmiTagMask)); |
2057 __ j(zero, &miss); | 2072 __ j(zero, &miss); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2133 MaybeObject* CallStubCompiler::CompileFastApiCall( | 2148 MaybeObject* CallStubCompiler::CompileFastApiCall( |
2134 const CallOptimization& optimization, | 2149 const CallOptimization& optimization, |
2135 Object* object, | 2150 Object* object, |
2136 JSObject* holder, | 2151 JSObject* holder, |
2137 JSGlobalPropertyCell* cell, | 2152 JSGlobalPropertyCell* cell, |
2138 JSFunction* function, | 2153 JSFunction* function, |
2139 String* name) { | 2154 String* name) { |
2140 ASSERT(optimization.is_simple_api_call()); | 2155 ASSERT(optimization.is_simple_api_call()); |
2141 // Bail out if object is a global object as we don't want to | 2156 // Bail out if object is a global object as we don't want to |
2142 // repatch it to global receiver. | 2157 // repatch it to global receiver. |
2143 if (object->IsGlobalObject()) return HEAP->undefined_value(); | 2158 Heap* heap = isolate()->heap(); |
2144 if (cell != NULL) return HEAP->undefined_value(); | 2159 if (object->IsGlobalObject()) return heap->undefined_value(); |
| 2160 if (cell != NULL) return heap->undefined_value(); |
2145 int depth = optimization.GetPrototypeDepthOfExpectedType( | 2161 int depth = optimization.GetPrototypeDepthOfExpectedType( |
2146 JSObject::cast(object), holder); | 2162 JSObject::cast(object), holder); |
2147 if (depth == kInvalidProtoDepth) return HEAP->undefined_value(); | 2163 if (depth == kInvalidProtoDepth) return heap->undefined_value(); |
2148 | 2164 |
2149 Label miss, miss_before_stack_reserved; | 2165 Label miss, miss_before_stack_reserved; |
2150 | 2166 |
2151 GenerateNameCheck(name, &miss_before_stack_reserved); | 2167 GenerateNameCheck(name, &miss_before_stack_reserved); |
2152 | 2168 |
2153 // Get the receiver from the stack. | 2169 // Get the receiver from the stack. |
2154 const int argc = arguments().immediate(); | 2170 const int argc = arguments().immediate(); |
2155 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 2171 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
2156 | 2172 |
2157 // Check that the receiver isn't a smi. | 2173 // Check that the receiver isn't a smi. |
2158 __ test(edx, Immediate(kSmiTagMask)); | 2174 __ test(edx, Immediate(kSmiTagMask)); |
2159 __ j(zero, &miss_before_stack_reserved, not_taken); | 2175 __ j(zero, &miss_before_stack_reserved, not_taken); |
2160 | 2176 |
2161 Counters* counters = masm()->isolate()->counters(); | 2177 Counters* counters = isolate()->counters(); |
2162 __ IncrementCounter(counters->call_const(), 1); | 2178 __ IncrementCounter(counters->call_const(), 1); |
2163 __ IncrementCounter(counters->call_const_fast_api(), 1); | 2179 __ IncrementCounter(counters->call_const_fast_api(), 1); |
2164 | 2180 |
2165 // Allocate space for v8::Arguments implicit values. Must be initialized | 2181 // Allocate space for v8::Arguments implicit values. Must be initialized |
2166 // before calling any runtime function. | 2182 // before calling any runtime function. |
2167 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); | 2183 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); |
2168 | 2184 |
2169 // Check that the maps haven't changed and find a Holder as a side effect. | 2185 // Check that the maps haven't changed and find a Holder as a side effect. |
2170 CheckPrototypes(JSObject::cast(object), edx, holder, | 2186 CheckPrototypes(JSObject::cast(object), edx, holder, |
2171 ebx, eax, edi, name, depth, &miss); | 2187 ebx, eax, edi, name, depth, &miss); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2227 __ j(zero, &miss, not_taken); | 2243 __ j(zero, &miss, not_taken); |
2228 } | 2244 } |
2229 | 2245 |
2230 // Make sure that it's okay not to patch the on stack receiver | 2246 // Make sure that it's okay not to patch the on stack receiver |
2231 // unless we're doing a receiver map check. | 2247 // unless we're doing a receiver map check. |
2232 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2248 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
2233 | 2249 |
2234 SharedFunctionInfo* function_info = function->shared(); | 2250 SharedFunctionInfo* function_info = function->shared(); |
2235 switch (check) { | 2251 switch (check) { |
2236 case RECEIVER_MAP_CHECK: | 2252 case RECEIVER_MAP_CHECK: |
2237 __ IncrementCounter(masm()->isolate()->counters()->call_const(), 1); | 2253 __ IncrementCounter(isolate()->counters()->call_const(), 1); |
2238 | 2254 |
2239 // Check that the maps haven't changed. | 2255 // Check that the maps haven't changed. |
2240 CheckPrototypes(JSObject::cast(object), edx, holder, | 2256 CheckPrototypes(JSObject::cast(object), edx, holder, |
2241 ebx, eax, edi, name, &miss); | 2257 ebx, eax, edi, name, &miss); |
2242 | 2258 |
2243 // Patch the receiver on the stack with the global proxy if | 2259 // Patch the receiver on the stack with the global proxy if |
2244 // necessary. | 2260 // necessary. |
2245 if (object->IsGlobalObject()) { | 2261 if (object->IsGlobalObject()) { |
2246 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2262 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
2247 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 2263 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2427 // Patch the receiver on the stack with the global proxy. | 2443 // Patch the receiver on the stack with the global proxy. |
2428 if (object->IsGlobalObject()) { | 2444 if (object->IsGlobalObject()) { |
2429 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2445 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
2430 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 2446 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
2431 } | 2447 } |
2432 | 2448 |
2433 // Setup the context (function already in edi). | 2449 // Setup the context (function already in edi). |
2434 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 2450 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
2435 | 2451 |
2436 // Jump to the cached code (tail call). | 2452 // Jump to the cached code (tail call). |
2437 Counters* counters = masm()->isolate()->counters(); | 2453 Counters* counters = isolate()->counters(); |
2438 __ IncrementCounter(counters->call_global_inline(), 1); | 2454 __ IncrementCounter(counters->call_global_inline(), 1); |
2439 ASSERT(function->is_compiled()); | 2455 ASSERT(function->is_compiled()); |
2440 ParameterCount expected(function->shared()->formal_parameter_count()); | 2456 ParameterCount expected(function->shared()->formal_parameter_count()); |
2441 if (V8::UseCrankshaft()) { | 2457 if (V8::UseCrankshaft()) { |
2442 // TODO(kasperl): For now, we always call indirectly through the | 2458 // TODO(kasperl): For now, we always call indirectly through the |
2443 // code field in the function to allow recompilation to take effect | 2459 // code field in the function to allow recompilation to take effect |
2444 // without changing any of the call sites. | 2460 // without changing any of the call sites. |
2445 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), | 2461 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), |
2446 expected, arguments(), JUMP_FUNCTION); | 2462 expected, arguments(), JUMP_FUNCTION); |
2447 } else { | 2463 } else { |
(...skipping 29 matching lines...) Expand all Loading... |
2477 GenerateStoreField(masm(), | 2493 GenerateStoreField(masm(), |
2478 object, | 2494 object, |
2479 index, | 2495 index, |
2480 transition, | 2496 transition, |
2481 edx, ecx, ebx, | 2497 edx, ecx, ebx, |
2482 &miss); | 2498 &miss); |
2483 | 2499 |
2484 // Handle store cache miss. | 2500 // Handle store cache miss. |
2485 __ bind(&miss); | 2501 __ bind(&miss); |
2486 __ mov(ecx, Immediate(Handle<String>(name))); // restore name | 2502 __ mov(ecx, Immediate(Handle<String>(name))); // restore name |
2487 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2503 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); |
2488 __ jmp(ic, RelocInfo::CODE_TARGET); | 2504 __ jmp(ic, RelocInfo::CODE_TARGET); |
2489 | 2505 |
2490 // Return the generated code. | 2506 // Return the generated code. |
2491 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2507 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
2492 } | 2508 } |
2493 | 2509 |
2494 | 2510 |
2495 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, | 2511 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, |
2496 AccessorInfo* callback, | 2512 AccessorInfo* callback, |
2497 String* name) { | 2513 String* name) { |
(...skipping 24 matching lines...) Expand all Loading... |
2522 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 2538 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
2523 | 2539 |
2524 __ pop(ebx); // remove the return address | 2540 __ pop(ebx); // remove the return address |
2525 __ push(edx); // receiver | 2541 __ push(edx); // receiver |
2526 __ push(Immediate(Handle<AccessorInfo>(callback))); // callback info | 2542 __ push(Immediate(Handle<AccessorInfo>(callback))); // callback info |
2527 __ push(ecx); // name | 2543 __ push(ecx); // name |
2528 __ push(eax); // value | 2544 __ push(eax); // value |
2529 __ push(ebx); // restore return address | 2545 __ push(ebx); // restore return address |
2530 | 2546 |
2531 // Do tail-call to the runtime system. | 2547 // Do tail-call to the runtime system. |
2532 Isolate* isolate = masm()->isolate(); | |
2533 ExternalReference store_callback_property = | 2548 ExternalReference store_callback_property = |
2534 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate); | 2549 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); |
2535 __ TailCallExternalReference(store_callback_property, 4, 1); | 2550 __ TailCallExternalReference(store_callback_property, 4, 1); |
2536 | 2551 |
2537 // Handle store cache miss. | 2552 // Handle store cache miss. |
2538 __ bind(&miss); | 2553 __ bind(&miss); |
2539 Handle<Code> ic = isolate->builtins()->StoreIC_Miss(); | 2554 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); |
2540 __ jmp(ic, RelocInfo::CODE_TARGET); | 2555 __ jmp(ic, RelocInfo::CODE_TARGET); |
2541 | 2556 |
2542 // Return the generated code. | 2557 // Return the generated code. |
2543 return GetCode(CALLBACKS, name); | 2558 return GetCode(CALLBACKS, name); |
2544 } | 2559 } |
2545 | 2560 |
2546 | 2561 |
2547 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, | 2562 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, |
2548 String* name) { | 2563 String* name) { |
2549 // ----------- S t a t e ------------- | 2564 // ----------- S t a t e ------------- |
(...skipping 23 matching lines...) Expand all Loading... |
2573 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); | 2588 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); |
2574 | 2589 |
2575 __ pop(ebx); // remove the return address | 2590 __ pop(ebx); // remove the return address |
2576 __ push(edx); // receiver | 2591 __ push(edx); // receiver |
2577 __ push(ecx); // name | 2592 __ push(ecx); // name |
2578 __ push(eax); // value | 2593 __ push(eax); // value |
2579 __ push(Immediate(Smi::FromInt(strict_mode_))); | 2594 __ push(Immediate(Smi::FromInt(strict_mode_))); |
2580 __ push(ebx); // restore return address | 2595 __ push(ebx); // restore return address |
2581 | 2596 |
2582 // Do tail-call to the runtime system. | 2597 // Do tail-call to the runtime system. |
2583 Isolate* isolate = masm()->isolate(); | |
2584 ExternalReference store_ic_property = | 2598 ExternalReference store_ic_property = |
2585 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate); | 2599 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); |
2586 __ TailCallExternalReference(store_ic_property, 4, 1); | 2600 __ TailCallExternalReference(store_ic_property, 4, 1); |
2587 | 2601 |
2588 // Handle store cache miss. | 2602 // Handle store cache miss. |
2589 __ bind(&miss); | 2603 __ bind(&miss); |
2590 Handle<Code> ic = isolate->builtins()->StoreIC_Miss(); | 2604 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); |
2591 __ jmp(ic, RelocInfo::CODE_TARGET); | 2605 __ jmp(ic, RelocInfo::CODE_TARGET); |
2592 | 2606 |
2593 // Return the generated code. | 2607 // Return the generated code. |
2594 return GetCode(INTERCEPTOR, name); | 2608 return GetCode(INTERCEPTOR, name); |
2595 } | 2609 } |
2596 | 2610 |
2597 | 2611 |
2598 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, | 2612 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, |
2599 JSGlobalPropertyCell* cell, | 2613 JSGlobalPropertyCell* cell, |
2600 String* name) { | 2614 String* name) { |
(...skipping 22 matching lines...) Expand all Loading... |
2623 // cell could have been deleted and reintroducing the global needs | 2637 // cell could have been deleted and reintroducing the global needs |
2624 // to update the property details in the property dictionary of the | 2638 // to update the property details in the property dictionary of the |
2625 // global object. We bail out to the runtime system to do that. | 2639 // global object. We bail out to the runtime system to do that. |
2626 __ cmp(cell_operand, FACTORY->the_hole_value()); | 2640 __ cmp(cell_operand, FACTORY->the_hole_value()); |
2627 __ j(equal, &miss); | 2641 __ j(equal, &miss); |
2628 | 2642 |
2629 // Store the value in the cell. | 2643 // Store the value in the cell. |
2630 __ mov(cell_operand, eax); | 2644 __ mov(cell_operand, eax); |
2631 | 2645 |
2632 // Return the value (register eax). | 2646 // Return the value (register eax). |
2633 Counters* counters = masm()->isolate()->counters(); | 2647 Counters* counters = isolate()->counters(); |
2634 __ IncrementCounter(counters->named_store_global_inline(), 1); | 2648 __ IncrementCounter(counters->named_store_global_inline(), 1); |
2635 __ ret(0); | 2649 __ ret(0); |
2636 | 2650 |
2637 // Handle store cache miss. | 2651 // Handle store cache miss. |
2638 __ bind(&miss); | 2652 __ bind(&miss); |
2639 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); | 2653 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); |
2640 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2654 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); |
2641 __ jmp(ic, RelocInfo::CODE_TARGET); | 2655 __ jmp(ic, RelocInfo::CODE_TARGET); |
2642 | 2656 |
2643 // Return the generated code. | 2657 // Return the generated code. |
2644 return GetCode(NORMAL, name); | 2658 return GetCode(NORMAL, name); |
2645 } | 2659 } |
2646 | 2660 |
2647 | 2661 |
2648 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 2662 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, |
2649 int index, | 2663 int index, |
2650 Map* transition, | 2664 Map* transition, |
2651 String* name) { | 2665 String* name) { |
2652 // ----------- S t a t e ------------- | 2666 // ----------- S t a t e ------------- |
2653 // -- eax : value | 2667 // -- eax : value |
2654 // -- ecx : key | 2668 // -- ecx : key |
2655 // -- edx : receiver | 2669 // -- edx : receiver |
2656 // -- esp[0] : return address | 2670 // -- esp[0] : return address |
2657 // ----------------------------------- | 2671 // ----------------------------------- |
2658 Label miss; | 2672 Label miss; |
2659 | 2673 |
2660 Counters* counters = masm()->isolate()->counters(); | 2674 Counters* counters = isolate()->counters(); |
2661 __ IncrementCounter(counters->keyed_store_field(), 1); | 2675 __ IncrementCounter(counters->keyed_store_field(), 1); |
2662 | 2676 |
2663 // Check that the name has not changed. | 2677 // Check that the name has not changed. |
2664 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); | 2678 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); |
2665 __ j(not_equal, &miss, not_taken); | 2679 __ j(not_equal, &miss, not_taken); |
2666 | 2680 |
2667 // Generate store field code. Trashes the name register. | 2681 // Generate store field code. Trashes the name register. |
2668 GenerateStoreField(masm(), | 2682 GenerateStoreField(masm(), |
2669 object, | 2683 object, |
2670 index, | 2684 index, |
2671 transition, | 2685 transition, |
2672 edx, ecx, ebx, | 2686 edx, ecx, ebx, |
2673 &miss); | 2687 &miss); |
2674 | 2688 |
2675 // Handle store cache miss. | 2689 // Handle store cache miss. |
2676 __ bind(&miss); | 2690 __ bind(&miss); |
2677 __ DecrementCounter(counters->keyed_store_field(), 1); | 2691 __ DecrementCounter(counters->keyed_store_field(), 1); |
2678 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); | 2692 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
2679 __ jmp(ic, RelocInfo::CODE_TARGET); | 2693 __ jmp(ic, RelocInfo::CODE_TARGET); |
2680 | 2694 |
2681 // Return the generated code. | 2695 // Return the generated code. |
2682 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2696 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
2683 } | 2697 } |
2684 | 2698 |
2685 | 2699 |
2686 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( | 2700 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( |
2687 JSObject* receiver) { | 2701 JSObject* receiver) { |
2688 // ----------- S t a t e ------------- | 2702 // ----------- S t a t e ------------- |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2725 // the value in register eax. | 2739 // the value in register eax. |
2726 __ mov(edx, Operand(eax)); | 2740 __ mov(edx, Operand(eax)); |
2727 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax); | 2741 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax); |
2728 __ RecordWrite(edi, 0, edx, ecx); | 2742 __ RecordWrite(edi, 0, edx, ecx); |
2729 | 2743 |
2730 // Done. | 2744 // Done. |
2731 __ ret(0); | 2745 __ ret(0); |
2732 | 2746 |
2733 // Handle store cache miss. | 2747 // Handle store cache miss. |
2734 __ bind(&miss); | 2748 __ bind(&miss); |
2735 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); | 2749 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
2736 __ jmp(ic, RelocInfo::CODE_TARGET); | 2750 __ jmp(ic, RelocInfo::CODE_TARGET); |
2737 | 2751 |
2738 // Return the generated code. | 2752 // Return the generated code. |
2739 return GetCode(NORMAL, NULL); | 2753 return GetCode(NORMAL, NULL); |
2740 } | 2754 } |
2741 | 2755 |
2742 | 2756 |
2743 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, | 2757 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, |
2744 JSObject* object, | 2758 JSObject* object, |
2745 JSObject* last) { | 2759 JSObject* last) { |
(...skipping 24 matching lines...) Expand all Loading... |
2770 edx, | 2784 edx, |
2771 &miss); | 2785 &miss); |
2772 if (cell->IsFailure()) { | 2786 if (cell->IsFailure()) { |
2773 miss.Unuse(); | 2787 miss.Unuse(); |
2774 return cell; | 2788 return cell; |
2775 } | 2789 } |
2776 } | 2790 } |
2777 | 2791 |
2778 // Return undefined if maps of the full prototype chain are still the | 2792 // Return undefined if maps of the full prototype chain are still the |
2779 // same and no global property with this name contains a value. | 2793 // same and no global property with this name contains a value. |
2780 __ mov(eax, FACTORY->undefined_value()); | 2794 __ mov(eax, isolate()->factory()->undefined_value()); |
2781 __ ret(0); | 2795 __ ret(0); |
2782 | 2796 |
2783 __ bind(&miss); | 2797 __ bind(&miss); |
2784 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2798 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2785 | 2799 |
2786 // Return the generated code. | 2800 // Return the generated code. |
2787 return GetCode(NONEXISTENT, HEAP->empty_string()); | 2801 return GetCode(NONEXISTENT, isolate()->heap()->empty_string()); |
2788 } | 2802 } |
2789 | 2803 |
2790 | 2804 |
2791 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, | 2805 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, |
2792 JSObject* holder, | 2806 JSObject* holder, |
2793 int index, | 2807 int index, |
2794 String* name) { | 2808 String* name) { |
2795 // ----------- S t a t e ------------- | 2809 // ----------- S t a t e ------------- |
2796 // -- eax : receiver | 2810 // -- eax : receiver |
2797 // -- ecx : name | 2811 // -- ecx : name |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2921 | 2935 |
2922 // Check for deleted property if property can actually be deleted. | 2936 // Check for deleted property if property can actually be deleted. |
2923 if (!is_dont_delete) { | 2937 if (!is_dont_delete) { |
2924 __ cmp(ebx, FACTORY->the_hole_value()); | 2938 __ cmp(ebx, FACTORY->the_hole_value()); |
2925 __ j(equal, &miss, not_taken); | 2939 __ j(equal, &miss, not_taken); |
2926 } else if (FLAG_debug_code) { | 2940 } else if (FLAG_debug_code) { |
2927 __ cmp(ebx, FACTORY->the_hole_value()); | 2941 __ cmp(ebx, FACTORY->the_hole_value()); |
2928 __ Check(not_equal, "DontDelete cells can't contain the hole"); | 2942 __ Check(not_equal, "DontDelete cells can't contain the hole"); |
2929 } | 2943 } |
2930 | 2944 |
2931 Counters* counters = masm()->isolate()->counters(); | 2945 Counters* counters = isolate()->counters(); |
2932 __ IncrementCounter(counters->named_load_global_stub(), 1); | 2946 __ IncrementCounter(counters->named_load_global_stub(), 1); |
2933 __ mov(eax, ebx); | 2947 __ mov(eax, ebx); |
2934 __ ret(0); | 2948 __ ret(0); |
2935 | 2949 |
2936 __ bind(&miss); | 2950 __ bind(&miss); |
2937 __ IncrementCounter(counters->named_load_global_stub_miss(), 1); | 2951 __ IncrementCounter(counters->named_load_global_stub_miss(), 1); |
2938 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2952 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2939 | 2953 |
2940 // Return the generated code. | 2954 // Return the generated code. |
2941 return GetCode(NORMAL, name); | 2955 return GetCode(NORMAL, name); |
2942 } | 2956 } |
2943 | 2957 |
2944 | 2958 |
2945 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, | 2959 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, |
2946 JSObject* receiver, | 2960 JSObject* receiver, |
2947 JSObject* holder, | 2961 JSObject* holder, |
2948 int index) { | 2962 int index) { |
2949 // ----------- S t a t e ------------- | 2963 // ----------- S t a t e ------------- |
2950 // -- eax : key | 2964 // -- eax : key |
2951 // -- edx : receiver | 2965 // -- edx : receiver |
2952 // -- esp[0] : return address | 2966 // -- esp[0] : return address |
2953 // ----------------------------------- | 2967 // ----------------------------------- |
2954 Label miss; | 2968 Label miss; |
2955 | 2969 |
2956 Counters* counters = masm()->isolate()->counters(); | 2970 Counters* counters = isolate()->counters(); |
2957 __ IncrementCounter(counters->keyed_load_field(), 1); | 2971 __ IncrementCounter(counters->keyed_load_field(), 1); |
2958 | 2972 |
2959 // Check that the name has not changed. | 2973 // Check that the name has not changed. |
2960 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 2974 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
2961 __ j(not_equal, &miss, not_taken); | 2975 __ j(not_equal, &miss, not_taken); |
2962 | 2976 |
2963 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); | 2977 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); |
2964 | 2978 |
2965 __ bind(&miss); | 2979 __ bind(&miss); |
2966 __ DecrementCounter(counters->keyed_load_field(), 1); | 2980 __ DecrementCounter(counters->keyed_load_field(), 1); |
2967 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2981 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2968 | 2982 |
2969 // Return the generated code. | 2983 // Return the generated code. |
2970 return GetCode(FIELD, name); | 2984 return GetCode(FIELD, name); |
2971 } | 2985 } |
2972 | 2986 |
2973 | 2987 |
2974 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( | 2988 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( |
2975 String* name, | 2989 String* name, |
2976 JSObject* receiver, | 2990 JSObject* receiver, |
2977 JSObject* holder, | 2991 JSObject* holder, |
2978 AccessorInfo* callback) { | 2992 AccessorInfo* callback) { |
2979 // ----------- S t a t e ------------- | 2993 // ----------- S t a t e ------------- |
2980 // -- eax : key | 2994 // -- eax : key |
2981 // -- edx : receiver | 2995 // -- edx : receiver |
2982 // -- esp[0] : return address | 2996 // -- esp[0] : return address |
2983 // ----------------------------------- | 2997 // ----------------------------------- |
2984 Label miss; | 2998 Label miss; |
2985 | 2999 |
2986 Counters* counters = masm()->isolate()->counters(); | 3000 Counters* counters = isolate()->counters(); |
2987 __ IncrementCounter(counters->keyed_load_callback(), 1); | 3001 __ IncrementCounter(counters->keyed_load_callback(), 1); |
2988 | 3002 |
2989 // Check that the name has not changed. | 3003 // Check that the name has not changed. |
2990 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 3004 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
2991 __ j(not_equal, &miss, not_taken); | 3005 __ j(not_equal, &miss, not_taken); |
2992 | 3006 |
2993 MaybeObject* result = GenerateLoadCallback(receiver, holder, edx, eax, ebx, | 3007 MaybeObject* result = GenerateLoadCallback(receiver, holder, edx, eax, ebx, |
2994 ecx, edi, callback, name, &miss); | 3008 ecx, edi, callback, name, &miss); |
2995 if (result->IsFailure()) { | 3009 if (result->IsFailure()) { |
2996 miss.Unuse(); | 3010 miss.Unuse(); |
(...skipping 14 matching lines...) Expand all Loading... |
3011 JSObject* receiver, | 3025 JSObject* receiver, |
3012 JSObject* holder, | 3026 JSObject* holder, |
3013 Object* value) { | 3027 Object* value) { |
3014 // ----------- S t a t e ------------- | 3028 // ----------- S t a t e ------------- |
3015 // -- eax : key | 3029 // -- eax : key |
3016 // -- edx : receiver | 3030 // -- edx : receiver |
3017 // -- esp[0] : return address | 3031 // -- esp[0] : return address |
3018 // ----------------------------------- | 3032 // ----------------------------------- |
3019 Label miss; | 3033 Label miss; |
3020 | 3034 |
3021 Counters* counters = masm()->isolate()->counters(); | 3035 Counters* counters = isolate()->counters(); |
3022 __ IncrementCounter(counters->keyed_load_constant_function(), 1); | 3036 __ IncrementCounter(counters->keyed_load_constant_function(), 1); |
3023 | 3037 |
3024 // Check that the name has not changed. | 3038 // Check that the name has not changed. |
3025 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 3039 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
3026 __ j(not_equal, &miss, not_taken); | 3040 __ j(not_equal, &miss, not_taken); |
3027 | 3041 |
3028 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi, | 3042 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi, |
3029 value, name, &miss); | 3043 value, name, &miss); |
3030 __ bind(&miss); | 3044 __ bind(&miss); |
3031 __ DecrementCounter(counters->keyed_load_constant_function(), 1); | 3045 __ DecrementCounter(counters->keyed_load_constant_function(), 1); |
3032 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3046 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3033 | 3047 |
3034 // Return the generated code. | 3048 // Return the generated code. |
3035 return GetCode(CONSTANT_FUNCTION, name); | 3049 return GetCode(CONSTANT_FUNCTION, name); |
3036 } | 3050 } |
3037 | 3051 |
3038 | 3052 |
3039 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 3053 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
3040 JSObject* holder, | 3054 JSObject* holder, |
3041 String* name) { | 3055 String* name) { |
3042 // ----------- S t a t e ------------- | 3056 // ----------- S t a t e ------------- |
3043 // -- eax : key | 3057 // -- eax : key |
3044 // -- edx : receiver | 3058 // -- edx : receiver |
3045 // -- esp[0] : return address | 3059 // -- esp[0] : return address |
3046 // ----------------------------------- | 3060 // ----------------------------------- |
3047 Label miss; | 3061 Label miss; |
3048 | 3062 |
3049 Counters* counters = masm()->isolate()->counters(); | 3063 Counters* counters = isolate()->counters(); |
3050 __ IncrementCounter(counters->keyed_load_interceptor(), 1); | 3064 __ IncrementCounter(counters->keyed_load_interceptor(), 1); |
3051 | 3065 |
3052 // Check that the name has not changed. | 3066 // Check that the name has not changed. |
3053 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 3067 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
3054 __ j(not_equal, &miss, not_taken); | 3068 __ j(not_equal, &miss, not_taken); |
3055 | 3069 |
3056 LookupResult lookup; | 3070 LookupResult lookup; |
3057 LookupPostInterceptor(holder, name, &lookup); | 3071 LookupPostInterceptor(holder, name, &lookup); |
3058 GenerateLoadInterceptor(receiver, | 3072 GenerateLoadInterceptor(receiver, |
3059 holder, | 3073 holder, |
(...skipping 15 matching lines...) Expand all Loading... |
3075 | 3089 |
3076 | 3090 |
3077 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 3091 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { |
3078 // ----------- S t a t e ------------- | 3092 // ----------- S t a t e ------------- |
3079 // -- eax : key | 3093 // -- eax : key |
3080 // -- edx : receiver | 3094 // -- edx : receiver |
3081 // -- esp[0] : return address | 3095 // -- esp[0] : return address |
3082 // ----------------------------------- | 3096 // ----------------------------------- |
3083 Label miss; | 3097 Label miss; |
3084 | 3098 |
3085 Counters* counters = masm()->isolate()->counters(); | 3099 Counters* counters = isolate()->counters(); |
3086 __ IncrementCounter(counters->keyed_load_array_length(), 1); | 3100 __ IncrementCounter(counters->keyed_load_array_length(), 1); |
3087 | 3101 |
3088 // Check that the name has not changed. | 3102 // Check that the name has not changed. |
3089 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 3103 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
3090 __ j(not_equal, &miss, not_taken); | 3104 __ j(not_equal, &miss, not_taken); |
3091 | 3105 |
3092 GenerateLoadArrayLength(masm(), edx, ecx, &miss); | 3106 GenerateLoadArrayLength(masm(), edx, ecx, &miss); |
3093 __ bind(&miss); | 3107 __ bind(&miss); |
3094 __ DecrementCounter(counters->keyed_load_array_length(), 1); | 3108 __ DecrementCounter(counters->keyed_load_array_length(), 1); |
3095 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3109 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3096 | 3110 |
3097 // Return the generated code. | 3111 // Return the generated code. |
3098 return GetCode(CALLBACKS, name); | 3112 return GetCode(CALLBACKS, name); |
3099 } | 3113 } |
3100 | 3114 |
3101 | 3115 |
3102 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 3116 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { |
3103 // ----------- S t a t e ------------- | 3117 // ----------- S t a t e ------------- |
3104 // -- eax : key | 3118 // -- eax : key |
3105 // -- edx : receiver | 3119 // -- edx : receiver |
3106 // -- esp[0] : return address | 3120 // -- esp[0] : return address |
3107 // ----------------------------------- | 3121 // ----------------------------------- |
3108 Label miss; | 3122 Label miss; |
3109 | 3123 |
3110 Counters* counters = masm()->isolate()->counters(); | 3124 Counters* counters = isolate()->counters(); |
3111 __ IncrementCounter(counters->keyed_load_string_length(), 1); | 3125 __ IncrementCounter(counters->keyed_load_string_length(), 1); |
3112 | 3126 |
3113 // Check that the name has not changed. | 3127 // Check that the name has not changed. |
3114 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 3128 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
3115 __ j(not_equal, &miss, not_taken); | 3129 __ j(not_equal, &miss, not_taken); |
3116 | 3130 |
3117 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); | 3131 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); |
3118 __ bind(&miss); | 3132 __ bind(&miss); |
3119 __ DecrementCounter(counters->keyed_load_string_length(), 1); | 3133 __ DecrementCounter(counters->keyed_load_string_length(), 1); |
3120 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3134 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3121 | 3135 |
3122 // Return the generated code. | 3136 // Return the generated code. |
3123 return GetCode(CALLBACKS, name); | 3137 return GetCode(CALLBACKS, name); |
3124 } | 3138 } |
3125 | 3139 |
3126 | 3140 |
3127 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 3141 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { |
3128 // ----------- S t a t e ------------- | 3142 // ----------- S t a t e ------------- |
3129 // -- eax : key | 3143 // -- eax : key |
3130 // -- edx : receiver | 3144 // -- edx : receiver |
3131 // -- esp[0] : return address | 3145 // -- esp[0] : return address |
3132 // ----------------------------------- | 3146 // ----------------------------------- |
3133 Label miss; | 3147 Label miss; |
3134 | 3148 |
3135 Counters* counters = masm()->isolate()->counters(); | 3149 Counters* counters = isolate()->counters(); |
3136 __ IncrementCounter(counters->keyed_load_function_prototype(), 1); | 3150 __ IncrementCounter(counters->keyed_load_function_prototype(), 1); |
3137 | 3151 |
3138 // Check that the name has not changed. | 3152 // Check that the name has not changed. |
3139 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 3153 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
3140 __ j(not_equal, &miss, not_taken); | 3154 __ j(not_equal, &miss, not_taken); |
3141 | 3155 |
3142 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); | 3156 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); |
3143 __ bind(&miss); | 3157 __ bind(&miss); |
3144 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); | 3158 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); |
3145 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3159 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3274 // depending on the this.x = ...; assignment in the function. | 3288 // depending on the this.x = ...; assignment in the function. |
3275 SharedFunctionInfo* shared = function->shared(); | 3289 SharedFunctionInfo* shared = function->shared(); |
3276 for (int i = 0; i < shared->this_property_assignments_count(); i++) { | 3290 for (int i = 0; i < shared->this_property_assignments_count(); i++) { |
3277 if (shared->IsThisPropertyAssignmentArgument(i)) { | 3291 if (shared->IsThisPropertyAssignmentArgument(i)) { |
3278 // Check if the argument assigned to the property is actually passed. | 3292 // Check if the argument assigned to the property is actually passed. |
3279 // If argument is not passed the property is set to undefined, | 3293 // If argument is not passed the property is set to undefined, |
3280 // otherwise find it on the stack. | 3294 // otherwise find it on the stack. |
3281 int arg_number = shared->GetThisPropertyAssignmentArgument(i); | 3295 int arg_number = shared->GetThisPropertyAssignmentArgument(i); |
3282 __ mov(ebx, edi); | 3296 __ mov(ebx, edi); |
3283 __ cmp(eax, arg_number); | 3297 __ cmp(eax, arg_number); |
3284 if (masm()->isolate()->cpu_features()->IsSupported(CMOV)) { | 3298 if (isolate()->cpu_features()->IsSupported(CMOV)) { |
3285 CpuFeatures::Scope use_cmov(CMOV); | 3299 CpuFeatures::Scope use_cmov(CMOV); |
3286 __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize)); | 3300 __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize)); |
3287 } else { | 3301 } else { |
3288 Label not_passed; | 3302 Label not_passed; |
3289 __ j(below_equal, ¬_passed); | 3303 __ j(below_equal, ¬_passed); |
3290 __ mov(ebx, Operand(ecx, arg_number * -kPointerSize)); | 3304 __ mov(ebx, Operand(ecx, arg_number * -kPointerSize)); |
3291 __ bind(¬_passed); | 3305 __ bind(¬_passed); |
3292 } | 3306 } |
3293 // Store value in the property. | 3307 // Store value in the property. |
3294 __ mov(Operand(edx, i * kPointerSize), ebx); | 3308 __ mov(Operand(edx, i * kPointerSize), ebx); |
(...skipping 14 matching lines...) Expand all Loading... |
3309 | 3323 |
3310 // Move argc to ebx and retrieve and tag the JSObject to return. | 3324 // Move argc to ebx and retrieve and tag the JSObject to return. |
3311 __ mov(ebx, eax); | 3325 __ mov(ebx, eax); |
3312 __ pop(eax); | 3326 __ pop(eax); |
3313 __ or_(Operand(eax), Immediate(kHeapObjectTag)); | 3327 __ or_(Operand(eax), Immediate(kHeapObjectTag)); |
3314 | 3328 |
3315 // Remove caller arguments and receiver from the stack and return. | 3329 // Remove caller arguments and receiver from the stack and return. |
3316 __ pop(ecx); | 3330 __ pop(ecx); |
3317 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize)); | 3331 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize)); |
3318 __ push(ecx); | 3332 __ push(ecx); |
3319 Counters* counters = masm()->isolate()->counters(); | 3333 Counters* counters = isolate()->counters(); |
3320 __ IncrementCounter(counters->constructed_objects(), 1); | 3334 __ IncrementCounter(counters->constructed_objects(), 1); |
3321 __ IncrementCounter(counters->constructed_objects_stub(), 1); | 3335 __ IncrementCounter(counters->constructed_objects_stub(), 1); |
3322 __ ret(0); | 3336 __ ret(0); |
3323 | 3337 |
3324 // Jump to the generic stub in case the specialized code cannot handle the | 3338 // Jump to the generic stub in case the specialized code cannot handle the |
3325 // construction. | 3339 // construction. |
3326 __ bind(&generic_stub_call); | 3340 __ bind(&generic_stub_call); |
3327 Handle<Code> generic_construct_stub = | 3341 Handle<Code> generic_construct_stub = |
3328 masm()->isolate()->builtins()->JSConstructStubGeneric(); | 3342 isolate()->builtins()->JSConstructStubGeneric(); |
3329 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); | 3343 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); |
3330 | 3344 |
3331 // Return the generated code. | 3345 // Return the generated code. |
3332 return GetCode(); | 3346 return GetCode(); |
3333 } | 3347 } |
3334 | 3348 |
3335 | 3349 |
3336 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( | 3350 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( |
3337 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) { | 3351 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) { |
3338 // ----------- S t a t e ------------- | 3352 // ----------- S t a t e ------------- |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3458 | 3472 |
3459 // If we fail allocation of the HeapNumber, we still have a value on | 3473 // If we fail allocation of the HeapNumber, we still have a value on |
3460 // top of the FPU stack. Remove it. | 3474 // top of the FPU stack. Remove it. |
3461 __ bind(&failed_allocation); | 3475 __ bind(&failed_allocation); |
3462 __ ffree(); | 3476 __ ffree(); |
3463 __ fincstp(); | 3477 __ fincstp(); |
3464 // Fall through to slow case. | 3478 // Fall through to slow case. |
3465 | 3479 |
3466 // Slow case: Jump to runtime. | 3480 // Slow case: Jump to runtime. |
3467 __ bind(&slow); | 3481 __ bind(&slow); |
3468 Counters* counters = masm()->isolate()->counters(); | 3482 Counters* counters = isolate()->counters(); |
3469 __ IncrementCounter(counters->keyed_load_external_array_slow(), 1); | 3483 __ IncrementCounter(counters->keyed_load_external_array_slow(), 1); |
3470 // ----------- S t a t e ------------- | 3484 // ----------- S t a t e ------------- |
3471 // -- eax : key | 3485 // -- eax : key |
3472 // -- edx : receiver | 3486 // -- edx : receiver |
3473 // -- esp[0] : return address | 3487 // -- esp[0] : return address |
3474 // ----------------------------------- | 3488 // ----------------------------------- |
3475 | 3489 |
3476 __ pop(ebx); | 3490 __ pop(ebx); |
3477 __ push(edx); // receiver | 3491 __ push(edx); // receiver |
3478 __ push(eax); // name | 3492 __ push(eax); // name |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3593 __ fstp_s(Operand(edi, ebx, times_4, 0)); | 3607 __ fstp_s(Operand(edi, ebx, times_4, 0)); |
3594 __ ret(0); | 3608 __ ret(0); |
3595 } else { | 3609 } else { |
3596 // Perform float-to-int conversion with truncation (round-to-zero) | 3610 // Perform float-to-int conversion with truncation (round-to-zero) |
3597 // behavior. | 3611 // behavior. |
3598 | 3612 |
3599 // For the moment we make the slow call to the runtime on | 3613 // For the moment we make the slow call to the runtime on |
3600 // processors that don't support SSE2. The code in IntegerConvert | 3614 // processors that don't support SSE2. The code in IntegerConvert |
3601 // (code-stubs-ia32.cc) is roughly what is needed here though the | 3615 // (code-stubs-ia32.cc) is roughly what is needed here though the |
3602 // conversion failure case does not need to be handled. | 3616 // conversion failure case does not need to be handled. |
3603 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) { | 3617 if (isolate()->cpu_features()->IsSupported(SSE2)) { |
3604 if (array_type != kExternalIntArray && | 3618 if (array_type != kExternalIntArray && |
3605 array_type != kExternalUnsignedIntArray) { | 3619 array_type != kExternalUnsignedIntArray) { |
3606 ASSERT(masm()->isolate()->cpu_features()->IsSupported(SSE2)); | 3620 ASSERT(isolate()->cpu_features()->IsSupported(SSE2)); |
3607 CpuFeatures::Scope scope(SSE2); | 3621 CpuFeatures::Scope scope(SSE2); |
3608 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset)); | 3622 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset)); |
3609 // ecx: untagged integer value | 3623 // ecx: untagged integer value |
3610 switch (array_type) { | 3624 switch (array_type) { |
3611 case kExternalPixelArray: | 3625 case kExternalPixelArray: |
3612 { // Clamp the value to [0..255]. | 3626 { // Clamp the value to [0..255]. |
3613 NearLabel done; | 3627 NearLabel done; |
3614 __ test(ecx, Immediate(0xFFFFFF00)); | 3628 __ test(ecx, Immediate(0xFFFFFF00)); |
3615 __ j(zero, &done); | 3629 __ j(zero, &done); |
3616 __ setcc(negative, ecx); // 1 if negative, 0 if positive. | 3630 __ setcc(negative, ecx); // 1 if negative, 0 if positive. |
3617 __ dec_b(ecx); // 0 if negative, 255 if positive. | 3631 __ dec_b(ecx); // 0 if negative, 255 if positive. |
3618 __ bind(&done); | 3632 __ bind(&done); |
3619 } | 3633 } |
3620 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); | 3634 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); |
3621 case kExternalByteArray: | 3635 case kExternalByteArray: |
3622 case kExternalUnsignedByteArray: | 3636 case kExternalUnsignedByteArray: |
3623 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); | 3637 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); |
3624 break; | 3638 break; |
3625 case kExternalShortArray: | 3639 case kExternalShortArray: |
3626 case kExternalUnsignedShortArray: | 3640 case kExternalUnsignedShortArray: |
3627 __ mov_w(Operand(edi, ebx, times_2, 0), ecx); | 3641 __ mov_w(Operand(edi, ebx, times_2, 0), ecx); |
3628 break; | 3642 break; |
3629 default: | 3643 default: |
3630 UNREACHABLE(); | 3644 UNREACHABLE(); |
3631 break; | 3645 break; |
3632 } | 3646 } |
3633 } else { | 3647 } else { |
3634 if (masm()->isolate()->cpu_features()->IsSupported(SSE3)) { | 3648 if (isolate()->cpu_features()->IsSupported(SSE3)) { |
3635 CpuFeatures::Scope scope(SSE3); | 3649 CpuFeatures::Scope scope(SSE3); |
3636 // fisttp stores values as signed integers. To represent the | 3650 // fisttp stores values as signed integers. To represent the |
3637 // entire range of int and unsigned int arrays, store as a | 3651 // entire range of int and unsigned int arrays, store as a |
3638 // 64-bit int and discard the high 32 bits. | 3652 // 64-bit int and discard the high 32 bits. |
3639 // If the value is NaN or +/-infinity, the result is 0x80000000, | 3653 // If the value is NaN or +/-infinity, the result is 0x80000000, |
3640 // which is automatically zero when taken mod 2^n, n < 32. | 3654 // which is automatically zero when taken mod 2^n, n < 32. |
3641 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 3655 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
3642 __ sub(Operand(esp), Immediate(2 * kPointerSize)); | 3656 __ sub(Operand(esp), Immediate(2 * kPointerSize)); |
3643 __ fisttp_d(Operand(esp, 0)); | 3657 __ fisttp_d(Operand(esp, 0)); |
3644 __ pop(ecx); | 3658 __ pop(ecx); |
3645 __ add(Operand(esp), Immediate(kPointerSize)); | 3659 __ add(Operand(esp), Immediate(kPointerSize)); |
3646 } else { | 3660 } else { |
3647 ASSERT(masm()->isolate()->cpu_features()->IsSupported(SSE2)); | 3661 ASSERT(isolate()->cpu_features()->IsSupported(SSE2)); |
3648 CpuFeatures::Scope scope(SSE2); | 3662 CpuFeatures::Scope scope(SSE2); |
3649 // We can easily implement the correct rounding behavior for the | 3663 // We can easily implement the correct rounding behavior for the |
3650 // range [0, 2^31-1]. For the time being, to keep this code simple, | 3664 // range [0, 2^31-1]. For the time being, to keep this code simple, |
3651 // make the slow runtime call for values outside this range. | 3665 // make the slow runtime call for values outside this range. |
3652 // Note: we could do better for signed int arrays. | 3666 // Note: we could do better for signed int arrays. |
3653 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); | 3667 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); |
3654 // We will need the key if we have to make the slow runtime call. | 3668 // We will need the key if we have to make the slow runtime call. |
3655 __ push(ecx); | 3669 __ push(ecx); |
3656 __ LoadPowerOf2(xmm1, ecx, 31); | 3670 __ LoadPowerOf2(xmm1, ecx, 31); |
3657 __ pop(ecx); | 3671 __ pop(ecx); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3690 | 3704 |
3691 return GetCode(flags); | 3705 return GetCode(flags); |
3692 } | 3706 } |
3693 | 3707 |
3694 | 3708 |
3695 #undef __ | 3709 #undef __ |
3696 | 3710 |
3697 } } // namespace v8::internal | 3711 } } // namespace v8::internal |
3698 | 3712 |
3699 #endif // V8_TARGET_ARCH_IA32 | 3713 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |