 Chromium Code Reviews
 Chromium Code Reviews Issue 12225099:
  Remove prototype checks for leaf maps in optimized code.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 12225099:
  Remove prototype checks for leaf maps in optimized code.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| 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 3606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3617 int instance_size_delta = map_of_this->instance_size() - new_instance_size; | 3617 int instance_size_delta = map_of_this->instance_size() - new_instance_size; | 
| 3618 ASSERT(instance_size_delta >= 0); | 3618 ASSERT(instance_size_delta >= 0); | 
| 3619 current_heap->CreateFillerObjectAt(this->address() + new_instance_size, | 3619 current_heap->CreateFillerObjectAt(this->address() + new_instance_size, | 
| 3620 instance_size_delta); | 3620 instance_size_delta); | 
| 3621 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { | 3621 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { | 
| 3622 MemoryChunk::IncrementLiveBytesFromMutator(this->address(), | 3622 MemoryChunk::IncrementLiveBytesFromMutator(this->address(), | 
| 3623 -instance_size_delta); | 3623 -instance_size_delta); | 
| 3624 } | 3624 } | 
| 3625 | 3625 | 
| 3626 set_map(new_map); | 3626 set_map(new_map); | 
| 3627 map_of_this->DeoptimizeDependentCodes(DependentCodes::kPrototypeCheckGroup); | |
| 3627 | 3628 | 
| 3628 set_properties(dictionary); | 3629 set_properties(dictionary); | 
| 3629 | 3630 | 
| 3630 current_heap->isolate()->counters()->props_to_dictionary()->Increment(); | 3631 current_heap->isolate()->counters()->props_to_dictionary()->Increment(); | 
| 3631 | 3632 | 
| 3632 #ifdef DEBUG | 3633 #ifdef DEBUG | 
| 3633 if (FLAG_trace_normalization) { | 3634 if (FLAG_trace_normalization) { | 
| 3634 PrintF("Object properties have been normalized:\n"); | 3635 PrintF("Object properties have been normalized:\n"); | 
| 3635 Print(); | 3636 Print(); | 
| 3636 } | 3637 } | 
| (...skipping 1648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5285 MaybeObject* maybe_result = RawCopy(instance_size()); | 5286 MaybeObject* maybe_result = RawCopy(instance_size()); | 
| 5286 if (!maybe_result->To(&result)) return maybe_result; | 5287 if (!maybe_result->To(&result)) return maybe_result; | 
| 5287 | 5288 | 
| 5288 // Please note instance_type and instance_size are set when allocated. | 5289 // Please note instance_type and instance_size are set when allocated. | 
| 5289 result->set_inobject_properties(inobject_properties()); | 5290 result->set_inobject_properties(inobject_properties()); | 
| 5290 result->set_unused_property_fields(unused_property_fields()); | 5291 result->set_unused_property_fields(unused_property_fields()); | 
| 5291 | 5292 | 
| 5292 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); | 5293 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); | 
| 5293 result->set_is_shared(false); | 5294 result->set_is_shared(false); | 
| 5294 result->ClearCodeCache(GetHeap()); | 5295 result->ClearCodeCache(GetHeap()); | 
| 5296 DeoptimizeDependentCodes(DependentCodes::kPrototypeCheckGroup); | |
| 
Toon Verwaest
2013/02/11 12:23:45
Placing this in CopyDropDescriptors is probably a
 
ulan
2013/02/12 13:42:07
As discussed offline, adding abstraction function
 | |
| 5295 return result; | 5297 return result; | 
| 5296 } | 5298 } | 
| 5297 | 5299 | 
| 5298 | 5300 | 
| 5299 MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors, | 5301 MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors, | 
| 5300 Descriptor* descriptor) { | 5302 Descriptor* descriptor) { | 
| 5301 // Sanity check. This path is only to be taken if the map owns its descriptor | 5303 // Sanity check. This path is only to be taken if the map owns its descriptor | 
| 5302 // array, implying that its NumberOfOwnDescriptors equals the number of | 5304 // array, implying that its NumberOfOwnDescriptors equals the number of | 
| 5303 // descriptors in the descriptor array. | 5305 // descriptors in the descriptor array. | 
| 5304 ASSERT(NumberOfOwnDescriptors() == | 5306 ASSERT(NumberOfOwnDescriptors() == | 
| (...skipping 4243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9548 bool DependentCodes::Contains(DependencyGroup group, Code* code) { | 9550 bool DependentCodes::Contains(DependencyGroup group, Code* code) { | 
| 9549 GroupStartIndexes starts; | 9551 GroupStartIndexes starts; | 
| 9550 ComputeGroupStartIndexes(starts); | 9552 ComputeGroupStartIndexes(starts); | 
| 9551 int number_of_codes = starts[kGroupCount]; | 9553 int number_of_codes = starts[kGroupCount]; | 
| 9552 for (int i = 0; i < number_of_codes; i++) { | 9554 for (int i = 0; i < number_of_codes; i++) { | 
| 9553 if (code_at(i) == code) return true; | 9555 if (code_at(i) == code) return true; | 
| 9554 } | 9556 } | 
| 9555 return false; | 9557 return false; | 
| 9556 } | 9558 } | 
| 9557 | 9559 | 
| 9560 class DeoptimizeDependentCodeFilter : public OptimizedFunctionFilter { | |
| 9561 public: | |
| 9562 virtual bool TakeFunction(JSFunction* function) { | |
| 9563 return function->code()->marked_for_deoptimization(); | |
| 9564 } | |
| 9565 }; | |
| 9566 | |
| 9567 | |
| 9568 void Map::DeoptimizeDependentCodes(DependentCodes::DependencyGroup group) { | |
| 9569 AssertNoAllocation no_allocation_scope; | |
| 9570 DependentCodes* codes = dependent_codes(); | |
| 9571 DependentCodes::GroupStartIndexes starts; | |
| 9572 codes->ComputeGroupStartIndexes(starts); | |
| 9573 int start = starts[group]; | |
| 9574 int end = starts[group + 1]; | |
| 9575 int number_of_codes = starts[DependentCodes::kGroupCount]; | |
| 9576 if (start == end) return; | |
| 9577 for (int i = start; i < end; i++) { | |
| 9578 Code* code = codes->code_at(i); | |
| 9579 if (!code->marked_for_deoptimization()) { | |
| 9580 code->set_marked_for_deoptimization(true); | |
| 9581 } | |
| 
Toon Verwaest
2013/02/11 12:23:45
I guess the if(!..) { } is not necessary; since af
 
ulan
2013/02/12 13:42:07
Done.
 | |
| 9582 } | |
| 
Toon Verwaest
2013/02/11 12:23:45
I don't particularly like this API. It seems like
 
ulan
2013/02/12 13:42:07
Done.
 | |
| 9583 for (int src = end, dst = start; src < number_of_codes; src++, dst++) { | |
| 9584 codes->set_code_at(dst, codes->code_at(src)); | |
| 9585 } | |
| 9586 codes->set_number_of_codes(group, 0); | |
| 9587 DeoptimizeDependentCodeFilter filter; | |
| 9588 Deoptimizer::DeoptimizeAllFunctionsWith(&filter); | |
| 9589 } | |
| 9590 | |
| 9558 | 9591 | 
| 9559 MaybeObject* JSReceiver::SetPrototype(Object* value, | 9592 MaybeObject* JSReceiver::SetPrototype(Object* value, | 
| 9560 bool skip_hidden_prototypes) { | 9593 bool skip_hidden_prototypes) { | 
| 9561 #ifdef DEBUG | 9594 #ifdef DEBUG | 
| 9562 int size = Size(); | 9595 int size = Size(); | 
| 9563 #endif | 9596 #endif | 
| 9564 | 9597 | 
| 9565 Heap* heap = GetHeap(); | 9598 Heap* heap = GetHeap(); | 
| 9566 // Silently ignore the change if value is not a JSObject or null. | 9599 // Silently ignore the change if value is not a JSObject or null. | 
| 9567 // SpiderMonkey behaves this way. | 9600 // SpiderMonkey behaves this way. | 
| (...skipping 4342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13910 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13943 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 
| 13911 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13944 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 
| 13912 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13945 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 
| 13913 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13946 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 
| 13914 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13947 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 
| 13915 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13948 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 
| 13916 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13949 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 
| 13917 } | 13950 } | 
| 13918 | 13951 | 
| 13919 } } // namespace v8::internal | 13952 } } // namespace v8::internal | 
| OLD | NEW |